Skip to content

Commit

Permalink
Refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
regginator committed Nov 5, 2023
1 parent 0b34af7 commit 3ae82dc
Show file tree
Hide file tree
Showing 3 changed files with 208 additions and 22 deletions.
157 changes: 135 additions & 22 deletions lib/init.luau
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
-- MIT License | Copyright (c) 2023 Latte Softworks <https://latte.to>

export type Asset = {
IconName: string, -- "server-crash"
Id: number, -- 123456789
Url: string, -- "rbxassetid://123456789"
ImageRectSize: Vector2, -- Vector2.new(48, 48)
Expand All @@ -9,8 +10,6 @@ export type Asset = {

local Icons = require(script.Icons)

local ContentProvider = game:GetService("ContentProvider")

local Type = typeof or type
local function CheckArgTypes(funcName: string, inputArgs: {any}, typeEntries: {[number]: {string}})
for ArgIndex, TypeEntryArray in typeEntries do
Expand All @@ -30,6 +29,22 @@ local function TrimIconIdentifier(inputIconIdentifier: string): string
return string.match(string.lower(inputIconIdentifier), "^%s*(.*)%s*$") :: string
end

local function ApplyToInstance(object: Instance, properties: {[string]: any}): Instance
if properties then
for Property, Value in properties do
if Property ~= "Parent" then
object[Property] = Value
end
end

if properties.Parent then
object.Parent = properties.Parent
end
end

return object
end

local Lucide = {
PackageVersion = "0.1.0", -- The version of this `lucide-roblox` package
LucideVersion = "0.292.0", -- The version of the Lucide icon set itself the package ver noted above is on
Expand All @@ -38,50 +53,51 @@ local Lucide = {
-- Add all icon names to an array
do
local IconNames: {string} = {}
local FirstIconIndex = next(Icons) or {} -- If it's actually `{}`, we're in trouble..
local _, FirstIconIndex = next(Icons) -- If it's actually `{}`, we're in trouble..
FirstIconIndex = FirstIconIndex or {}

for IconName in FirstIconIndex do
table.insert(IconNames, IconName)
end

table.sort(IconNames)
Lucide.IconNames = IconNames
end

--[[
This function attempts to retrieve and wrap an asset object from a specified
icon name, optional target size most applicable/closest to what's supported, and
optionally preload the said asset's `rbxassetid` URI, which will yield a return
until Roblox has preloaded the actual asset
Attempts to retrieve and wrap an asset object from a specified icon name, with
an optional target icon size argument, fetching the closest to what's supported
*Will* throw an error if the icon name provided is invalid/not found
Example:
*Example:*
```lua
local Asset = Lucide.GetAsset("server", 48)
assert(Asset, 'Failed to fetch asset!')
local Asset = Lucide.GetAsset("server", 48) -- iconSize will default to `256` if not provided
assert(Asset, "Failed to fetch asset!")
print(Asset.IconName) -- "server"
print(Asset.Id) -- 15269177520
print(Asset.Url) -- "rbxassetid://15269177520"
print(Asset.ImageRectSize) -- Vector2.new(48, 48)
print(Asset.ImageRectOffset) -- Vector2.new(0, 771)
```
]]
function Lucide.GetAsset(iconName: string, inputSize: number?, preload: boolean?): Asset?
local InputSize = if inputSize == nil then 256 else inputSize
local Preload = if preload == nil then false else preload
function Lucide.GetAsset(iconName: string, iconSize: number?): Asset
local IconSize = if iconSize == nil then 256 else iconSize

CheckArgTypes("Lucide.GetAsset", {iconName, InputSize, Preload}, {
CheckArgTypes("Lucide.GetAsset", {iconName, IconSize}, {
[1] = {"iconName", "string"},
[2] = {"inputSize", "number"},
[3] = {"preload", "boolean"},
[2] = {"iconSize", "number"},
})

local IconName = TrimIconIdentifier(iconName)

-- If reading directly from a UI obj w/ a negative size..?
if InputSize < 0 then
InputSize = -InputSize
if IconSize < 0 then
IconSize = -IconSize
end

local RealSizeIndex = if InputSize <= 48 then "48px" else "256px"
local RealSizeIndex = if IconSize <= 48 then "48px" else "256px"
local IconIndexDict = Icons[RealSizeIndex]

if not IconIndexDict then
Expand All @@ -90,22 +106,23 @@ function Lucide.GetAsset(iconName: string, inputSize: number?, preload: boolean?

local RawAsset = IconIndexDict[IconName]
if not RawAsset then
return
error("Lucide.GetAsset: Failed to find icon by the name of \"" .. IconName .. "\" (@" .. RealSizeIndex .. "), perhaps a spelling mistake?", 2)
end

local Id = RawAsset[1]
local RawImageRectSize = RawAsset[2]
local RawImageRectOffset = RawAsset[3]

if type(Id) ~= "number" or type(RawImageRectSize) ~= "table" or type(RawImageRectOffset) ~= "table" then
return
error("Lucide.GetAsset: Internal error: Invalid auto-generated asset entry")
end

local Url = "rbxassetid://" .. Id
local ImageRectSize = Vector2.new(RawImageRectSize[1], RawImageRectSize[2])
local ImageRectOffset = Vector2.new(RawImageRectOffset[1], RawImageRectOffset[2])

local Asset = {
local Asset: Asset = {
IconName = IconName,
Id = Id,
Url = Url,
ImageRectSize = ImageRectSize,
Expand All @@ -115,4 +132,100 @@ function Lucide.GetAsset(iconName: string, inputSize: number?, preload: boolean?
return Asset
end

--[[
Wrapper around `Lucide.GetAsset()` that fetches asset info for the specified
icon name and size, anc creates an `ImageLabel` Instance. Accepts an additional
optional argument for providing a table of properties to automatically apply
after the asset has been applied to said `ImageLabel`
Without providing any extra property overrides, the icon is colored to its
default of #FFFFFF, and theinput from the `imageSize` argument is the
offset value of `ImageLabel.Size`
Throws an error under the same terms as `Lucide.GetAsset()`
*Example:*
```lua
local PlayerGui = game:GetService("Players").LocalPlayer.PlayerGui
local ScreenGui = Instance.new("ScreenGui")
Lucide.ImageLabel("server-crash", 256, {
AnchorPoint = Vector2.new(0.5, 0.5),
Position = UDim2.fromScale(0.5, 0.5),
Parent = ScreenGui,
})
ScreenGui.Parent = PlayerGui
```
]]
function Lucide.ImageLabel(iconName: string, imageSize: number?, propertyOverrides: {[string]: any}?): ImageLabel
local ImageSize = if imageSize == nil then 256 else imageSize
local PropertyOverrides = if propertyOverrides == nil then {} else propertyOverrides

CheckArgTypes("Lucide.ImageLabel", {iconName, imageSize, propertyOverrides}, {
[1] = {"iconName", "string"},
[2] = {"imageSize", "number"},
[3] = {"propertyOverrides", "table"}
})

local Asset = Lucide.GetAsset(iconName, ImageSize)

local ImageLabel = ApplyToInstance(Instance.new("ImageLabel"), {
Name = Asset.IconName,

Size = UDim2.fromOffset(ImageSize, ImageSize),

BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 1,
BorderSizePixel = 0,

Image = Asset.Url,
ImageRectSize = Asset.ImageRectSize,
ImageRectOffset = Asset.ImageRectOffset,
ImageColor3 = Color3.new(1, 1, 1), -- #FFFFFF
ScaleType = Enum.ScaleType.Fit,
})

-- Apply any provided overrides
ApplyToInstance(ImageLabel, PropertyOverrides)

return ImageLabel
end

--[[
Returns a dictionary of every `Asset` from every icon name in `Lucide.IconNames`
This could also be useful for, for example, working with a custom asset
preloading system via `ContentProvider:PreloadAsync()` etc
*Example:*
```lua
local AllAssets = Lucide.GetAllAssets(256) -- Also defaults to `256`, just like `Lucide.GetAsset()`
for _, Asset in AllAssets do
print(Asset.IconName, Asset.Url)
end
```
]]
function Lucide.GetAllAssets(inputSize: number?): {Asset}
local InputSize = if inputSize == nil then 256 else inputSize

CheckArgTypes("Lucide.GetAllAssets", {InputSize}, {
[1] = {"inputSize", "number"},
})

local Assets = {}

for _, IconName in Lucide.IconNames do
local Asset = Lucide.GetAsset(IconName, InputSize)
if Asset then
table.insert(Assets, Asset)
end
end

-- `Lucide.IconNames` is already pre-sorted
return Assets
end

return Lucide
18 changes: 18 additions & 0 deletions stories.project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "Lucide Storybooks",
"tree": {
"$className": "DataModel",

"ServerStorage": {
"$className": "ServerStorage",

"Lucide Storybooks": {
"$path": "stories",

"Lucide": {
"$path": "default.project.json"
}
}
}
}
}
55 changes: 55 additions & 0 deletions stories/Lucide.story.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
-- MIT License | Copyright (c) 2023 Latte Softworks <https://latte.to>

local Lucide = require(script.Parent.Lucide)

local function ApplyToInstance(object: Instance, properties: {[string]: any}): Instance
if properties then
for Property, Value in properties do
if Property ~= "Parent" then
object[Property] = Value
end
end

if properties.Parent then
object.Parent = properties.Parent
end
end

return object
end

return function(target: Frame)
local InnerFrame = ApplyToInstance(Instance.new("ScrollingFrame"), {
Position = UDim2.fromOffset(20, 20),
Size = UDim2.new(1, -40, 1, 0),

BackgroundTransparency = 1,
BorderSizePixel = 0,

ScrollingDirection = Enum.ScrollingDirection.Y,
AutomaticCanvasSize = Enum.AutomaticSize.Y,
CanvasSize = UDim2.fromOffset(0, 0),
ScrollBarThickness = 8,

--BottomImage = "",
--MidImage = "",
--TopImage = "",
})

ApplyToInstance(Instance.new("UIGridLayout"), {
Parent = InnerFrame,

CellSize = UDim2.fromOffset(48, 48),
CellPadding = UDim2.fromOffset(10, 10),

HorizontalAlignment = Enum.HorizontalAlignment.Center,
})

InnerFrame.Parent = target

for _, IconName in Lucide.IconNames do
Lucide.ImageLabel(IconName, 48, {
Parent = InnerFrame
})
end
end

0 comments on commit 3ae82dc

Please sign in to comment.