Created
August 22, 2024 20:47
-
-
Save cameronpcampbell/c0b2e187444d94cd0d6b95b51a648c63 to your computer and use it in GitHub Desktop.
Component Helper (Fusion)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--!strict | |
--> Modules ------------------------------------------------------------------------------------------- | |
local Fusion = require(script.Parent.Fusion) -- Replace with path to fusion. | |
------------------------------------------------------------------------------------------------------- | |
--> Types --------------------------------------------------------------------------------------------- | |
type Scope = Fusion.Scope<typeof(Fusion)> | |
type BaseProps = { | |
Scope: Fusion.Scope<typeof(Fusion)>, | |
[string | Fusion.SpecialKey]: unknown? | |
} | |
type BasePropsOptional = { | |
Scope: (Fusion.Scope<typeof(Fusion)>)?, | |
[string | Fusion.SpecialKey]: unknown? | |
} | |
------------------------------------------------------------------------------------------------------- | |
--> Variables ----------------------------------------------------------------------------------------- | |
local Children = Fusion.Children | |
------------------------------------------------------------------------------------------------------- | |
--> Functions ----------------------------------------------------------------------------------------- | |
local function TableTake(tble: { [any]: any }, keyOrIndex: any, default: any?) | |
local value = tble[keyOrIndex] | |
tble[keyOrIndex] = nil | |
if value == nil then return default end | |
return value | |
end | |
local function CombineProps(...: Fusion.PropertyTable): Fusion.PropertyTable | |
local propTablesLength = select("#", ...) | |
if propTablesLength == 1 then return ... end | |
local combinedProps: Fusion.PropertyTable = {} | |
local combinedChildren: { Fusion.Child } = {} | |
for i = 1, propTablesLength do | |
local propTble = select(i, ...) | |
for propName,propValue in propTble do | |
if propName == Children then | |
if typeof(propValue) == "table" and not propValue.kind then | |
for _,child in propValue do table.insert(combinedChildren, child) end | |
else | |
table.insert(combinedChildren, propValue) | |
end | |
continue | |
end | |
combinedProps[propName] = propValue | |
end | |
end | |
if #combinedChildren then | |
combinedProps[Children] = combinedChildren | |
end | |
return combinedProps | |
end | |
------------------------------------------------------------------------------------------------------- | |
return { | |
Component = function <Props>(fn: (scope: Scope, props: Props) -> Fusion.Child) | |
return function(props: Props & BaseProps, ...: Props & BasePropsOptional) | |
local combinedProps = CombineProps(props, ...) :: Props & BaseProps | |
local scope = TableTake(combinedProps, "Scope") :: Scope | |
return fn(scope, combinedProps) | |
end | |
end, | |
ComponentExplicitScope = function <Props>(fn: (scope: Scope, props: Props) -> Fusion.Child) | |
return function(scope: Scope, ...: Props & BasePropsOptional) | |
local combinedProps = CombineProps(...) :: Props & BaseProps | |
scope = TableTake(combinedProps, "Scope", scope) :: Scope | |
return fn(scope, combinedProps) | |
end | |
end, | |
} |
why not leave the scope as the first arg for the component so it can be used in scooed syntax
ComponentExplicitScope
does this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example Usage