├── .github
├── create-release.nu
├── update-icons.nu
└── workflows
│ ├── build-native.yml
│ ├── build.yml
│ ├── release-gallery.yml
│ ├── release-notes.yml
│ ├── release.yml
│ └── update-icons.yml
├── .gitignore
├── .gitmodules
├── LICENSE
├── README.md
├── res
└── logo
│ ├── logo.dark.png
│ ├── logo.light.png
│ ├── lucide-logo-nuget.png
│ ├── lucide-logo.ico
│ └── lucide-logo.png
└── src
├── Generator.Icons
├── Generator.Icons.csproj
├── GeometryDataGenerator.cs
├── IconToGeometryBuilder.cs
├── LucideIconInfoBuilder.cs
├── LucideIconKindBuilder.cs
├── Program.cs
├── Usings.cs
└── Utilities.cs
├── Generator.ReleaseNotes
├── ChangeInfo.cs
├── ChangeNotesGenerator.cs
├── Generator.ReleaseNotes.csproj
├── GitDiff.cs
├── GitHubReleaseNotesUpdater.cs
├── ProcessRunner.cs
└── Program.cs
├── Lucide.Avalonia.Gallery
├── App.axaml
├── App.axaml.cs
├── Assets
│ └── lucide-logo.ico
├── Global
│ └── Usings.cs
├── Lucide.Avalonia.Gallery.csproj
├── Program.cs
├── Services
│ ├── ClipboardService.cs
│ └── NotificationService.cs
├── ViewModels
│ ├── IconViewModel.cs
│ ├── MainWindowViewModel.cs
│ └── ReactiveViewModel.cs
├── Views
│ ├── MainWindow.axaml
│ └── MainWindow.axaml.cs
└── app.manifest
├── Lucide.Avalonia.sln
└── Lucide.Avalonia
├── Global
├── Assembly.cs
└── Usings.cs
├── IconToGeometry.cs
├── Lucide.Avalonia.csproj
├── LucideIcon.cs
├── LucideIconContentExtension.cs
├── LucideIconKind.cs
└── Metadata
└── LucideIconInfo.cs
/.github/create-release.nu:
--------------------------------------------------------------------------------
1 | const project_path = "src/Lucide.Avalonia/Lucide.Avalonia.csproj"
2 |
3 | let repo_name = $env.REPO_NAME
4 | let nuget_api_key = $env.NUGET_API_KEY
5 | let version = git describe --tags --abbrev=0
6 |
7 | # Build and pack library
8 | dotnet build -c Release $project_path -p:Version=($version)
9 | dotnet pack -c Release $project_path -o . -p:Version=($version)
10 |
11 | # Push NuGet package
12 | dotnet nuget push *.nupkg --api-key $nuget_api_key --source https://api.nuget.org/v3/index.json --skip-duplicate
13 |
14 | # Create GitHub Release with the tag name
15 | gh release create $version --repo $repo_name --title $version --fail-on-no-commits --generate-notes --verify-tag
16 |
17 | # Dispath release workflows
18 | gh workflow run release-notes.yml --field release_tag_name=($version)
19 | gh workflow run release-gallery.yml --field release_tag_name=($version)
20 |
--------------------------------------------------------------------------------
/.github/update-icons.nu:
--------------------------------------------------------------------------------
1 | def generate-and-commit [] {
2 | # Clone the lucide library repo
3 | http get https://github.com/lucide-icons/lucide/archive/refs/heads/main.zip | save lucide-latest.zip
4 | unzip lucide-latest.zip
5 |
6 | # Run the generator
7 | dotnet restore ./src/Generator.Icons
8 | dotnet run --project ./src/Generator.Icons ./lucide-main ./src/Lucide.Avalonia/
9 |
10 | rm lucide-main -r
11 |
12 | # Verify generated code
13 | dotnet build ./src/Lucide.Avalonia/
14 |
15 | # Configure git user details
16 | git config --global user.name 'github-actions[bot]'
17 | git config --global user.email 'github-actions[bot]@users.noreply.github.com'
18 |
19 | # Add changed files to git
20 | git add ./src/Lucide.Avalonia/IconToGeometry.cs
21 | git add ./src/Lucide.Avalonia/LucideIconKind.cs
22 | git add ./src/Lucide.Avalonia/Metadata/LucideIconInfo.cs
23 | }
24 |
25 | def increment-version [version: string] {
26 | let version_parts = ($version | split row '.')
27 |
28 | if ($version_parts | length) != 3 {
29 | error make {
30 | msg: 'Invalid version format. Expected X.Y.Z'
31 | }
32 | }
33 |
34 | let major = ($version_parts | get 0)
35 | let minor = ($version_parts | get 1)
36 | let patch = ($version_parts | get 2 | into int) + 1
37 |
38 | $"($major).($minor).($patch)"
39 | }
40 |
41 | generate-and-commit
42 |
43 | # Check if there are staged changes
44 | let has_changes = (git diff --cached --name-only | str length) > 0
45 |
46 | if $has_changes {
47 | git commit -m "🔄 Update Icon Collection"
48 | git tag (increment-version (git describe --tags --abbrev=0))
49 | git push origin master --tags
50 | source create-release.nu
51 | } else {
52 | print "No changes to commit"
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/.github/workflows/build-native.yml:
--------------------------------------------------------------------------------
1 | name: Build Gallery (NativeAOT)
2 |
3 | on:
4 | push:
5 | pull_request:
6 | workflow_dispatch:
7 |
8 | jobs:
9 | build:
10 | runs-on: windows-latest
11 |
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v4
15 | with:
16 | submodules: true
17 |
18 | - name: Setup .NET
19 | uses: actions/setup-dotnet@v4
20 | with:
21 | dotnet-version: 9.0.x
22 |
23 | - name: Build
24 | run: dotnet publish src/Lucide.Avalonia.Gallery/Lucide.Avalonia.Gallery.csproj -c Release -r win-x64 -o bin/
25 |
26 | - name: Upload
27 | uses: actions/upload-artifact@v4
28 | with:
29 | name: gallery-native
30 | path: |
31 | bin/*exe
32 | bin/*dll
33 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | workflow_dispatch:
8 |
9 | jobs:
10 | build:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 |
17 | - name: Setup .NET
18 | uses: actions/setup-dotnet@v4
19 | with:
20 | dotnet-version: 9.0.x
21 |
22 | - name: Build
23 | run: |
24 | dotnet build -c Debug src/Lucide.Avalonia/Lucide.Avalonia.csproj
25 | dotnet build -c Release src/Lucide.Avalonia/Lucide.Avalonia.csproj
--------------------------------------------------------------------------------
/.github/workflows/release-gallery.yml:
--------------------------------------------------------------------------------
1 | name: Release Gallery (NativeAOT)
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_tag_name:
7 | required: true
8 |
9 | jobs:
10 | build-and-upload:
11 | runs-on: windows-latest
12 | permissions:
13 | contents: write
14 |
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 | with:
19 | ref: ${{ inputs.release_tag_name }}
20 | submodules: recursive
21 |
22 | - name: Build
23 | run: |
24 | dotnet publish src/Lucide.Avalonia.Gallery/Lucide.Avalonia.Gallery.csproj -c Release -r win-x64 -o bin/
25 | cd bin
26 | 7z a ../icons-gallery-win-x64-aot.zip *.exe *.dll
27 |
28 | - name: Upload Gallery to Release
29 | run: gh release upload ${{ inputs.release_tag_name }} icons-gallery-win-x64-aot.zip
30 | env:
31 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 |
--------------------------------------------------------------------------------
/.github/workflows/release-notes.yml:
--------------------------------------------------------------------------------
1 | name: Release Notes Generator (Bot)
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | release_tag_name:
7 | required: true
8 |
9 | jobs:
10 | generate:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 | with:
17 | fetch-depth: 0
18 |
19 | - name: Setup .NET
20 | uses: actions/setup-dotnet@v4
21 | with:
22 | dotnet-version: 9.0.x
23 |
24 | - name: Generate Release Notes
25 | run: dotnet run --project src/Generator.ReleaseNotes ${{ inputs.release_tag_name }}
26 | env:
27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28 | REPOSITORY_ID: ${{ github.event.repository.id }}
29 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Build & Publish
2 |
3 | on:
4 | push:
5 | tags:
6 | - "*.*.*"
7 | workflow_dispatch:
8 |
9 | jobs:
10 | publish:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v4
16 |
17 | - name: Setup .NET
18 | uses: actions/setup-dotnet@v4
19 | with:
20 | dotnet-version: 9.0.x
21 |
22 | - name: Setup Nushell
23 | run: |
24 | curl -fsSL https://apt.fury.io/nushell/gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/fury-nushell.gpg
25 | echo "deb https://apt.fury.io/nushell/ /" | sudo tee /etc/apt/sources.list.d/fury.list
26 | sudo apt update
27 | sudo apt install nushell
28 |
29 | - name: Release
30 | run: nu .github/create-release.nu
31 | env:
32 | REPO_NAME: ${{ github.event.repository.full_name }}
33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
35 |
--------------------------------------------------------------------------------
/.github/workflows/update-icons.yml:
--------------------------------------------------------------------------------
1 | name: Update Icon Collection (Bot)
2 |
3 | on:
4 | schedule:
5 | - cron: "0 4 * * 0"
6 |
7 | workflow_dispatch:
8 |
9 | jobs:
10 | update:
11 | runs-on: ubuntu-latest
12 |
13 | steps:
14 | - name: Setup .NET
15 | uses: actions/setup-dotnet@v4
16 | with:
17 | dotnet-version: 9.0.x
18 |
19 | - name: Setup Nushell
20 | run: |
21 | curl -fsSL https://apt.fury.io/nushell/gpg.key | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/fury-nushell.gpg
22 | echo "deb https://apt.fury.io/nushell/ /" | sudo tee /etc/apt/sources.list.d/fury.list
23 | sudo apt update
24 | sudo apt install nushell
25 |
26 | - name: Checkout
27 | uses: actions/checkout@v4
28 | with:
29 | fetch-depth: 0
30 |
31 | - name: Release
32 | run: nu .github/update-icons.nu
33 | env:
34 | REPO_NAME: ${{ github.event.repository.full_name }}
35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36 | NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Ll]og/
33 | [Ll]ogs/
34 |
35 | # Visual Studio 2015/2017 cache/options directory
36 | .vs/
37 | # Uncomment if you have tasks that create the project's static files in wwwroot
38 | #wwwroot/
39 |
40 | # Visual Studio 2017 auto generated files
41 | Generated\ Files/
42 |
43 | # MSTest test Results
44 | [Tt]est[Rr]esult*/
45 | [Bb]uild[Ll]og.*
46 |
47 | # NUnit
48 | *.VisualState.xml
49 | TestResult.xml
50 | nunit-*.xml
51 |
52 | # Build Results of an ATL Project
53 | [Dd]ebugPS/
54 | [Rr]eleasePS/
55 | dlldata.c
56 |
57 | # Benchmark Results
58 | BenchmarkDotNet.Artifacts/
59 |
60 | # .NET Core
61 | project.lock.json
62 | project.fragment.lock.json
63 | artifacts/
64 |
65 | # ASP.NET Scaffolding
66 | ScaffoldingReadMe.txt
67 |
68 | # StyleCop
69 | StyleCopReport.xml
70 |
71 | # Files built by Visual Studio
72 | *_i.c
73 | *_p.c
74 | *_h.h
75 | *.ilk
76 | *.meta
77 | *.obj
78 | *.iobj
79 | *.pch
80 | *.pdb
81 | *.ipdb
82 | *.pgc
83 | *.pgd
84 | *.rsp
85 | # but not Directory.Build.rsp, as it configures directory-level build defaults
86 | !Directory.Build.rsp
87 | *.sbr
88 | *.tlb
89 | *.tli
90 | *.tlh
91 | *.tmp
92 | *.tmp_proj
93 | *_wpftmp.csproj
94 | *.log
95 | *.tlog
96 | *.vspscc
97 | *.vssscc
98 | .builds
99 | *.pidb
100 | *.svclog
101 | *.scc
102 |
103 | # Chutzpah Test files
104 | _Chutzpah*
105 |
106 | # Visual C++ cache files
107 | ipch/
108 | *.aps
109 | *.ncb
110 | *.opendb
111 | *.opensdf
112 | *.sdf
113 | *.cachefile
114 | *.VC.db
115 | *.VC.VC.opendb
116 |
117 | # Visual Studio profiler
118 | *.psess
119 | *.vsp
120 | *.vspx
121 | *.sap
122 |
123 | # Visual Studio Trace Files
124 | *.e2e
125 |
126 | # TFS 2012 Local Workspace
127 | $tf/
128 |
129 | # Guidance Automation Toolkit
130 | *.gpState
131 |
132 | # ReSharper is a .NET coding add-in
133 | _ReSharper*/
134 | *.[Rr]e[Ss]harper
135 | *.DotSettings.user
136 |
137 | # TeamCity is a build add-in
138 | _TeamCity*
139 |
140 | # DotCover is a Code Coverage Tool
141 | *.dotCover
142 |
143 | # AxoCover is a Code Coverage Tool
144 | .axoCover/*
145 | !.axoCover/settings.json
146 |
147 | # Coverlet is a free, cross platform Code Coverage Tool
148 | coverage*.json
149 | coverage*.xml
150 | coverage*.info
151 |
152 | # Visual Studio code coverage results
153 | *.coverage
154 | *.coveragexml
155 |
156 | # NCrunch
157 | _NCrunch_*
158 | .*crunch*.local.xml
159 | nCrunchTemp_*
160 |
161 | # MightyMoose
162 | *.mm.*
163 | AutoTest.Net/
164 |
165 | # Web workbench (sass)
166 | .sass-cache/
167 |
168 | # Installshield output folder
169 | [Ee]xpress/
170 |
171 | # DocProject is a documentation generator add-in
172 | DocProject/buildhelp/
173 | DocProject/Help/*.HxT
174 | DocProject/Help/*.HxC
175 | DocProject/Help/*.hhc
176 | DocProject/Help/*.hhk
177 | DocProject/Help/*.hhp
178 | DocProject/Help/Html2
179 | DocProject/Help/html
180 |
181 | # Click-Once directory
182 | publish/
183 |
184 | # Publish Web Output
185 | *.[Pp]ublish.xml
186 | *.azurePubxml
187 | # Note: Comment the next line if you want to checkin your web deploy settings,
188 | # but database connection strings (with potential passwords) will be unencrypted
189 | *.pubxml
190 | *.publishproj
191 |
192 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
193 | # checkin your Azure Web App publish settings, but sensitive information contained
194 | # in these scripts will be unencrypted
195 | PublishScripts/
196 |
197 | # NuGet Packages
198 | *.nupkg
199 | # NuGet Symbol Packages
200 | *.snupkg
201 | # The packages folder can be ignored because of Package Restore
202 | **/[Pp]ackages/*
203 | # except build/, which is used as an MSBuild target.
204 | !**/[Pp]ackages/build/
205 | # Uncomment if necessary however generally it will be regenerated when needed
206 | #!**/[Pp]ackages/repositories.config
207 | # NuGet v3's project.json files produces more ignorable files
208 | *.nuget.props
209 | *.nuget.targets
210 |
211 | # Microsoft Azure Build Output
212 | csx/
213 | *.build.csdef
214 |
215 | # Microsoft Azure Emulator
216 | ecf/
217 | rcf/
218 |
219 | # Windows Store app package directories and files
220 | AppPackages/
221 | BundleArtifacts/
222 | Package.StoreAssociation.xml
223 | _pkginfo.txt
224 | *.appx
225 | *.appxbundle
226 | *.appxupload
227 |
228 | # Visual Studio cache files
229 | # files ending in .cache can be ignored
230 | *.[Cc]ache
231 | # but keep track of directories ending in .cache
232 | !?*.[Cc]ache/
233 |
234 | # Others
235 | ClientBin/
236 | ~$*
237 | *~
238 | *.dbmdl
239 | *.dbproj.schemaview
240 | *.jfm
241 | *.pfx
242 | *.publishsettings
243 | orleans.codegen.cs
244 |
245 | # Including strong name files can present a security risk
246 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
247 | #*.snk
248 |
249 | # Since there are multiple workflows, uncomment next line to ignore bower_components
250 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
251 | #bower_components/
252 |
253 | # RIA/Silverlight projects
254 | Generated_Code/
255 |
256 | # Backup & report files from converting an old project file
257 | # to a newer Visual Studio version. Backup files are not needed,
258 | # because we have git ;-)
259 | _UpgradeReport_Files/
260 | Backup*/
261 | UpgradeLog*.XML
262 | UpgradeLog*.htm
263 | ServiceFabricBackup/
264 | *.rptproj.bak
265 |
266 | # SQL Server files
267 | *.mdf
268 | *.ldf
269 | *.ndf
270 |
271 | # Business Intelligence projects
272 | *.rdl.data
273 | *.bim.layout
274 | *.bim_*.settings
275 | *.rptproj.rsuser
276 | *- [Bb]ackup.rdl
277 | *- [Bb]ackup ([0-9]).rdl
278 | *- [Bb]ackup ([0-9][0-9]).rdl
279 |
280 | # Microsoft Fakes
281 | FakesAssemblies/
282 |
283 | # GhostDoc plugin setting file
284 | *.GhostDoc.xml
285 |
286 | # Node.js Tools for Visual Studio
287 | .ntvs_analysis.dat
288 | node_modules/
289 |
290 | # Visual Studio 6 build log
291 | *.plg
292 |
293 | # Visual Studio 6 workspace options file
294 | *.opt
295 |
296 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
297 | *.vbw
298 |
299 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
300 | *.vbp
301 |
302 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
303 | *.dsw
304 | *.dsp
305 |
306 | # Visual Studio 6 technical files
307 | *.ncb
308 | *.aps
309 |
310 | # Visual Studio LightSwitch build output
311 | **/*.HTMLClient/GeneratedArtifacts
312 | **/*.DesktopClient/GeneratedArtifacts
313 | **/*.DesktopClient/ModelManifest.xml
314 | **/*.Server/GeneratedArtifacts
315 | **/*.Server/ModelManifest.xml
316 | _Pvt_Extensions
317 |
318 | # Paket dependency manager
319 | .paket/paket.exe
320 | paket-files/
321 |
322 | # FAKE - F# Make
323 | .fake/
324 |
325 | # CodeRush personal settings
326 | .cr/personal
327 |
328 | # Python Tools for Visual Studio (PTVS)
329 | __pycache__/
330 | *.pyc
331 |
332 | # Cake - Uncomment if you are using it
333 | # tools/**
334 | # !tools/packages.config
335 |
336 | # Tabs Studio
337 | *.tss
338 |
339 | # Telerik's JustMock configuration file
340 | *.jmconfig
341 |
342 | # BizTalk build output
343 | *.btp.cs
344 | *.btm.cs
345 | *.odx.cs
346 | *.xsd.cs
347 |
348 | # OpenCover UI analysis results
349 | OpenCover/
350 |
351 | # Azure Stream Analytics local run output
352 | ASALocalRun/
353 |
354 | # MSBuild Binary and Structured Log
355 | *.binlog
356 |
357 | # NVidia Nsight GPU debugger configuration file
358 | *.nvuser
359 |
360 | # MFractors (Xamarin productivity tool) working folder
361 | .mfractor/
362 |
363 | # Local History for Visual Studio
364 | .localhistory/
365 |
366 | # Visual Studio History (VSHistory) files
367 | .vshistory/
368 |
369 | # BeatPulse healthcheck temp database
370 | healthchecksdb
371 |
372 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
373 | MigrationBackup/
374 |
375 | # Ionide (cross platform F# VS Code tools) working folder
376 | .ionide/
377 |
378 | # Fody - auto-generated XML schema
379 | FodyWeavers.xsd
380 |
381 | # VS Code files for those working on multiple tools
382 | .vscode/*
383 | !.vscode/settings.json
384 | !.vscode/tasks.json
385 | !.vscode/launch.json
386 | !.vscode/extensions.json
387 | *.code-workspace
388 |
389 | # Local History for Visual Studio Code
390 | .history/
391 |
392 | # Windows Installer files from build outputs
393 | *.cab
394 | *.msi
395 | *.msix
396 | *.msm
397 | *.msp
398 |
399 | # JetBrains Rider
400 | .idea/
401 | *.sln.iml
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "ext/SukiUI"]
2 | path = ext/SukiUI
3 | url = https://github.com/kikipoulet/SukiUI.git
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Compunet
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ✨ Lucide.Avalonia
2 |
3 | Implementation of the [Lucide icon library](https://github.com/lucide-icons/lucide) for [AvaloniaUI](https://github.com/AvaloniaUI/Avalonia).
4 |
5 | [](https://www.nuget.org/packages/Lucide.Avalonia)
6 | [](https://github.com/dme-compunet/Lucide.Avalonia/blob/main/LICENSE)
7 |
8 | ---
9 |
10 | ## ⚡ Advantages
11 |
12 | - No styles include required.
13 | - No xmlns declaration required.
14 | - Automatic daily updates and releases.
15 |
16 | ---
17 |
18 | ## 🚀 Usage Examples
19 |
20 | ### Using the `LucideIcon` Element
21 |
22 | ```xml
23 |
24 |
25 |
26 | ```
27 |
28 | ### Using a Markup Extension
29 |
30 | ```xml
31 |
32 |
33 |
34 | ```
35 |
36 | ---
37 |
38 | ## 🔗 Additional Links
39 |
40 | - [AvaloniaUI](https://github.com/AvaloniaUI/Avalonia)
41 | - [Lucide Icons](https://lucide.dev/icons)
42 | - [NuGet Package](https://www.nuget.org/packages/Lucide.Avalonia)
43 |
--------------------------------------------------------------------------------
/res/logo/logo.dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dme-compunet/Lucide.Avalonia/8e4b5c33dbdcb9f000b70edfe7b51511f9de91eb/res/logo/logo.dark.png
--------------------------------------------------------------------------------
/res/logo/logo.light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dme-compunet/Lucide.Avalonia/8e4b5c33dbdcb9f000b70edfe7b51511f9de91eb/res/logo/logo.light.png
--------------------------------------------------------------------------------
/res/logo/lucide-logo-nuget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dme-compunet/Lucide.Avalonia/8e4b5c33dbdcb9f000b70edfe7b51511f9de91eb/res/logo/lucide-logo-nuget.png
--------------------------------------------------------------------------------
/res/logo/lucide-logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dme-compunet/Lucide.Avalonia/8e4b5c33dbdcb9f000b70edfe7b51511f9de91eb/res/logo/lucide-logo.ico
--------------------------------------------------------------------------------
/res/logo/lucide-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dme-compunet/Lucide.Avalonia/8e4b5c33dbdcb9f000b70edfe7b51511f9de91eb/res/logo/lucide-logo.png
--------------------------------------------------------------------------------
/src/Generator.Icons/Generator.Icons.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/Generator.Icons/GeometryDataGenerator.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Icons;
2 |
3 | public static class GeometryDataGenerator
4 | {
5 | public static string CreateFromFile(string path)
6 | {
7 | using var svg = SKSvg.CreateFromFile(path);
8 |
9 | var drawingGroup = new DrawingGroup(svg.Model);
10 |
11 | var geometryString = new StringBuilder();
12 |
13 | foreach (var item in EnumerateGeometryDrawing(drawingGroup.Children))
14 | {
15 | var skPath = item.Geometry
16 | ??
17 | throw new InvalidOperationException();
18 |
19 | var data = ToSvgPathData(skPath, SKMatrix.CreateIdentity());
20 |
21 | geometryString.Append(data);
22 | }
23 |
24 | return geometryString.ToString();
25 | }
26 |
27 | private static IEnumerable EnumerateGeometryDrawing(IEnumerable source)
28 | {
29 | foreach (var drawing in source)
30 | {
31 | if (drawing is DrawingGroup group)
32 | {
33 | foreach (var item in EnumerateGeometryDrawing(group.Children))
34 | {
35 | yield return item;
36 | }
37 | }
38 | else if (drawing is GeometryDrawing geometryDrawing)
39 | {
40 | yield return geometryDrawing;
41 | }
42 | else
43 | {
44 | throw new InvalidOperationException();
45 | }
46 | }
47 | }
48 |
49 | private static string ToSvgPathData(SKPath path, SKMatrix matrix)
50 | {
51 | var transformedPath = new SKPath(path);
52 | transformedPath.Transform(matrix);
53 | if (transformedPath.FillType == SKPathFillType.EvenOdd)
54 | {
55 | // EvenOdd
56 | var sb = new StringBuilder();
57 | sb.Append("F0 ");
58 | sb.Append(transformedPath.ToSvgPathData());
59 | return sb.ToString();
60 | }
61 | else
62 | {
63 | // Nonzero
64 | var sb = new StringBuilder();
65 | sb.Append("F1 ");
66 | sb.Append(transformedPath.ToSvgPathData());
67 | return sb.ToString();
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/src/Generator.Icons/IconToGeometryBuilder.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Icons;
2 |
3 | public class IconToGeometryBuilder
4 | {
5 | private readonly List<(string Name, string Geometry)> _icons = [];
6 |
7 | public void AddIcon(string name, string path)
8 | {
9 | var geometry = GeometryDataGenerator.CreateFromFile(path);
10 |
11 | _icons.Add((name, geometry));
12 | }
13 |
14 | public string Build()
15 | {
16 | var sb = new StringBuilder();
17 |
18 | sb.AppendLine("""
19 | namespace Lucide.Avalonia;
20 |
21 | internal static class IconToGeometry
22 | {
23 | private readonly record struct Entry(LucideIconKind Key, string Geometry);
24 |
25 | private static readonly Dictionary _geometryCache = [];
26 | private static readonly FrozenDictionary _geometries;
27 |
28 | static IconToGeometry()
29 | {
30 | Entry[] entries =
31 | [
32 | """);
33 |
34 | foreach (var (name, geometry) in _icons)
35 | {
36 | sb.AppendLine($" new(LucideIconKind.{name}, \"{geometry}\"),");
37 | }
38 |
39 | sb.AppendLine("""
40 | ];
41 |
42 | _geometries = entries.ToFrozenDictionary(x => x.Key, x => x.Geometry);
43 | }
44 |
45 | public static Geometry CreateGeometry(LucideIconKind icon)
46 | {
47 | if (_geometryCache.TryGetValue(icon, out var geometry))
48 | {
49 | return geometry;
50 | }
51 |
52 | geometry = Geometry.Parse(_geometries[icon]);
53 |
54 | _geometryCache.Add(icon, geometry);
55 |
56 | return geometry;
57 | }
58 | }
59 | """);
60 |
61 | return sb.ToString();
62 | }
63 | }
--------------------------------------------------------------------------------
/src/Generator.Icons/LucideIconInfoBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Text.Json;
3 |
4 | namespace Generator.Icons;
5 |
6 | public class LucideIconInfoBuilder
7 | {
8 | public record Info(string[]? Contributors, string[]? Categories, string[]? Tags);
9 |
10 | private readonly JsonSerializerOptions _options = new()
11 | {
12 | PropertyNameCaseInsensitive = true,
13 | };
14 |
15 | private readonly List<(string Name, Info Info)> _icon = [];
16 |
17 | public void AddIcon(string name, string path)
18 | {
19 | path = path.Replace(".svg", ".json");
20 |
21 | var json = File.ReadAllText(path);
22 |
23 | var info = JsonSerializer.Deserialize(json, _options) ?? throw new JsonException();
24 |
25 | _icon.Add((name, info));
26 | }
27 |
28 | public string Build()
29 | {
30 | var sb = new StringBuilder();
31 |
32 | //sb.AppendLine("namespace Lucide.Avalonia.Metadata;");
33 | //sb.AppendLine();
34 | //sb.AppendLine("public class LucideIconInfo");
35 | //sb.AppendLine("{");
36 | //sb.AppendLine(" public required LucideIconKind Kind { get; init; }");
37 | //sb.AppendLine();
38 | //sb.AppendLine(" public required string[] Contributors { get; init; }");
39 | //sb.AppendLine();
40 | //sb.AppendLine(" public required string[] Categories { get; init; }");
41 | //sb.AppendLine();
42 | //sb.AppendLine(" public required string[] Tags { get; init; }");
43 | //sb.AppendLine();
44 | //sb.AppendLine(" public bool Contains(string? value)");
45 | //sb.AppendLine(" {");
46 | //sb.AppendLine(" if (string.IsNullOrEmpty(value))");
47 | //sb.AppendLine(" {");
48 | //sb.AppendLine(" return true;");
49 | //sb.AppendLine(" }");
50 | //sb.AppendLine();
51 | //sb.AppendLine(" value = value.ToLower();");
52 | //sb.AppendLine();
53 | //sb.AppendLine(" if (Kind.ToString().Contains(value, StringComparison.OrdinalIgnoreCase))");
54 | //sb.AppendLine(" {");
55 | //sb.AppendLine(" return true;");
56 | //sb.AppendLine(" }");
57 | //sb.AppendLine();
58 | //sb.AppendLine(" foreach (var category in Categories)");
59 | //sb.AppendLine(" {");
60 | //sb.AppendLine(" if (category.Contains(value))");
61 | //sb.AppendLine(" {");
62 | //sb.AppendLine(" return true;");
63 | //sb.AppendLine(" }");
64 | //sb.AppendLine(" }");
65 | //sb.AppendLine();
66 | //sb.AppendLine(" foreach (var tag in Tags)");
67 | //sb.AppendLine(" {");
68 | //sb.AppendLine(" if (tag.Contains(value))");
69 | //sb.AppendLine(" {");
70 | //sb.AppendLine(" return true;");
71 | //sb.AppendLine(" }");
72 | //sb.AppendLine(" }");
73 | //sb.AppendLine();
74 | //sb.AppendLine(" return false;");
75 | //sb.AppendLine(" }");
76 |
77 | sb.AppendLine("""
78 | namespace Lucide.Avalonia.Metadata;
79 |
80 | public class LucideIconInfo
81 | {
82 | public required LucideIconKind Kind { get; init; }
83 |
84 | public required string[] Contributors { get; init; }
85 |
86 | public required string[] Categories { get; init; }
87 |
88 | public required string[] Tags { get; init; }
89 |
90 | public bool Contains(string? value, out int priority)
91 | {
92 | priority = 0;
93 |
94 | if (string.IsNullOrEmpty(value))
95 | {
96 | return true;
97 | }
98 |
99 | value = value.ToLower();
100 |
101 | var kind = Kind.ToString().ToLower();
102 |
103 | if (kind == value)
104 | {
105 | return true;
106 | }
107 |
108 | if (kind.StartsWith(value))
109 | {
110 | priority = 1;
111 | return true;
112 | }
113 |
114 | if (kind.Contains(value))
115 | {
116 | priority = 2;
117 | return true;
118 | }
119 |
120 | foreach (var category in Categories)
121 | {
122 | if (category.Contains(value))
123 | {
124 | priority = 3;
125 | return true;
126 | }
127 | }
128 |
129 | foreach (var tag in Tags)
130 | {
131 | if (tag.Contains(value))
132 | {
133 | priority = 4;
134 | return true;
135 | }
136 | }
137 |
138 | return false;
139 | }
140 | """);
141 |
142 | sb.AppendLine();
143 | sb.AppendLine(" public static LucideIconInfo GetIconInfo(LucideIconKind kind)");
144 | sb.AppendLine(" {");
145 | sb.AppendLine(" return kind switch");
146 | sb.AppendLine(" {");
147 |
148 | foreach (var (name, info) in _icon)
149 | {
150 | sb.AppendLine($" LucideIconKind.{name} => new LucideIconInfo");
151 | sb.AppendLine(" {");
152 | sb.AppendLine(" Kind = kind,");
153 | sb.AppendLine($" Contributors = [{CreateCSharpStringArray(info.Contributors)}],");
154 | sb.AppendLine($" Categories = [{CreateCSharpStringArray(info.Categories)}],");
155 | sb.AppendLine($" Tags = [{CreateCSharpStringArray(info.Tags)}],");
156 | sb.AppendLine(" },");
157 | }
158 |
159 | sb.AppendLine(" _ => throw new InvalidOperationException(),");
160 | sb.AppendLine(" };");
161 | sb.AppendLine(" }");
162 | sb.AppendLine("}");
163 |
164 | return sb.ToString();
165 | }
166 |
167 | private static string CreateCSharpStringArray(string[]? values)
168 | {
169 | if (values == null || values.Length == 0)
170 | {
171 | return string.Empty;
172 | }
173 |
174 | values = [.. values.Select(x => $"\"{x}\"")];
175 |
176 | return string.Join(", ", values);
177 | }
178 |
179 | public override string ToString() => Build();
180 | }
--------------------------------------------------------------------------------
/src/Generator.Icons/LucideIconKindBuilder.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace Generator.Icons;
4 |
5 | public class LucideIconKindBuilder
6 | {
7 | private readonly List _icon = [];
8 |
9 | public void AddIcon(string name) => _icon.Add(name);
10 |
11 | public string Build()
12 | {
13 | var sb = new StringBuilder();
14 |
15 | sb.AppendLine("namespace Lucide.Avalonia;");
16 | sb.AppendLine();
17 | sb.AppendLine("public enum LucideIconKind");
18 | sb.AppendLine("{");
19 |
20 | foreach (var name in _icon)
21 | {
22 | sb.AppendLine($" {name},");
23 | }
24 |
25 | sb.AppendLine("}");
26 |
27 | return sb.ToString();
28 | }
29 |
30 | public override string ToString() => Build();
31 | }
--------------------------------------------------------------------------------
/src/Generator.Icons/Program.cs:
--------------------------------------------------------------------------------
1 | Console.WriteLine("Starting the icon generation process...");
2 |
3 | if (args.Length != 2)
4 | {
5 | ExitWithError("Two arguments are required: and .");
6 | }
7 |
8 | var lucideRepositoryPath = args[0];
9 | var generatedCsFilesPath = args[1];
10 |
11 | if (Directory.Exists(generatedCsFilesPath) == false)
12 | {
13 | ExitWithError($"The directory '{generatedCsFilesPath}' does not exist.");
14 | }
15 |
16 | lucideRepositoryPath = Path.Combine(lucideRepositoryPath, "icons");
17 |
18 | if (Directory.Exists(lucideRepositoryPath) == false)
19 | {
20 | ExitWithError($"The directory '{lucideRepositoryPath}' does not exist.");
21 | }
22 |
23 | var paths = Directory.GetFiles(lucideRepositoryPath, "*.svg");
24 |
25 | if (paths.Length == 0)
26 | {
27 | ExitWithError("No SVG files found in the specified directory.");
28 | }
29 |
30 | paths = [.. paths.OrderBy(path => Path.GetFileNameWithoutExtension(path))];
31 |
32 | var iconKindBuilder = new LucideIconKindBuilder();
33 | var iconInfoBuilder = new LucideIconInfoBuilder();
34 | var iconToGeometryBuilder = new IconToGeometryBuilder();
35 |
36 | foreach (var path in paths)
37 | {
38 | var name = Path.GetFileNameWithoutExtension(path);
39 |
40 | Utilities.NormalizeName(ref name);
41 |
42 | Console.WriteLine($"Creating icon: {name}");
43 |
44 | iconKindBuilder.AddIcon(name);
45 | iconInfoBuilder.AddIcon(name, path);
46 | iconToGeometryBuilder.AddIcon(name, path);
47 | }
48 |
49 | var iconKindPath = Path.Combine(generatedCsFilesPath, "LucideIconKind.cs");
50 | var iconInfoPath = Path.Combine(generatedCsFilesPath, "Metadata", "LucideIconInfo.cs");
51 | var iconToGeometryPath = Path.Combine(generatedCsFilesPath, "IconToGeometry.cs");
52 |
53 | Console.WriteLine("Writing generated files...");
54 |
55 | File.WriteAllText(iconKindPath, iconKindBuilder.Build());
56 | File.WriteAllText(iconInfoPath, iconInfoBuilder.Build());
57 | File.WriteAllText(iconToGeometryPath, iconToGeometryBuilder.Build());
58 |
59 | Console.WriteLine("Icon generation process completed.");
60 |
61 | static void ExitWithError(string message)
62 | {
63 | Console.Error.WriteLine(message);
64 |
65 | Environment.Exit(1);
66 | }
--------------------------------------------------------------------------------
/src/Generator.Icons/Usings.cs:
--------------------------------------------------------------------------------
1 | global using Generator.Icons;
2 | global using SkiaSharp;
3 | global using Svg.Skia;
4 | global using SvgToXaml.Model.Drawing;
5 | global using System.Diagnostics;
6 | global using System.Text;
7 |
--------------------------------------------------------------------------------
/src/Generator.Icons/Utilities.cs:
--------------------------------------------------------------------------------
1 | namespace Generator.Icons;
2 |
3 | public static class Utilities
4 | {
5 | [ThreadStatic]
6 | private static StringBuilder? _sb;
7 |
8 | public static void NormalizeName(ref string name)
9 | {
10 | if (_sb == null)
11 | {
12 | _sb = new StringBuilder();
13 | }
14 | else
15 | {
16 | _sb.Clear();
17 | }
18 |
19 | var words = name.Split('-');
20 |
21 | foreach (var word in words)
22 | {
23 | _sb.Append(char.ToUpper(word[0]));
24 |
25 | if (word.Length > 1)
26 | {
27 | _sb.Append(word[1..]);
28 | }
29 | }
30 |
31 | name = _sb.ToString();
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/ChangeInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace Generator.ReleaseNotes;
5 |
6 | public partial class ChangeInfo
7 | {
8 | public required string[] AddedIcons { get; init; }
9 |
10 | public required string[] ModifiedIcons { get; init; }
11 |
12 | public string MarkdownText => CreateMarkdown();
13 |
14 | public static ChangeInfo Analyze(GitDiff iconToGeometryDiff)
15 | {
16 | var addedLines = iconToGeometryDiff.AddedLines;
17 | var removedLines = iconToGeometryDiff.RemovedLines;
18 |
19 | var addedIcons = addedLines.Select(ExtractIconName).ToArray();
20 | var removedIcons = removedLines.Select(ExtractIconName).ToArray();
21 |
22 | var newIcons = addedIcons.Except(removedIcons).ToArray();
23 | var modifiedIcons = removedIcons.Intersect(addedIcons).ToArray();
24 |
25 | return new ChangeInfo
26 | {
27 | AddedIcons = newIcons,
28 | ModifiedIcons = modifiedIcons
29 | };
30 | }
31 |
32 | private string CreateMarkdown()
33 | {
34 | var builder = new StringBuilder();
35 |
36 | if (AddedIcons.Length > 0)
37 | {
38 | builder.AppendLine("## New icons 🎨");
39 |
40 | foreach (var addedIcon in AddedIcons)
41 | {
42 | var link = CreateLinkToWeb(addedIcon);
43 |
44 | builder.AppendLine($"- The `{addedIcon}` icon is added ({link})");
45 | }
46 |
47 | builder.AppendLine();
48 | }
49 |
50 | if (ModifiedIcons.Length > 0)
51 | {
52 | builder.AppendLine("## Modified Icons 🔨");
53 |
54 | foreach (var modifiedIcon in ModifiedIcons)
55 | {
56 | var link = CreateLinkToWeb(modifiedIcon);
57 |
58 | builder.AppendLine($"- The `{modifiedIcon}` icon is modified ({link})");
59 | }
60 |
61 | builder.AppendLine();
62 | }
63 |
64 | return builder.ToString();
65 | }
66 |
67 | private static string CreateLinkToWeb(string iconName)
68 | {
69 | var name = NormalizeName(iconName);
70 | var link = $"https://lucide.dev/icons/{name}";
71 |
72 | return $"[{name}]({link})";
73 | }
74 |
75 | ///
76 | /// Change 'IconName' to 'icon-name'
77 | ///
78 | /// The icon name to normalize (PascalCase)
79 | /// The normalized icon name (kebab-case)
80 | private static string NormalizeName(string name)
81 | {
82 | var result = new StringBuilder();
83 |
84 | result.Append(char.ToLower(name[0]));
85 |
86 | for (var i = 1; i < name.Length; i++)
87 | {
88 | var character = name[i];
89 |
90 | if (char.IsUpper(character) || char.IsNumber(character))
91 | {
92 | result.Append('-');
93 | result.Append(char.ToLower(character));
94 | }
95 | else
96 | {
97 | result.Append(character);
98 | }
99 | }
100 |
101 | return result.ToString();
102 | }
103 |
104 | private static string ExtractIconName(string line)
105 | {
106 | var match = IconNameRegex().Match(line);
107 |
108 | if (match.Success == false)
109 | {
110 | throw new Exception("Could not extract icon name");
111 | }
112 |
113 | return match.Groups[1].Value;
114 | }
115 |
116 | [GeneratedRegex(@"LucideIconKind\.(\w+)")]
117 | private static partial Regex IconNameRegex();
118 | }
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/ChangeNotesGenerator.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace Generator.ReleaseNotes;
4 |
5 | public static class ChangeNotesGenerator
6 | {
7 | private const string IconToGeometryPath = "src/Lucide.Avalonia/IconToGeometry.cs";
8 |
9 | public static ChangeInfo Generate(string headTag)
10 | {
11 | var baseTag = new StringBuilder();
12 |
13 | ProcessRunner
14 | .Create("git")
15 | .WithArguments($"describe --tags --abbrev=0 {headTag}^")
16 | .WithRedirectOutput(baseTag)
17 | .Execute();
18 |
19 | return Generate(headTag, baseTag.ToString().Trim());
20 | }
21 |
22 | private static ChangeInfo Generate(string headTag, string baseTag)
23 | {
24 | Console.WriteLine($"baseTag: {baseTag}");
25 | Console.WriteLine($"headTag: {headTag}");
26 |
27 | Console.WriteLine("Generating icons changes...");
28 |
29 | var diff = GitDiff.Run(baseTag, headTag, IconToGeometryPath);
30 |
31 | return ChangeInfo.Analyze(diff);
32 | }
33 | }
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/Generator.ReleaseNotes.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | net9.0
6 | enable
7 | enable
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/GitDiff.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace Generator.ReleaseNotes;
4 |
5 | public class GitDiff
6 | {
7 | public static GitDiff Run(string baseCommit, string headCommit, string path)
8 | {
9 | var output = new StringBuilder();
10 |
11 | ProcessRunner.Create("git")
12 | .WithArguments($"diff {baseCommit} {headCommit} -- {path}")
13 | .WithRedirectOutput(output)
14 | .Execute();
15 |
16 | return new GitDiff(output.ToString());
17 | }
18 |
19 | public string[] AddedLines { get; }
20 |
21 | public string[] RemovedLines { get; }
22 |
23 | private GitDiff(string diff)
24 | {
25 | var lines = diff.Split(['\n', '\r']);
26 |
27 | var added = new List();
28 | var removed = new List();
29 |
30 | foreach (var line in lines)
31 | {
32 | if (line.StartsWith('+') && line.StartsWith("+++") == false)
33 | {
34 | added.Add(line);
35 | }
36 |
37 | if (line.StartsWith('-') && line.StartsWith("---") == false)
38 | {
39 | removed.Add(line);
40 | }
41 | }
42 |
43 | AddedLines = [.. added];
44 | RemovedLines = [.. removed];
45 | }
46 | }
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/GitHubReleaseNotesUpdater.cs:
--------------------------------------------------------------------------------
1 | using Octokit;
2 |
3 | namespace Generator.ReleaseNotes;
4 |
5 | public static class GitHubReleaseNotesUpdater
6 | {
7 | public static async Task UpdateReleaseNotes(string tagName, string releaseNotesMarkdown)
8 | {
9 | Console.WriteLine("Updating GitHub release notes...");
10 |
11 | var token = Environment.GetEnvironmentVariable("GITHUB_TOKEN")
12 | ??
13 | throw new InvalidOperationException("GITHUB_TOKEN environment variable is not set.");
14 |
15 | var repositoryId = long.Parse(Environment.GetEnvironmentVariable("REPOSITORY_ID")
16 | ??
17 | throw new InvalidOperationException("REPOSITORY_ID environment variable is not set."));
18 |
19 | var github = new GitHubClient(new ProductHeaderValue("release-notes-updater"))
20 | {
21 | Credentials = new Credentials(token)
22 | };
23 |
24 | var release = await github.Repository.Release.Get(repositoryId, tagName);
25 |
26 | var updateRelease = release.ToUpdate();
27 |
28 | updateRelease.Body = releaseNotesMarkdown + release.Body;
29 |
30 | _ = await github.Repository.Release.Edit(repositoryId, release.Id, updateRelease);
31 |
32 | Console.WriteLine("Release notes updated successfully.");
33 | }
34 | }
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/ProcessRunner.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Text;
3 |
4 | namespace Generator.ReleaseNotes;
5 |
6 | public ref struct ProcessRunner
7 | {
8 | private readonly ProcessStartInfo _info;
9 |
10 | private StringBuilder? _output;
11 |
12 | public static ProcessRunner Create(string processPath) => new(processPath);
13 |
14 | private ProcessRunner(string processPath)
15 | {
16 | _info = new ProcessStartInfo(processPath);
17 | }
18 |
19 | public readonly ProcessRunner WithArguments(string arguments)
20 | {
21 | _info.Arguments = arguments;
22 | return this;
23 | }
24 |
25 | public readonly ProcessRunner WithWorkingDirectory(string workingDirectory)
26 | {
27 | _info.WorkingDirectory = workingDirectory;
28 | return this;
29 | }
30 |
31 | public ProcessRunner WithRedirectOutput(StringBuilder buffer)
32 | {
33 | _info.RedirectStandardOutput = true;
34 | _output = buffer;
35 |
36 | return this;
37 | }
38 |
39 | public readonly void Execute()
40 | {
41 | var process = Process.Start(_info)
42 | ??
43 | throw new InvalidOperationException("Failed to start process");
44 |
45 | if (_output != null)
46 | {
47 | var output = _output;
48 |
49 | process.OutputDataReceived += (_, args) => output.AppendLine(args.Data);
50 | process.BeginOutputReadLine();
51 | }
52 |
53 | process.WaitForExit();
54 |
55 | if (process.ExitCode != 0)
56 | {
57 | throw new InvalidOperationException("Process exited with code " + process.ExitCode);
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/Generator.ReleaseNotes/Program.cs:
--------------------------------------------------------------------------------
1 | using Generator.ReleaseNotes;
2 |
3 | if (args.Length == 0)
4 | {
5 | throw new InvalidOperationException("No arguments were provided.");
6 | }
7 |
8 | var tagName = args[0];
9 |
10 | var changeInfo = ChangeNotesGenerator.Generate(tagName);
11 |
12 | Console.WriteLine("===== Release Notes Preview =====");
13 |
14 | Console.WriteLine(changeInfo.MarkdownText);
15 |
16 | await GitHubReleaseNotesUpdater.UpdateReleaseNotes(tagName, changeInfo.MarkdownText);
17 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/App.axaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/App.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia.Gallery;
2 |
3 | public partial class App : Application
4 | {
5 | public override void Initialize()
6 | {
7 | AvaloniaXamlLoader.Load(this);
8 | }
9 |
10 | public override void OnFrameworkInitializationCompleted()
11 | {
12 | if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
13 | {
14 | desktop.MainWindow = new MainWindow
15 | {
16 | DataContext = new MainWindowViewModel(),
17 | };
18 | }
19 |
20 | base.OnFrameworkInitializationCompleted();
21 | }
22 | }
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Assets/lucide-logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dme-compunet/Lucide.Avalonia/8e4b5c33dbdcb9f000b70edfe7b51511f9de91eb/src/Lucide.Avalonia.Gallery/Assets/lucide-logo.ico
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Global/Usings.cs:
--------------------------------------------------------------------------------
1 | global using Avalonia;
2 | global using Avalonia.Controls.ApplicationLifetimes;
3 | global using Avalonia.Input.Platform;
4 | global using Avalonia.Markup.Xaml;
5 | global using Avalonia.ReactiveUI;
6 | global using Lucide.Avalonia.Gallery.Services;
7 | global using Lucide.Avalonia.Gallery.ViewModels;
8 | global using Lucide.Avalonia.Gallery.Views;
9 | global using Lucide.Avalonia.Metadata;
10 | global using ReactiveUI;
11 | global using SukiUI;
12 | global using SukiUI.Controls;
13 | global using SukiUI.Toasts;
14 | global using System;
15 | global using System.Collections.Frozen;
16 | global using System.Collections.Generic;
17 | global using System.Reactive.Linq;
18 | global using System.Threading.Tasks;
19 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Lucide.Avalonia.Gallery.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | WinExe
4 | net9.0
5 | enable
6 | preview
7 | Assets/lucide-logo.ico
8 | true
9 | app.manifest
10 | true
11 |
12 |
13 |
14 | true
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | None
29 | All
30 |
31 |
32 |
33 | all
34 | runtime; build; native; contentfiles; analyzers; buildtransitive
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Program.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia.Gallery;
2 |
3 | internal sealed class Program
4 | {
5 | // Initialization code. Don't use any Avalonia, third-party APIs or any
6 | // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
7 | // yet and stuff might break.
8 | [STAThread]
9 | public static void Main(string[] args) => BuildAvaloniaApp()
10 | .StartWithClassicDesktopLifetime(args);
11 |
12 | // Avalonia configuration, don't remove; also used by visual designer.
13 | public static AppBuilder BuildAvaloniaApp()
14 | => AppBuilder.Configure()
15 | .UsePlatformDetect()
16 | .WithInterFont()
17 | .LogToTrace()
18 | .UseReactiveUI();
19 | }
20 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Services/ClipboardService.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia.Gallery.Services;
2 |
3 | public class ClipboardService
4 | {
5 | private readonly IClipboard? _clipboard;
6 |
7 | public static ClipboardService Instance { get; } = new();
8 |
9 | public ClipboardService()
10 | {
11 | if (Application.Current?.ApplicationLifetime
12 | is IClassicDesktopStyleApplicationLifetime lifetime)
13 | {
14 | _clipboard = lifetime.MainWindow?.Clipboard;
15 | }
16 | }
17 |
18 | public async Task SetClipboardAsync(string value)
19 | {
20 | if (_clipboard != null)
21 | {
22 | await _clipboard.SetTextAsync(value);
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Services/NotificationService.cs:
--------------------------------------------------------------------------------
1 | using SukiUI.Toasts;
2 |
3 | namespace Lucide.Avalonia.Gallery.Services;
4 |
5 | public class NotificationService
6 | {
7 | public static NotificationService Singleton { get; } = new();
8 |
9 | public SukiToastManager ToastManager { get; } = new();
10 |
11 | public void ShowNotification(string title, string message)
12 | {
13 | ToastManager.CreateSimpleInfoToast()
14 | .WithTitle(title)
15 | .WithContent(message)
16 | .Queue();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/ViewModels/IconViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia.Gallery.ViewModels;
2 |
3 | [Reactive]
4 | public partial class IconViewModel(LucideIconKind kind)
5 | {
6 | public LucideIconKind Kind { get; } = kind;
7 |
8 | public partial double Size { get; set; } = 24;
9 |
10 | public partial double StrokeWidth { get; set; } = 1.5;
11 |
12 | public string Tip => $"{Kind}";
13 |
14 | public void CopyNameCommand() => SetClipboard($"{Kind}");
15 |
16 | public void CopyXamlCommand() => SetClipboard($"");
17 |
18 | public void CopyExtensionCommand() => SetClipboard($"{{LucideIconContent {Kind}}}");
19 |
20 | //private string BuildTipText()
21 | //{
22 | // var sb = new StringBuilder();
23 |
24 | // var info = LucideIconInfo.GetIconInfo(Kind);
25 |
26 | // sb.AppendLine($"{Kind}");
27 | // sb.AppendLine();
28 | // sb.AppendLine("Contributors:");
29 |
30 | // foreach (var contributor in info.Contributors)
31 | // {
32 | // sb.AppendLine($" {contributor}");
33 | // }
34 |
35 | // sb.AppendLine();
36 | // sb.AppendLine("Categories:");
37 |
38 | // foreach (var category in info.Categories)
39 | // {
40 | // sb.AppendLine($" {category}");
41 | // }
42 |
43 | // sb.AppendLine();
44 | // sb.AppendLine("Tags:");
45 |
46 | // foreach (var tag in info.Tags)
47 | // {
48 | // sb.AppendLine($" {tag}");
49 | // }
50 |
51 | // return sb.ToString();
52 | //}
53 |
54 | private static async void SetClipboard(string text)
55 | {
56 | await ClipboardService.Instance.SetClipboardAsync(text);
57 |
58 | NotificationService.Singleton.ShowNotification("Icon Copied!", $"The text \"{text}\" has been copied to clipboard.");
59 | }
60 |
61 | public static IconViewModel[] CreateIconCollection()
62 | {
63 | var kinds = Enum.GetValues();
64 |
65 | var icons = new IconViewModel[kinds.Length];
66 |
67 | for (int i = 0; i < kinds.Length; i++)
68 | {
69 | icons[i] = new IconViewModel(kinds[i]);
70 | }
71 |
72 | return icons;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/ViewModels/MainWindowViewModel.cs:
--------------------------------------------------------------------------------
1 | using SukiUI.Toasts;
2 |
3 | namespace Lucide.Avalonia.Gallery.ViewModels;
4 |
5 | [Reactive]
6 | public partial class MainWindowViewModel : ReactiveViewModel
7 | {
8 | private readonly Lazy _allIconsLazy = new(IconViewModel.CreateIconCollection);
9 | private readonly Lazy> _iconsInfo = new(CreateIconCollectionInfo);
10 |
11 | public SukiToastManager ToastManager { get; } = NotificationService.Singleton.ToastManager;
12 |
13 | public partial bool IsBusy { get; set; }
14 |
15 | public partial double Size { get; set; } = 24;
16 |
17 | public partial float StrokeWidth { get; set; } = 1.5f;
18 |
19 | public partial string? SearchText { get; set; }
20 |
21 | public partial IconViewModel[]? Icons { get; set; }
22 |
23 | public MainWindowViewModel()
24 | {
25 | this.WhenAnyValue(x => x.Size, x => x.StrokeWidth)
26 | .Throttle(TimeSpan.FromSeconds(.1))
27 | .Subscribe(_ => UpdateIcons());
28 |
29 | this.WhenAnyValue(x => x.SearchText)
30 | .Throttle(TimeSpan.FromSeconds(.4))
31 | .Subscribe(FilterIconsAsync);
32 |
33 | Task.Run(() =>
34 | {
35 | Icons = _allIconsLazy.Value;
36 | });
37 | }
38 |
39 | public void ResetCommand()
40 | {
41 | Size = 24;
42 | StrokeWidth = 1.5f;
43 | }
44 |
45 | public void SwitchBaseThemeCommand() => SukiTheme.GetInstance().SwitchBaseTheme();
46 |
47 | private void UpdateIcons()
48 | {
49 | if (Icons == null)
50 | {
51 | return;
52 | }
53 |
54 | foreach (var icon in Icons)
55 | {
56 | icon.Size = Size;
57 | icon.StrokeWidth = StrokeWidth;
58 | }
59 | }
60 |
61 | private void FilterIcons(string? value)
62 | {
63 | var icons = _allIconsLazy.Value;
64 |
65 | var queue = new PriorityQueue(icons.Length);
66 |
67 | if (string.IsNullOrWhiteSpace(value))
68 | {
69 | Icons = icons;
70 |
71 | return;
72 | }
73 |
74 | value = value.ToLower();
75 |
76 | foreach (var icon in icons)
77 | {
78 | var info = _iconsInfo.Value[icon.Kind];
79 |
80 | if (info.Contains(value, out var priority))
81 | {
82 | queue.Enqueue(icon, priority);
83 | }
84 | }
85 |
86 | var list = new List(queue.Count);
87 |
88 | while (queue.Count > 0)
89 | {
90 | list.Add(queue.Dequeue());
91 | }
92 |
93 | Icons = [.. list];
94 | }
95 |
96 | private async void FilterIconsAsync(string? filter)
97 | {
98 | IsBusy = true;
99 |
100 | await Task.Delay(100);
101 |
102 | await Task.Run(() =>
103 | {
104 | FilterIcons(filter);
105 | });
106 |
107 | IsBusy = false;
108 | }
109 |
110 | private static FrozenDictionary CreateIconCollectionInfo()
111 | {
112 | var kinds = Enum.GetValues();
113 |
114 | var result = new Dictionary(kinds.Length);
115 |
116 | foreach (var kind in kinds)
117 | {
118 | result[kind] = LucideIconInfo.GetIconInfo(kind);
119 | }
120 |
121 | return result.ToFrozenDictionary();
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/ViewModels/ReactiveViewModel.cs:
--------------------------------------------------------------------------------
1 | using ReactiveUI;
2 |
3 | namespace Lucide.Avalonia.Gallery.ViewModels;
4 |
5 | public class ReactiveViewModel
6 | : ReactiveObject
7 | { }
8 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Views/MainWindow.axaml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
25 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | F1 M14 12C14 9.79086 12.2091 8 10 8C7.79086 8 6 9.79086 6 12C6 16.4183 9.58172 20 14 20C18.4183 20 22 16.4183 22 12C22 8.446 20.455 5.25285 18 3.05557F1 M10 12C10 14.2091 11.7909 16 14 16C16.2091 16 18 14.2091 18 12C18 7.58172 14.4183 4 10 4C5.58172 4 2 7.58172 2 12C2 15.5841 3.57127 18.8012 6.06253 21
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
86 |
87 |
88 |
89 |
90 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
125 |
126 |
129 |
130 |
131 |
132 |
135 |
138 |
141 |
142 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/Views/MainWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia.Gallery.Views;
2 |
3 | public partial class MainWindow : SukiWindow
4 | {
5 | public MainWindow()
6 | {
7 | InitializeComponent();
8 | }
9 | }
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.Gallery/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio Version 17
3 | VisualStudioVersion = 17.5.2.0
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucide.Avalonia", "Lucide.Avalonia\Lucide.Avalonia.csproj", "{3B0FC7C7-71BD-DEF4-7A43-5D07A632E4DB}"
6 | EndProject
7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generator.Icons", "Generator.Icons\Generator.Icons.csproj", "{C0A447D5-C19A-44F7-9CE5-17ADF0A28BF5}"
8 | EndProject
9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lucide.Avalonia.Gallery", "Lucide.Avalonia.Gallery\Lucide.Avalonia.Gallery.csproj", "{EDD7CDF6-3C2F-4587-80AD-32FF5BCCF748}"
10 | EndProject
11 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SukiUI", "..\ext\SukiUI\SukiUI\SukiUI.csproj", "{68D873F7-2620-45CF-D536-4F46B845F8D7}"
12 | EndProject
13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Generator.ReleaseNotes", "Generator.ReleaseNotes\Generator.ReleaseNotes.csproj", "{6984126F-B4F4-4F2D-9012-3AB3F8A65B4B}"
14 | EndProject
15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generators", "Generators", "{A54FE795-E59F-48E8-B4A9-8EEC517C0128}"
16 | EndProject
17 | Global
18 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
19 | Debug|Any CPU = Debug|Any CPU
20 | Release|Any CPU = Release|Any CPU
21 | EndGlobalSection
22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
23 | {3B0FC7C7-71BD-DEF4-7A43-5D07A632E4DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24 | {3B0FC7C7-71BD-DEF4-7A43-5D07A632E4DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
25 | {3B0FC7C7-71BD-DEF4-7A43-5D07A632E4DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
26 | {3B0FC7C7-71BD-DEF4-7A43-5D07A632E4DB}.Release|Any CPU.Build.0 = Release|Any CPU
27 | {C0A447D5-C19A-44F7-9CE5-17ADF0A28BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
28 | {C0A447D5-C19A-44F7-9CE5-17ADF0A28BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
29 | {C0A447D5-C19A-44F7-9CE5-17ADF0A28BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
30 | {C0A447D5-C19A-44F7-9CE5-17ADF0A28BF5}.Release|Any CPU.Build.0 = Release|Any CPU
31 | {EDD7CDF6-3C2F-4587-80AD-32FF5BCCF748}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
32 | {EDD7CDF6-3C2F-4587-80AD-32FF5BCCF748}.Debug|Any CPU.Build.0 = Debug|Any CPU
33 | {EDD7CDF6-3C2F-4587-80AD-32FF5BCCF748}.Release|Any CPU.ActiveCfg = Release|Any CPU
34 | {EDD7CDF6-3C2F-4587-80AD-32FF5BCCF748}.Release|Any CPU.Build.0 = Release|Any CPU
35 | {68D873F7-2620-45CF-D536-4F46B845F8D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
36 | {68D873F7-2620-45CF-D536-4F46B845F8D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
37 | {68D873F7-2620-45CF-D536-4F46B845F8D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
38 | {68D873F7-2620-45CF-D536-4F46B845F8D7}.Release|Any CPU.Build.0 = Release|Any CPU
39 | {6984126F-B4F4-4F2D-9012-3AB3F8A65B4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
40 | {6984126F-B4F4-4F2D-9012-3AB3F8A65B4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
41 | {6984126F-B4F4-4F2D-9012-3AB3F8A65B4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
42 | {6984126F-B4F4-4F2D-9012-3AB3F8A65B4B}.Release|Any CPU.Build.0 = Release|Any CPU
43 | EndGlobalSection
44 | GlobalSection(SolutionProperties) = preSolution
45 | HideSolutionNode = FALSE
46 | EndGlobalSection
47 | GlobalSection(ExtensibilityGlobals) = postSolution
48 | SolutionGuid = {2B8DF243-C10F-49D4-9993-09C19AD61E40}
49 | EndGlobalSection
50 | GlobalSection(NestedProjects) = preSolution
51 | {C0A447D5-C19A-44F7-9CE5-17ADF0A28BF5} = {A54FE795-E59F-48E8-B4A9-8EEC517C0128}
52 | {6984126F-B4F4-4F2D-9012-3AB3F8A65B4B} = {A54FE795-E59F-48E8-B4A9-8EEC517C0128}
53 | EndGlobalSection
54 | EndGlobal
55 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia/Global/Assembly.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Metadata;
2 |
3 | [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Lucide.Avalonia")]
--------------------------------------------------------------------------------
/src/Lucide.Avalonia/Global/Usings.cs:
--------------------------------------------------------------------------------
1 | global using Avalonia;
2 | global using Avalonia.Controls;
3 | global using Avalonia.Controls.Documents;
4 | global using Avalonia.Markup.Xaml;
5 | global using Avalonia.Media;
6 | global using System.Collections.Frozen;
--------------------------------------------------------------------------------
/src/Lucide.Avalonia/Lucide.Avalonia.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 |
8 |
9 |
10 | Implementation of the Lucide icon library for AvaloniaUI
11 | https://github.com/dme-compunet/Lucide.Avalonia
12 | MIT
13 | README.md
14 | csharp avalonia-ui icons lucide
15 | lucide-logo-nuget.png
16 | Compunet
17 | 0.1.0
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia/LucideIcon.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia;
2 |
3 | public class LucideIcon : Control
4 | {
5 | private const float RawIconSize = 24;
6 |
7 | public static readonly StyledProperty SizeProperty =
8 | AvaloniaProperty.Register(nameof(Size), 24);
9 |
10 | public static readonly StyledProperty ForegroundProperty =
11 | TextElement.ForegroundProperty.AddOwner();
12 |
13 | public static readonly StyledProperty StrokeWidthProperty =
14 | AvaloniaProperty.Register(nameof(StrokeWidth), 1.5);
15 |
16 | public static readonly StyledProperty KindProperty =
17 | AvaloniaProperty.Register(nameof(Kind));
18 |
19 | private Pen? _stroke;
20 | private Geometry? _geometry;
21 |
22 | public double Size
23 | {
24 | get => GetValue(SizeProperty);
25 | set => SetValue(SizeProperty, value);
26 | }
27 |
28 | public IBrush? Foreground
29 | {
30 | get => GetValue(ForegroundProperty);
31 | set => SetValue(ForegroundProperty, value);
32 | }
33 |
34 | public double StrokeWidth
35 | {
36 | get => GetValue(StrokeWidthProperty);
37 | set => SetValue(StrokeWidthProperty, value);
38 | }
39 | public LucideIconKind? Kind
40 | {
41 | get => GetValue(KindProperty);
42 | set => SetValue(KindProperty, value);
43 | }
44 |
45 |
46 | static LucideIcon()
47 | {
48 | AffectsRender(KindProperty,
49 | SizeProperty,
50 | ForegroundProperty,
51 | StrokeWidthProperty);
52 |
53 | AffectsMeasure(SizeProperty);
54 | }
55 |
56 | protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
57 | {
58 | if (change.Property == KindProperty)
59 | {
60 | var kind = change.GetNewValue();
61 |
62 | _geometry = kind == null
63 | ? null
64 | : IconToGeometry.CreateGeometry(kind.Value);
65 | }
66 | else if (change.Property == ForegroundProperty || change.Property == StrokeWidthProperty)
67 | {
68 | var brush = Foreground;
69 | var width = StrokeWidth;
70 |
71 | if (_stroke == null)
72 | {
73 | _stroke = new Pen(brush, width, null, PenLineCap.Round, PenLineJoin.Round);
74 | }
75 | else
76 | {
77 | _stroke.Brush = brush;
78 | _stroke.Thickness = width;
79 | }
80 | }
81 |
82 | base.OnPropertyChanged(change);
83 | }
84 |
85 | protected override Size MeasureOverride(Size availableSize) => GetIconSize();
86 |
87 | protected override Size ArrangeOverride(Size finalSize) => GetIconSize();
88 |
89 | public override void Render(DrawingContext context)
90 | {
91 | if (_geometry is null)
92 | {
93 | return;
94 | }
95 |
96 | AddScale(context);
97 |
98 | context.DrawRectangle(Brushes.Transparent, null, new Rect(0, 0, Bounds.Width, Bounds.Height));
99 |
100 | context.DrawGeometry(null, _stroke, _geometry);
101 | }
102 |
103 | private void AddScale(DrawingContext context)
104 | {
105 | if (IsSet(SizeProperty))
106 | {
107 | var scale = Size / RawIconSize;
108 |
109 | context.PushTransform(Matrix.CreateScale(scale, scale));
110 | }
111 | }
112 |
113 | private Size GetIconSize() => new(Size, Size);
114 | }
115 |
--------------------------------------------------------------------------------
/src/Lucide.Avalonia/LucideIconContentExtension.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia;
2 |
3 | public class LucideIconContentExtension : MarkupExtension
4 | {
5 | public LucideIconKind Kind { get; set; }
6 |
7 | public double? Size { get; set; }
8 |
9 | public double? StrokeWidth { get; set; }
10 |
11 | public LucideIconContentExtension() { }
12 |
13 | public LucideIconContentExtension(LucideIconKind kind) => Kind = kind;
14 |
15 | public LucideIconContentExtension(LucideIconKind kind, double size)
16 | {
17 | Kind = kind;
18 | Size = size;
19 | }
20 |
21 | public LucideIconContentExtension(LucideIconKind kind, double size, double strokeWidth)
22 | {
23 | Kind = kind;
24 | Size = size;
25 | StrokeWidth = strokeWidth;
26 | }
27 |
28 | public override object ProvideValue(IServiceProvider serviceProvider)
29 | {
30 | var icon = new LucideIcon
31 | {
32 | Kind = Kind,
33 | };
34 |
35 | if (Size.HasValue)
36 | {
37 | icon.Size = Size.Value;
38 | }
39 |
40 | if (StrokeWidth.HasValue)
41 | {
42 | icon.StrokeWidth = StrokeWidth.Value;
43 | }
44 |
45 | return icon;
46 | }
47 | }
--------------------------------------------------------------------------------
/src/Lucide.Avalonia/LucideIconKind.cs:
--------------------------------------------------------------------------------
1 | namespace Lucide.Avalonia;
2 |
3 | public enum LucideIconKind
4 | {
5 | AArrowDown,
6 | AArrowUp,
7 | ALargeSmall,
8 | Accessibility,
9 | Activity,
10 | AirVent,
11 | Airplay,
12 | AlarmClock,
13 | AlarmClockCheck,
14 | AlarmClockMinus,
15 | AlarmClockOff,
16 | AlarmClockPlus,
17 | AlarmSmoke,
18 | Album,
19 | AlignCenter,
20 | AlignCenterHorizontal,
21 | AlignCenterVertical,
22 | AlignEndHorizontal,
23 | AlignEndVertical,
24 | AlignHorizontalDistributeCenter,
25 | AlignHorizontalDistributeEnd,
26 | AlignHorizontalDistributeStart,
27 | AlignHorizontalJustifyCenter,
28 | AlignHorizontalJustifyEnd,
29 | AlignHorizontalJustifyStart,
30 | AlignHorizontalSpaceAround,
31 | AlignHorizontalSpaceBetween,
32 | AlignJustify,
33 | AlignLeft,
34 | AlignRight,
35 | AlignStartHorizontal,
36 | AlignStartVertical,
37 | AlignVerticalDistributeCenter,
38 | AlignVerticalDistributeEnd,
39 | AlignVerticalDistributeStart,
40 | AlignVerticalJustifyCenter,
41 | AlignVerticalJustifyEnd,
42 | AlignVerticalJustifyStart,
43 | AlignVerticalSpaceAround,
44 | AlignVerticalSpaceBetween,
45 | Ambulance,
46 | Ampersand,
47 | Ampersands,
48 | Amphora,
49 | Anchor,
50 | Angry,
51 | Annoyed,
52 | Antenna,
53 | Anvil,
54 | Aperture,
55 | AppWindow,
56 | AppWindowMac,
57 | Apple,
58 | Archive,
59 | ArchiveRestore,
60 | ArchiveX,
61 | Armchair,
62 | ArrowBigDown,
63 | ArrowBigDownDash,
64 | ArrowBigLeft,
65 | ArrowBigLeftDash,
66 | ArrowBigRight,
67 | ArrowBigRightDash,
68 | ArrowBigUp,
69 | ArrowBigUpDash,
70 | ArrowDown,
71 | ArrowDown01,
72 | ArrowDown10,
73 | ArrowDownAZ,
74 | ArrowDownFromLine,
75 | ArrowDownLeft,
76 | ArrowDownNarrowWide,
77 | ArrowDownRight,
78 | ArrowDownToDot,
79 | ArrowDownToLine,
80 | ArrowDownUp,
81 | ArrowDownWideNarrow,
82 | ArrowDownZA,
83 | ArrowLeft,
84 | ArrowLeftFromLine,
85 | ArrowLeftRight,
86 | ArrowLeftToLine,
87 | ArrowRight,
88 | ArrowRightFromLine,
89 | ArrowRightLeft,
90 | ArrowRightToLine,
91 | ArrowUp,
92 | ArrowUp01,
93 | ArrowUp10,
94 | ArrowUpAZ,
95 | ArrowUpDown,
96 | ArrowUpFromDot,
97 | ArrowUpFromLine,
98 | ArrowUpLeft,
99 | ArrowUpNarrowWide,
100 | ArrowUpRight,
101 | ArrowUpToLine,
102 | ArrowUpWideNarrow,
103 | ArrowUpZA,
104 | ArrowsUpFromLine,
105 | Asterisk,
106 | AtSign,
107 | Atom,
108 | AudioLines,
109 | AudioWaveform,
110 | Award,
111 | Axe,
112 | Axis3d,
113 | Baby,
114 | Backpack,
115 | Badge,
116 | BadgeAlert,
117 | BadgeCent,
118 | BadgeCheck,
119 | BadgeDollarSign,
120 | BadgeEuro,
121 | BadgeHelp,
122 | BadgeIndianRupee,
123 | BadgeInfo,
124 | BadgeJapaneseYen,
125 | BadgeMinus,
126 | BadgePercent,
127 | BadgePlus,
128 | BadgePoundSterling,
129 | BadgeRussianRuble,
130 | BadgeSwissFranc,
131 | BadgeX,
132 | BaggageClaim,
133 | Ban,
134 | Banana,
135 | Bandage,
136 | Banknote,
137 | BanknoteArrowDown,
138 | BanknoteArrowUp,
139 | BanknoteX,
140 | Barcode,
141 | Baseline,
142 | Bath,
143 | Battery,
144 | BatteryCharging,
145 | BatteryFull,
146 | BatteryLow,
147 | BatteryMedium,
148 | BatteryPlus,
149 | BatteryWarning,
150 | Beaker,
151 | Bean,
152 | BeanOff,
153 | Bed,
154 | BedDouble,
155 | BedSingle,
156 | Beef,
157 | Beer,
158 | BeerOff,
159 | Bell,
160 | BellDot,
161 | BellElectric,
162 | BellMinus,
163 | BellOff,
164 | BellPlus,
165 | BellRing,
166 | BetweenHorizontalEnd,
167 | BetweenHorizontalStart,
168 | BetweenVerticalEnd,
169 | BetweenVerticalStart,
170 | BicepsFlexed,
171 | Bike,
172 | Binary,
173 | Binoculars,
174 | Biohazard,
175 | Bird,
176 | Bitcoin,
177 | Blend,
178 | Blinds,
179 | Blocks,
180 | Bluetooth,
181 | BluetoothConnected,
182 | BluetoothOff,
183 | BluetoothSearching,
184 | Bold,
185 | Bolt,
186 | Bomb,
187 | Bone,
188 | Book,
189 | BookA,
190 | BookAudio,
191 | BookCheck,
192 | BookCopy,
193 | BookDashed,
194 | BookDown,
195 | BookHeadphones,
196 | BookHeart,
197 | BookImage,
198 | BookKey,
199 | BookLock,
200 | BookMarked,
201 | BookMinus,
202 | BookOpen,
203 | BookOpenCheck,
204 | BookOpenText,
205 | BookPlus,
206 | BookText,
207 | BookType,
208 | BookUp,
209 | BookUp2,
210 | BookUser,
211 | BookX,
212 | Bookmark,
213 | BookmarkCheck,
214 | BookmarkMinus,
215 | BookmarkPlus,
216 | BookmarkX,
217 | BoomBox,
218 | Bot,
219 | BotMessageSquare,
220 | BotOff,
221 | BowArrow,
222 | Box,
223 | Boxes,
224 | Braces,
225 | Brackets,
226 | Brain,
227 | BrainCircuit,
228 | BrainCog,
229 | BrickWall,
230 | BrickWallFire,
231 | Briefcase,
232 | BriefcaseBusiness,
233 | BriefcaseConveyorBelt,
234 | BriefcaseMedical,
235 | BringToFront,
236 | Brush,
237 | BrushCleaning,
238 | Bubbles,
239 | Bug,
240 | BugOff,
241 | BugPlay,
242 | Building,
243 | Building2,
244 | Bus,
245 | BusFront,
246 | Cable,
247 | CableCar,
248 | Cake,
249 | CakeSlice,
250 | Calculator,
251 | Calendar,
252 | Calendar1,
253 | CalendarArrowDown,
254 | CalendarArrowUp,
255 | CalendarCheck,
256 | CalendarCheck2,
257 | CalendarClock,
258 | CalendarCog,
259 | CalendarDays,
260 | CalendarFold,
261 | CalendarHeart,
262 | CalendarMinus,
263 | CalendarMinus2,
264 | CalendarOff,
265 | CalendarPlus,
266 | CalendarPlus2,
267 | CalendarRange,
268 | CalendarSearch,
269 | CalendarSync,
270 | CalendarX,
271 | CalendarX2,
272 | Camera,
273 | CameraOff,
274 | Candy,
275 | CandyCane,
276 | CandyOff,
277 | Cannabis,
278 | Captions,
279 | CaptionsOff,
280 | Car,
281 | CarFront,
282 | CarTaxiFront,
283 | Caravan,
284 | CardSim,
285 | Carrot,
286 | CaseLower,
287 | CaseSensitive,
288 | CaseUpper,
289 | CassetteTape,
290 | Cast,
291 | Castle,
292 | Cat,
293 | Cctv,
294 | ChartArea,
295 | ChartBar,
296 | ChartBarBig,
297 | ChartBarDecreasing,
298 | ChartBarIncreasing,
299 | ChartBarStacked,
300 | ChartCandlestick,
301 | ChartColumn,
302 | ChartColumnBig,
303 | ChartColumnDecreasing,
304 | ChartColumnIncreasing,
305 | ChartColumnStacked,
306 | ChartGantt,
307 | ChartLine,
308 | ChartNetwork,
309 | ChartNoAxesColumn,
310 | ChartNoAxesColumnDecreasing,
311 | ChartNoAxesColumnIncreasing,
312 | ChartNoAxesCombined,
313 | ChartNoAxesGantt,
314 | ChartPie,
315 | ChartScatter,
316 | ChartSpline,
317 | Check,
318 | CheckCheck,
319 | CheckLine,
320 | ChefHat,
321 | Cherry,
322 | ChevronDown,
323 | ChevronFirst,
324 | ChevronLast,
325 | ChevronLeft,
326 | ChevronRight,
327 | ChevronUp,
328 | ChevronsDown,
329 | ChevronsDownUp,
330 | ChevronsLeft,
331 | ChevronsLeftRight,
332 | ChevronsLeftRightEllipsis,
333 | ChevronsRight,
334 | ChevronsRightLeft,
335 | ChevronsUp,
336 | ChevronsUpDown,
337 | Chrome,
338 | Church,
339 | Cigarette,
340 | CigaretteOff,
341 | Circle,
342 | CircleAlert,
343 | CircleArrowDown,
344 | CircleArrowLeft,
345 | CircleArrowOutDownLeft,
346 | CircleArrowOutDownRight,
347 | CircleArrowOutUpLeft,
348 | CircleArrowOutUpRight,
349 | CircleArrowRight,
350 | CircleArrowUp,
351 | CircleCheck,
352 | CircleCheckBig,
353 | CircleChevronDown,
354 | CircleChevronLeft,
355 | CircleChevronRight,
356 | CircleChevronUp,
357 | CircleDashed,
358 | CircleDivide,
359 | CircleDollarSign,
360 | CircleDot,
361 | CircleDotDashed,
362 | CircleEllipsis,
363 | CircleEqual,
364 | CircleFadingArrowUp,
365 | CircleFadingPlus,
366 | CircleGauge,
367 | CircleHelp,
368 | CircleMinus,
369 | CircleOff,
370 | CircleParking,
371 | CircleParkingOff,
372 | CirclePause,
373 | CirclePercent,
374 | CirclePlay,
375 | CirclePlus,
376 | CirclePoundSterling,
377 | CirclePower,
378 | CircleSlash,
379 | CircleSlash2,
380 | CircleSmall,
381 | CircleStop,
382 | CircleUser,
383 | CircleUserRound,
384 | CircleX,
385 | CircuitBoard,
386 | Citrus,
387 | Clapperboard,
388 | Clipboard,
389 | ClipboardCheck,
390 | ClipboardCopy,
391 | ClipboardList,
392 | ClipboardMinus,
393 | ClipboardPaste,
394 | ClipboardPen,
395 | ClipboardPenLine,
396 | ClipboardPlus,
397 | ClipboardType,
398 | ClipboardX,
399 | Clock,
400 | Clock1,
401 | Clock10,
402 | Clock11,
403 | Clock12,
404 | Clock2,
405 | Clock3,
406 | Clock4,
407 | Clock5,
408 | Clock6,
409 | Clock7,
410 | Clock8,
411 | Clock9,
412 | ClockAlert,
413 | ClockArrowDown,
414 | ClockArrowUp,
415 | ClockFading,
416 | ClockPlus,
417 | Cloud,
418 | CloudAlert,
419 | CloudCheck,
420 | CloudCog,
421 | CloudDownload,
422 | CloudDrizzle,
423 | CloudFog,
424 | CloudHail,
425 | CloudLightning,
426 | CloudMoon,
427 | CloudMoonRain,
428 | CloudOff,
429 | CloudRain,
430 | CloudRainWind,
431 | CloudSnow,
432 | CloudSun,
433 | CloudSunRain,
434 | CloudUpload,
435 | Cloudy,
436 | Clover,
437 | Club,
438 | Code,
439 | CodeXml,
440 | Codepen,
441 | Codesandbox,
442 | Coffee,
443 | Cog,
444 | Coins,
445 | Columns2,
446 | Columns3,
447 | Columns3Cog,
448 | Columns4,
449 | Combine,
450 | Command,
451 | Compass,
452 | Component,
453 | Computer,
454 | ConciergeBell,
455 | Cone,
456 | Construction,
457 | Contact,
458 | ContactRound,
459 | Container,
460 | Contrast,
461 | Cookie,
462 | CookingPot,
463 | Copy,
464 | CopyCheck,
465 | CopyMinus,
466 | CopyPlus,
467 | CopySlash,
468 | CopyX,
469 | Copyleft,
470 | Copyright,
471 | CornerDownLeft,
472 | CornerDownRight,
473 | CornerLeftDown,
474 | CornerLeftUp,
475 | CornerRightDown,
476 | CornerRightUp,
477 | CornerUpLeft,
478 | CornerUpRight,
479 | Cpu,
480 | CreativeCommons,
481 | CreditCard,
482 | Croissant,
483 | Crop,
484 | Cross,
485 | Crosshair,
486 | Crown,
487 | Cuboid,
488 | CupSoda,
489 | Currency,
490 | Cylinder,
491 | Dam,
492 | Database,
493 | DatabaseBackup,
494 | DatabaseZap,
495 | DecimalsArrowLeft,
496 | DecimalsArrowRight,
497 | Delete,
498 | Dessert,
499 | Diameter,
500 | Diamond,
501 | DiamondMinus,
502 | DiamondPercent,
503 | DiamondPlus,
504 | Dice1,
505 | Dice2,
506 | Dice3,
507 | Dice4,
508 | Dice5,
509 | Dice6,
510 | Dices,
511 | Diff,
512 | Disc,
513 | Disc2,
514 | Disc3,
515 | DiscAlbum,
516 | Divide,
517 | Dna,
518 | DnaOff,
519 | Dock,
520 | Dog,
521 | DollarSign,
522 | Donut,
523 | DoorClosed,
524 | DoorClosedLocked,
525 | DoorOpen,
526 | Dot,
527 | Download,
528 | DraftingCompass,
529 | Drama,
530 | Dribbble,
531 | Drill,
532 | Droplet,
533 | DropletOff,
534 | Droplets,
535 | Drum,
536 | Drumstick,
537 | Dumbbell,
538 | Ear,
539 | EarOff,
540 | Earth,
541 | EarthLock,
542 | Eclipse,
543 | Egg,
544 | EggFried,
545 | EggOff,
546 | Ellipsis,
547 | EllipsisVertical,
548 | Equal,
549 | EqualApproximately,
550 | EqualNot,
551 | Eraser,
552 | EthernetPort,
553 | Euro,
554 | Expand,
555 | ExternalLink,
556 | Eye,
557 | EyeClosed,
558 | EyeOff,
559 | Facebook,
560 | Factory,
561 | Fan,
562 | FastForward,
563 | Feather,
564 | Fence,
565 | FerrisWheel,
566 | Figma,
567 | File,
568 | FileArchive,
569 | FileAudio,
570 | FileAudio2,
571 | FileAxis3d,
572 | FileBadge,
573 | FileBadge2,
574 | FileBox,
575 | FileChartColumn,
576 | FileChartColumnIncreasing,
577 | FileChartLine,
578 | FileChartPie,
579 | FileCheck,
580 | FileCheck2,
581 | FileClock,
582 | FileCode,
583 | FileCode2,
584 | FileCog,
585 | FileDiff,
586 | FileDigit,
587 | FileDown,
588 | FileHeart,
589 | FileImage,
590 | FileInput,
591 | FileJson,
592 | FileJson2,
593 | FileKey,
594 | FileKey2,
595 | FileLock,
596 | FileLock2,
597 | FileMinus,
598 | FileMinus2,
599 | FileMusic,
600 | FileOutput,
601 | FilePen,
602 | FilePenLine,
603 | FilePlus,
604 | FilePlus2,
605 | FileQuestion,
606 | FileScan,
607 | FileSearch,
608 | FileSearch2,
609 | FileSliders,
610 | FileSpreadsheet,
611 | FileStack,
612 | FileSymlink,
613 | FileTerminal,
614 | FileText,
615 | FileType,
616 | FileType2,
617 | FileUp,
618 | FileUser,
619 | FileVideo,
620 | FileVideo2,
621 | FileVolume,
622 | FileVolume2,
623 | FileWarning,
624 | FileX,
625 | FileX2,
626 | Files,
627 | Film,
628 | Fingerprint,
629 | FireExtinguisher,
630 | Fish,
631 | FishOff,
632 | FishSymbol,
633 | Flag,
634 | FlagOff,
635 | FlagTriangleLeft,
636 | FlagTriangleRight,
637 | Flame,
638 | FlameKindling,
639 | Flashlight,
640 | FlashlightOff,
641 | FlaskConical,
642 | FlaskConicalOff,
643 | FlaskRound,
644 | FlipHorizontal,
645 | FlipHorizontal2,
646 | FlipVertical,
647 | FlipVertical2,
648 | Flower,
649 | Flower2,
650 | Focus,
651 | FoldHorizontal,
652 | FoldVertical,
653 | Folder,
654 | FolderArchive,
655 | FolderCheck,
656 | FolderClock,
657 | FolderClosed,
658 | FolderCode,
659 | FolderCog,
660 | FolderDot,
661 | FolderDown,
662 | FolderGit,
663 | FolderGit2,
664 | FolderHeart,
665 | FolderInput,
666 | FolderKanban,
667 | FolderKey,
668 | FolderLock,
669 | FolderMinus,
670 | FolderOpen,
671 | FolderOpenDot,
672 | FolderOutput,
673 | FolderPen,
674 | FolderPlus,
675 | FolderRoot,
676 | FolderSearch,
677 | FolderSearch2,
678 | FolderSymlink,
679 | FolderSync,
680 | FolderTree,
681 | FolderUp,
682 | FolderX,
683 | Folders,
684 | Footprints,
685 | Forklift,
686 | Forward,
687 | Frame,
688 | Framer,
689 | Frown,
690 | Fuel,
691 | Fullscreen,
692 | Funnel,
693 | FunnelPlus,
694 | FunnelX,
695 | GalleryHorizontal,
696 | GalleryHorizontalEnd,
697 | GalleryThumbnails,
698 | GalleryVertical,
699 | GalleryVerticalEnd,
700 | Gamepad,
701 | Gamepad2,
702 | Gauge,
703 | Gavel,
704 | Gem,
705 | Ghost,
706 | Gift,
707 | GitBranch,
708 | GitBranchPlus,
709 | GitCommitHorizontal,
710 | GitCommitVertical,
711 | GitCompare,
712 | GitCompareArrows,
713 | GitFork,
714 | GitGraph,
715 | GitMerge,
716 | GitPullRequest,
717 | GitPullRequestArrow,
718 | GitPullRequestClosed,
719 | GitPullRequestCreate,
720 | GitPullRequestCreateArrow,
721 | GitPullRequestDraft,
722 | Github,
723 | Gitlab,
724 | GlassWater,
725 | Glasses,
726 | Globe,
727 | GlobeLock,
728 | Goal,
729 | Gpu,
730 | Grab,
731 | GraduationCap,
732 | Grape,
733 | Grid2x2,
734 | Grid2x2Check,
735 | Grid2x2Plus,
736 | Grid2x2X,
737 | Grid3x2,
738 | Grid3x3,
739 | Grip,
740 | GripHorizontal,
741 | GripVertical,
742 | Group,
743 | Guitar,
744 | Ham,
745 | Hamburger,
746 | Hammer,
747 | Hand,
748 | HandCoins,
749 | HandHeart,
750 | HandHelping,
751 | HandMetal,
752 | HandPlatter,
753 | Handshake,
754 | HardDrive,
755 | HardDriveDownload,
756 | HardDriveUpload,
757 | HardHat,
758 | Hash,
759 | Haze,
760 | HdmiPort,
761 | Heading,
762 | Heading1,
763 | Heading2,
764 | Heading3,
765 | Heading4,
766 | Heading5,
767 | Heading6,
768 | HeadphoneOff,
769 | Headphones,
770 | Headset,
771 | Heart,
772 | HeartCrack,
773 | HeartHandshake,
774 | HeartMinus,
775 | HeartOff,
776 | HeartPlus,
777 | HeartPulse,
778 | Heater,
779 | Hexagon,
780 | Highlighter,
781 | History,
782 | Hop,
783 | HopOff,
784 | Hospital,
785 | Hotel,
786 | Hourglass,
787 | House,
788 | HousePlug,
789 | HousePlus,
790 | HouseWifi,
791 | IceCreamBowl,
792 | IceCreamCone,
793 | IdCard,
794 | IdCardLanyard,
795 | Image,
796 | ImageDown,
797 | ImageMinus,
798 | ImageOff,
799 | ImagePlay,
800 | ImagePlus,
801 | ImageUp,
802 | ImageUpscale,
803 | Images,
804 | Import,
805 | Inbox,
806 | IndentDecrease,
807 | IndentIncrease,
808 | IndianRupee,
809 | Infinity,
810 | Info,
811 | InspectionPanel,
812 | Instagram,
813 | Italic,
814 | IterationCcw,
815 | IterationCw,
816 | JapaneseYen,
817 | Joystick,
818 | Kanban,
819 | Key,
820 | KeyRound,
821 | KeySquare,
822 | Keyboard,
823 | KeyboardMusic,
824 | KeyboardOff,
825 | Lamp,
826 | LampCeiling,
827 | LampDesk,
828 | LampFloor,
829 | LampWallDown,
830 | LampWallUp,
831 | LandPlot,
832 | Landmark,
833 | Languages,
834 | Laptop,
835 | LaptopMinimal,
836 | LaptopMinimalCheck,
837 | Lasso,
838 | LassoSelect,
839 | Laugh,
840 | Layers,
841 | Layers2,
842 | LayoutDashboard,
843 | LayoutGrid,
844 | LayoutList,
845 | LayoutPanelLeft,
846 | LayoutPanelTop,
847 | LayoutTemplate,
848 | Leaf,
849 | LeafyGreen,
850 | Lectern,
851 | LetterText,
852 | Library,
853 | LibraryBig,
854 | LifeBuoy,
855 | Ligature,
856 | Lightbulb,
857 | LightbulbOff,
858 | Link,
859 | Link2,
860 | Link2Off,
861 | Linkedin,
862 | List,
863 | ListCheck,
864 | ListChecks,
865 | ListCollapse,
866 | ListEnd,
867 | ListFilter,
868 | ListFilterPlus,
869 | ListMinus,
870 | ListMusic,
871 | ListOrdered,
872 | ListPlus,
873 | ListRestart,
874 | ListStart,
875 | ListTodo,
876 | ListTree,
877 | ListVideo,
878 | ListX,
879 | Loader,
880 | LoaderCircle,
881 | LoaderPinwheel,
882 | Locate,
883 | LocateFixed,
884 | LocateOff,
885 | LocationEdit,
886 | Lock,
887 | LockKeyhole,
888 | LockKeyholeOpen,
889 | LockOpen,
890 | LogIn,
891 | LogOut,
892 | Logs,
893 | Lollipop,
894 | Luggage,
895 | Magnet,
896 | Mail,
897 | MailCheck,
898 | MailMinus,
899 | MailOpen,
900 | MailPlus,
901 | MailQuestion,
902 | MailSearch,
903 | MailWarning,
904 | MailX,
905 | Mailbox,
906 | Mails,
907 | Map,
908 | MapPin,
909 | MapPinCheck,
910 | MapPinCheckInside,
911 | MapPinHouse,
912 | MapPinMinus,
913 | MapPinMinusInside,
914 | MapPinOff,
915 | MapPinPlus,
916 | MapPinPlusInside,
917 | MapPinX,
918 | MapPinXInside,
919 | MapPinned,
920 | MapPlus,
921 | Mars,
922 | MarsStroke,
923 | Martini,
924 | Maximize,
925 | Maximize2,
926 | Medal,
927 | Megaphone,
928 | MegaphoneOff,
929 | Meh,
930 | MemoryStick,
931 | Menu,
932 | Merge,
933 | MessageCircle,
934 | MessageCircleCode,
935 | MessageCircleDashed,
936 | MessageCircleHeart,
937 | MessageCircleMore,
938 | MessageCircleOff,
939 | MessageCirclePlus,
940 | MessageCircleQuestion,
941 | MessageCircleReply,
942 | MessageCircleWarning,
943 | MessageCircleX,
944 | MessageSquare,
945 | MessageSquareCode,
946 | MessageSquareDashed,
947 | MessageSquareDiff,
948 | MessageSquareDot,
949 | MessageSquareHeart,
950 | MessageSquareLock,
951 | MessageSquareMore,
952 | MessageSquareOff,
953 | MessageSquarePlus,
954 | MessageSquareQuote,
955 | MessageSquareReply,
956 | MessageSquareShare,
957 | MessageSquareText,
958 | MessageSquareWarning,
959 | MessageSquareX,
960 | MessagesSquare,
961 | Mic,
962 | MicOff,
963 | MicVocal,
964 | Microchip,
965 | Microscope,
966 | Microwave,
967 | Milestone,
968 | Milk,
969 | MilkOff,
970 | Minimize,
971 | Minimize2,
972 | Minus,
973 | Monitor,
974 | MonitorCheck,
975 | MonitorCog,
976 | MonitorDot,
977 | MonitorDown,
978 | MonitorOff,
979 | MonitorPause,
980 | MonitorPlay,
981 | MonitorSmartphone,
982 | MonitorSpeaker,
983 | MonitorStop,
984 | MonitorUp,
985 | MonitorX,
986 | Moon,
987 | MoonStar,
988 | Mountain,
989 | MountainSnow,
990 | Mouse,
991 | MouseOff,
992 | MousePointer,
993 | MousePointer2,
994 | MousePointerBan,
995 | MousePointerClick,
996 | Move,
997 | Move3d,
998 | MoveDiagonal,
999 | MoveDiagonal2,
1000 | MoveDown,
1001 | MoveDownLeft,
1002 | MoveDownRight,
1003 | MoveHorizontal,
1004 | MoveLeft,
1005 | MoveRight,
1006 | MoveUp,
1007 | MoveUpLeft,
1008 | MoveUpRight,
1009 | MoveVertical,
1010 | Music,
1011 | Music2,
1012 | Music3,
1013 | Music4,
1014 | Navigation,
1015 | Navigation2,
1016 | Navigation2Off,
1017 | NavigationOff,
1018 | Network,
1019 | Newspaper,
1020 | Nfc,
1021 | NonBinary,
1022 | Notebook,
1023 | NotebookPen,
1024 | NotebookTabs,
1025 | NotebookText,
1026 | NotepadText,
1027 | NotepadTextDashed,
1028 | Nut,
1029 | NutOff,
1030 | Octagon,
1031 | OctagonAlert,
1032 | OctagonMinus,
1033 | OctagonPause,
1034 | OctagonX,
1035 | Omega,
1036 | Option,
1037 | Orbit,
1038 | Origami,
1039 | Package,
1040 | Package2,
1041 | PackageCheck,
1042 | PackageMinus,
1043 | PackageOpen,
1044 | PackagePlus,
1045 | PackageSearch,
1046 | PackageX,
1047 | PaintBucket,
1048 | PaintRoller,
1049 | Paintbrush,
1050 | PaintbrushVertical,
1051 | Palette,
1052 | Panda,
1053 | PanelBottom,
1054 | PanelBottomClose,
1055 | PanelBottomDashed,
1056 | PanelBottomOpen,
1057 | PanelLeft,
1058 | PanelLeftClose,
1059 | PanelLeftDashed,
1060 | PanelLeftOpen,
1061 | PanelRight,
1062 | PanelRightClose,
1063 | PanelRightDashed,
1064 | PanelRightOpen,
1065 | PanelTop,
1066 | PanelTopClose,
1067 | PanelTopDashed,
1068 | PanelTopOpen,
1069 | PanelsLeftBottom,
1070 | PanelsRightBottom,
1071 | PanelsTopLeft,
1072 | Paperclip,
1073 | Parentheses,
1074 | ParkingMeter,
1075 | PartyPopper,
1076 | Pause,
1077 | PawPrint,
1078 | PcCase,
1079 | Pen,
1080 | PenLine,
1081 | PenOff,
1082 | PenTool,
1083 | Pencil,
1084 | PencilLine,
1085 | PencilOff,
1086 | PencilRuler,
1087 | Pentagon,
1088 | Percent,
1089 | PersonStanding,
1090 | PhilippinePeso,
1091 | Phone,
1092 | PhoneCall,
1093 | PhoneForwarded,
1094 | PhoneIncoming,
1095 | PhoneMissed,
1096 | PhoneOff,
1097 | PhoneOutgoing,
1098 | Pi,
1099 | Piano,
1100 | Pickaxe,
1101 | PictureInPicture,
1102 | PictureInPicture2,
1103 | PiggyBank,
1104 | Pilcrow,
1105 | PilcrowLeft,
1106 | PilcrowRight,
1107 | Pill,
1108 | PillBottle,
1109 | Pin,
1110 | PinOff,
1111 | Pipette,
1112 | Pizza,
1113 | Plane,
1114 | PlaneLanding,
1115 | PlaneTakeoff,
1116 | Play,
1117 | Plug,
1118 | Plug2,
1119 | PlugZap,
1120 | Plus,
1121 | Pocket,
1122 | PocketKnife,
1123 | Podcast,
1124 | Pointer,
1125 | PointerOff,
1126 | Popcorn,
1127 | Popsicle,
1128 | PoundSterling,
1129 | Power,
1130 | PowerOff,
1131 | Presentation,
1132 | Printer,
1133 | PrinterCheck,
1134 | Projector,
1135 | Proportions,
1136 | Puzzle,
1137 | Pyramid,
1138 | QrCode,
1139 | Quote,
1140 | Rabbit,
1141 | Radar,
1142 | Radiation,
1143 | Radical,
1144 | Radio,
1145 | RadioReceiver,
1146 | RadioTower,
1147 | Radius,
1148 | RailSymbol,
1149 | Rainbow,
1150 | Rat,
1151 | Ratio,
1152 | Receipt,
1153 | ReceiptCent,
1154 | ReceiptEuro,
1155 | ReceiptIndianRupee,
1156 | ReceiptJapaneseYen,
1157 | ReceiptPoundSterling,
1158 | ReceiptRussianRuble,
1159 | ReceiptSwissFranc,
1160 | ReceiptText,
1161 | RectangleEllipsis,
1162 | RectangleGoggles,
1163 | RectangleHorizontal,
1164 | RectangleVertical,
1165 | Recycle,
1166 | Redo,
1167 | Redo2,
1168 | RedoDot,
1169 | RefreshCcw,
1170 | RefreshCcwDot,
1171 | RefreshCw,
1172 | RefreshCwOff,
1173 | Refrigerator,
1174 | Regex,
1175 | RemoveFormatting,
1176 | Repeat,
1177 | Repeat1,
1178 | Repeat2,
1179 | Replace,
1180 | ReplaceAll,
1181 | Reply,
1182 | ReplyAll,
1183 | Rewind,
1184 | Ribbon,
1185 | Rocket,
1186 | RockingChair,
1187 | RollerCoaster,
1188 | Rotate3d,
1189 | RotateCcw,
1190 | RotateCcwKey,
1191 | RotateCcwSquare,
1192 | RotateCw,
1193 | RotateCwSquare,
1194 | Route,
1195 | RouteOff,
1196 | Router,
1197 | Rows2,
1198 | Rows3,
1199 | Rows4,
1200 | Rss,
1201 | Ruler,
1202 | RulerDimensionLine,
1203 | RussianRuble,
1204 | Sailboat,
1205 | Salad,
1206 | Sandwich,
1207 | Satellite,
1208 | SatelliteDish,
1209 | SaudiRiyal,
1210 | Save,
1211 | SaveAll,
1212 | SaveOff,
1213 | Scale,
1214 | Scale3d,
1215 | Scaling,
1216 | Scan,
1217 | ScanBarcode,
1218 | ScanEye,
1219 | ScanFace,
1220 | ScanHeart,
1221 | ScanLine,
1222 | ScanQrCode,
1223 | ScanSearch,
1224 | ScanText,
1225 | School,
1226 | Scissors,
1227 | ScissorsLineDashed,
1228 | ScreenShare,
1229 | ScreenShareOff,
1230 | Scroll,
1231 | ScrollText,
1232 | Search,
1233 | SearchCheck,
1234 | SearchCode,
1235 | SearchSlash,
1236 | SearchX,
1237 | Section,
1238 | Send,
1239 | SendHorizontal,
1240 | SendToBack,
1241 | SeparatorHorizontal,
1242 | SeparatorVertical,
1243 | Server,
1244 | ServerCog,
1245 | ServerCrash,
1246 | ServerOff,
1247 | Settings,
1248 | Settings2,
1249 | Shapes,
1250 | Share,
1251 | Share2,
1252 | Sheet,
1253 | Shell,
1254 | Shield,
1255 | ShieldAlert,
1256 | ShieldBan,
1257 | ShieldCheck,
1258 | ShieldEllipsis,
1259 | ShieldHalf,
1260 | ShieldMinus,
1261 | ShieldOff,
1262 | ShieldPlus,
1263 | ShieldQuestion,
1264 | ShieldUser,
1265 | ShieldX,
1266 | Ship,
1267 | ShipWheel,
1268 | Shirt,
1269 | ShoppingBag,
1270 | ShoppingBasket,
1271 | ShoppingCart,
1272 | Shovel,
1273 | ShowerHead,
1274 | Shredder,
1275 | Shrimp,
1276 | Shrink,
1277 | Shrub,
1278 | Shuffle,
1279 | Sigma,
1280 | Signal,
1281 | SignalHigh,
1282 | SignalLow,
1283 | SignalMedium,
1284 | SignalZero,
1285 | Signature,
1286 | Signpost,
1287 | SignpostBig,
1288 | Siren,
1289 | SkipBack,
1290 | SkipForward,
1291 | Skull,
1292 | Slack,
1293 | Slash,
1294 | Slice,
1295 | SlidersHorizontal,
1296 | SlidersVertical,
1297 | Smartphone,
1298 | SmartphoneCharging,
1299 | SmartphoneNfc,
1300 | Smile,
1301 | SmilePlus,
1302 | Snail,
1303 | Snowflake,
1304 | SoapDispenserDroplet,
1305 | Sofa,
1306 | Soup,
1307 | Space,
1308 | Spade,
1309 | Sparkle,
1310 | Sparkles,
1311 | Speaker,
1312 | Speech,
1313 | SpellCheck,
1314 | SpellCheck2,
1315 | Spline,
1316 | SplinePointer,
1317 | Split,
1318 | SprayCan,
1319 | Sprout,
1320 | Square,
1321 | SquareActivity,
1322 | SquareArrowDown,
1323 | SquareArrowDownLeft,
1324 | SquareArrowDownRight,
1325 | SquareArrowLeft,
1326 | SquareArrowOutDownLeft,
1327 | SquareArrowOutDownRight,
1328 | SquareArrowOutUpLeft,
1329 | SquareArrowOutUpRight,
1330 | SquareArrowRight,
1331 | SquareArrowUp,
1332 | SquareArrowUpLeft,
1333 | SquareArrowUpRight,
1334 | SquareAsterisk,
1335 | SquareBottomDashedScissors,
1336 | SquareChartGantt,
1337 | SquareCheck,
1338 | SquareCheckBig,
1339 | SquareChevronDown,
1340 | SquareChevronLeft,
1341 | SquareChevronRight,
1342 | SquareChevronUp,
1343 | SquareCode,
1344 | SquareDashed,
1345 | SquareDashedBottom,
1346 | SquareDashedBottomCode,
1347 | SquareDashedKanban,
1348 | SquareDashedMousePointer,
1349 | SquareDashedTopSolid,
1350 | SquareDivide,
1351 | SquareDot,
1352 | SquareEqual,
1353 | SquareFunction,
1354 | SquareKanban,
1355 | SquareLibrary,
1356 | SquareM,
1357 | SquareMenu,
1358 | SquareMinus,
1359 | SquareMousePointer,
1360 | SquareParking,
1361 | SquareParkingOff,
1362 | SquarePen,
1363 | SquarePercent,
1364 | SquarePi,
1365 | SquarePilcrow,
1366 | SquarePlay,
1367 | SquarePlus,
1368 | SquarePower,
1369 | SquareRadical,
1370 | SquareRoundCorner,
1371 | SquareScissors,
1372 | SquareSigma,
1373 | SquareSlash,
1374 | SquareSplitHorizontal,
1375 | SquareSplitVertical,
1376 | SquareSquare,
1377 | SquareStack,
1378 | SquareTerminal,
1379 | SquareUser,
1380 | SquareUserRound,
1381 | SquareX,
1382 | SquaresExclude,
1383 | SquaresIntersect,
1384 | SquaresSubtract,
1385 | SquaresUnite,
1386 | Squircle,
1387 | Squirrel,
1388 | Stamp,
1389 | Star,
1390 | StarHalf,
1391 | StarOff,
1392 | StepBack,
1393 | StepForward,
1394 | Stethoscope,
1395 | Sticker,
1396 | StickyNote,
1397 | Store,
1398 | StretchHorizontal,
1399 | StretchVertical,
1400 | Strikethrough,
1401 | Subscript,
1402 | Sun,
1403 | SunDim,
1404 | SunMedium,
1405 | SunMoon,
1406 | SunSnow,
1407 | Sunrise,
1408 | Sunset,
1409 | Superscript,
1410 | SwatchBook,
1411 | SwissFranc,
1412 | SwitchCamera,
1413 | Sword,
1414 | Swords,
1415 | Syringe,
1416 | Table,
1417 | Table2,
1418 | TableCellsMerge,
1419 | TableCellsSplit,
1420 | TableColumnsSplit,
1421 | TableOfContents,
1422 | TableProperties,
1423 | TableRowsSplit,
1424 | Tablet,
1425 | TabletSmartphone,
1426 | Tablets,
1427 | Tag,
1428 | Tags,
1429 | Tally1,
1430 | Tally2,
1431 | Tally3,
1432 | Tally4,
1433 | Tally5,
1434 | Tangent,
1435 | Target,
1436 | Telescope,
1437 | Tent,
1438 | TentTree,
1439 | Terminal,
1440 | TestTube,
1441 | TestTubeDiagonal,
1442 | TestTubes,
1443 | Text,
1444 | TextCursor,
1445 | TextCursorInput,
1446 | TextQuote,
1447 | TextSearch,
1448 | TextSelect,
1449 | Theater,
1450 | Thermometer,
1451 | ThermometerSnowflake,
1452 | ThermometerSun,
1453 | ThumbsDown,
1454 | ThumbsUp,
1455 | Ticket,
1456 | TicketCheck,
1457 | TicketMinus,
1458 | TicketPercent,
1459 | TicketPlus,
1460 | TicketSlash,
1461 | TicketX,
1462 | Tickets,
1463 | TicketsPlane,
1464 | Timer,
1465 | TimerOff,
1466 | TimerReset,
1467 | ToggleLeft,
1468 | ToggleRight,
1469 | Toilet,
1470 | Tornado,
1471 | Torus,
1472 | Touchpad,
1473 | TouchpadOff,
1474 | TowerControl,
1475 | ToyBrick,
1476 | Tractor,
1477 | TrafficCone,
1478 | TrainFront,
1479 | TrainFrontTunnel,
1480 | TrainTrack,
1481 | TramFront,
1482 | Transgender,
1483 | Trash,
1484 | Trash2,
1485 | TreeDeciduous,
1486 | TreePalm,
1487 | TreePine,
1488 | Trees,
1489 | Trello,
1490 | TrendingDown,
1491 | TrendingUp,
1492 | TrendingUpDown,
1493 | Triangle,
1494 | TriangleAlert,
1495 | TriangleDashed,
1496 | TriangleRight,
1497 | Trophy,
1498 | Truck,
1499 | TruckElectric,
1500 | Turtle,
1501 | Tv,
1502 | TvMinimal,
1503 | TvMinimalPlay,
1504 | Twitch,
1505 | Twitter,
1506 | Type,
1507 | TypeOutline,
1508 | Umbrella,
1509 | UmbrellaOff,
1510 | Underline,
1511 | Undo,
1512 | Undo2,
1513 | UndoDot,
1514 | UnfoldHorizontal,
1515 | UnfoldVertical,
1516 | Ungroup,
1517 | University,
1518 | Unlink,
1519 | Unlink2,
1520 | Unplug,
1521 | Upload,
1522 | Usb,
1523 | User,
1524 | UserCheck,
1525 | UserCog,
1526 | UserLock,
1527 | UserMinus,
1528 | UserPen,
1529 | UserPlus,
1530 | UserRound,
1531 | UserRoundCheck,
1532 | UserRoundCog,
1533 | UserRoundMinus,
1534 | UserRoundPen,
1535 | UserRoundPlus,
1536 | UserRoundSearch,
1537 | UserRoundX,
1538 | UserSearch,
1539 | UserX,
1540 | Users,
1541 | UsersRound,
1542 | Utensils,
1543 | UtensilsCrossed,
1544 | UtilityPole,
1545 | Variable,
1546 | Vault,
1547 | Vegan,
1548 | VenetianMask,
1549 | Venus,
1550 | VenusAndMars,
1551 | Vibrate,
1552 | VibrateOff,
1553 | Video,
1554 | VideoOff,
1555 | Videotape,
1556 | View,
1557 | Voicemail,
1558 | Volleyball,
1559 | Volume,
1560 | Volume1,
1561 | Volume2,
1562 | VolumeOff,
1563 | VolumeX,
1564 | Vote,
1565 | Wallet,
1566 | WalletCards,
1567 | WalletMinimal,
1568 | Wallpaper,
1569 | Wand,
1570 | WandSparkles,
1571 | Warehouse,
1572 | WashingMachine,
1573 | Watch,
1574 | Waves,
1575 | WavesLadder,
1576 | Waypoints,
1577 | Webcam,
1578 | Webhook,
1579 | WebhookOff,
1580 | Weight,
1581 | Wheat,
1582 | WheatOff,
1583 | WholeWord,
1584 | Wifi,
1585 | WifiHigh,
1586 | WifiLow,
1587 | WifiOff,
1588 | WifiPen,
1589 | WifiZero,
1590 | Wind,
1591 | WindArrowDown,
1592 | Wine,
1593 | WineOff,
1594 | Workflow,
1595 | Worm,
1596 | WrapText,
1597 | Wrench,
1598 | X,
1599 | Youtube,
1600 | Zap,
1601 | ZapOff,
1602 | ZoomIn,
1603 | ZoomOut,
1604 | }
1605 |
--------------------------------------------------------------------------------