Facebook's React.js-like UI Development Framework for Roblox(Luau) and Kolloid Framework on Roblox
"Koact" stands for KO(lloid)(re)ACT It is a built-in library for the Kolloid framework and is included as a submodule. Koact also enables UI development in Roblox in a similar way to React.
- This project was not developed using rojo (I just wanted to develop on Roblox Studio :D, And this makes it easy to insert as a submodule into the kolloid framework)
- I'm thinking about using wally package manager soon
- The autocomplete feature has only been tested in Roblox Studio's script editor. Sadly it may not work externally or on the Roblox LSP.
- I spent quite a bit of my time to open source this project in order to be of some help to someone. Please refrain from criticizing me and I would appreciate it if you could help me.
- This project is not yet complete and may contain errors or bugs.
- Not much testing has been done yet, and there may still be unknown issues remaining. (I would really appreciate it if you could report it to the issues. Or contact me through Discord
jiwonz
) - Documentation is not yet complete. If you have any questions, please leave an issue or contact us on Discord
jiwonz
and i will gladly explain.
- React-like development pattern and code styles
- Supports Roblox UI Classes
- Supports Full Auto completion (for Roblox Studio)
- Supports Helper types (for Roblox Studio)
- Supports React-like Hooks
- More snippets support
- Unlike react, there is Modifiers concept
- Unlike react, supports Localization
- Unlike react, supports 2D ParticleEmitter (thanks to @nuttolum)
localization/default.lua
return Koact.newLocalizationTable{
CounterText="you've clicked %s times!";
}
localization/tur.lua
local Default = require(script.Parent.default)
return {
[Default.CounterText]="%s kez tıkladınız!";
}
number_counter.lua
local localizationTable = require(script.Parent.localization.default)
local function App()
local count, setCount = Koact.useState(0)
local localization = Koact.useLocalization(localizationTable)
return Koact.TextButton{
Position=UDim2.fromScale(0.5,0.5);
AnchorPoint=Vector2.new(0.5,0.5);
Size=UDim2.fromScale(0.5,0.5);
Text=(localization.CounterText):format(count); --- if you're turkish, this text will be "{count} kez tıkladınız!"
onClick=function()
setCount(count+1)
end
}
end
Koact.render(
Koact.ScreenGui{
Koact[App]{}
},LocalPlayer.PlayerGui
)
COMING SOON
Although there are some things missing or added to Koact, i recommend that you refer to React's reference. Additionally, Koact uses a virtual DOM(Koact elements) like React and its life cycle is almost identical to React. also full documentation for Koact will be released later. if you have a question or a problem, please leave a issue or a DM in my discord jiwonz
- You can type 'help' or 'HELP' in props table to watch all properties
- If there are any changes to the Roblox UI API, the helper must be updated for autocomplete to work to the latest version.
example
--- to create UI Elements
Koact["Roblox UI Class Name Here"]{} --- equal to Koact["Roblox UI Class Name Here"](), props can be nil if you want
--- TextLabel element
Koact.TextLabel{
Text="Hello world";
}
--- event handling
Koact.ImageButton{
ref=ref;
onClick=function()
print("clicked")
end,
onMouseDown=function()
print("mouse button down")
end,
onMouseUp=function()
print("mouse button up")
end,
onMouseEnter=function()
print("mouse entered")
end,
onMouseLeave=function()
print("mouse left")
end,
onRightClick=function()
print("right mouse clicked")
end,
on={"Changed",function()
print("you can also handle Instance's events manually too!")
end},
onChange={"Name",function(old,new)
print("property Name has changed to",new,"from",old)
end}
}
--- style
local styles = Koact.newStylesheet({
BlueBackground={
BackgroundColor3=Color3.new(0,0,1);
};
[Koact.Frame]={
BackgroundColor3=Color3.new(1,0,0);
}
})
return function()
Koact.useStylesheet(styles)
return Koact.Frame{
Name="Red Screen";
Size=UDim2.fromScale(1,1);
Koact.TextLabel{
style=styles.BlueBackground;
Size=UDim2.fromScale(0.5,0.5);
}
}
end
- Make child components render in the parent component
- Provides path and navigate function to children components
- If the router's current path matches, render the child component, otherwise not render it
- Provides a localization table to child components, equivalent to localizationTable.Provider{}, which receives the
localization
prop
- Creates a 2D particle emitter that receives
ParticleEmitter
and theEnabled
andEmit
properties. - Special thanks to
@nuttolum
for providing the implementation of the 2D particle emitter
Koact.Modifier[Element Name]
Creates a modifier element whose parent element is affected by it
example
--- you can create roblox's modifiers such as UIGradient, UIStroke, UICorners and etc
--- Or you can use special custom modifiers whose references are listed below.
return Koact.Frame{
Size=UDim2.fromOffset(300,300);
Koact.Modifier.UIGradient{
Color=ColorSequence.new(Color3.new(1,0,0),Color3.new(0,0,1));
Rotation=45;
}
}
- Modifies parent element's TextSize depends on this modifier's
Scale
prop - This
Scale
prop is relative to the Y axis - Example code is appeared in Function Components example code section
- Uses Image's slices to implement its round corners
- Must be parented to ImageLabel or ImageButton
- Special thanks to
@qwreey75
for contributing the rounded corners feature of theQuad UI library
.
- Makes parent element's area blurry
- Uses
DOF
to create this blur effect - Special thanks to @Fractality for providing the 2D blur effect module.
- Makes whole screen blurry if the parent element is visible
- Creates shadow effect on the parent element
- It repeats every frame to maintain the position of the parent element.
- Requires prop
Dragger
argument which must be a Button - Allows you to click on a Dragger element and drag the position of its parent element.
- Attaches resizers to parent elements
example
local function MyButton(props)
return Koact.ImageButton{
Position=props.Position;
Size=props.Size;
Image=Koact.rbxassetid(12345678);
Koact.TextLabel{
Size=UDim2.fromScale(1,1);
Text=props.Text:upper(); --- i want to make it upper case :D
Koact.Modifier.TextScale{
Scale=0.7;
}; --- TextScale example!
}
}
end
Koact.render(
Koact.ScreenGui{
Koact[MyButton]{ --- this table is called 'props'
Text="Hello Koact!"
Size=UDim2.fromOffset(200,100);
Position=UDim2.fromOffset(0,0);
};
Koact[MyButton]{
Size=UDim2.fromOffset(200,100);
Position=UDim2.fromOffset(0,100);
};
Koact[MyButton]{
Size=UDim2.fromOffset(200,100);
Position=UDim2.fromOffset(0,200);
};
},LocalPlayer.PlayerGui
)
warning
This function is only available in function component scope
useContext: (context: Context) -> (any?)
- Returns a value from the given context.
warning
This function is only available in function component scope
useState: (initialValue: any?) -> (any?, (value) -> ())
- Manages state in functional components.
warning
This function is only available in function component scope
useEffect: (callback: () -> (), ...any?) -> (() -> ())
- Runs an effect in functional components.
warning
This function is only available in function component scope
useReducer: (reducer: (state: any?, action: any?) -> (any?), initialArg: any?) -> (any?, (action: any?) -> ())
- Manages state using a reducer function.
example
local function counterReducer(state,action)
if action.type == "INCREMENT" then
return { count = state.count + 1 }
elseif action.type == "DECREMENT" then
return { count = state.count - 1 }
else
return state
end
end
local function Counter()
local state, dispatch = Koact.useReducer(counterReducer,{ count = 0 })
return Koact.TextButton{
Position=UDim2.fromScale(0.5,0.5);
AnchorPoint=Vector2.new(0.5,0.5);
Text=state.count;
Size=UDim2.fromScale(0.5,0.5);
onClick=function()
dispatch({ type = "INCREMENT" })
end,
onRightClick=function()
dispatch({ type = "DECREMENT" })
end,
Koact.Modifier.TextScale{
Scale=0.7;
}
}
end
warning
This function is only available in function component scope
useRef: (initialValue) -> (Ref)
- Creates a mutable object that persists across renders.
example
return function()
local ref = Koact.useRef()
Koact.useEffect(function()
local viewportFrame = ref.current
local camera = Instance.new("Camera",viewportFrame)
viewportFrame.CurrentCamera = camera
local sword = script.Parent.assets.Sword:Clone()
sword.Parent = viewportFrame
end,nil)
return Koact.ViewportFrame{
ref=ref;
}
end
warning
This function is only available in function component scope
useCallback: (callback: () -> (), ...any?) -> (() -> ())
- Memoizes a callback function.
warning
This function is only available in function component scope
useMemo: (callback: () -> (), ...any?) -> (any?)
- Memoizes a value.
warning
This function is only available in function component scope
useChange: (...any?) -> (boolean)
- Monitors changes and returns a boolean.
warning
This function is only available in function component scope
useNavigate: () -> ()
- Navigates within the application.
warning
This function is only available in function component scope
useTween: (initialValue: any) -> (Hooker, () -> ())
- When the initial value is set, tweening is not initially performed to that initial value position.
- The first returns a state value, and the second returns a function that can trigger the tween by changing the state value.
warning
This function is only available in function component scope
useLocalization: (localizationTable: {}) -> ({})
- Returns current localization table
warning
This function is only available in function component scope
useLanguage: () -> (Locale.Enums, (Locale.Enums) -> ())
- Returns current language using and a function that allows you to manually change the main language of the localization table that useLocalization will return.
warning
This function is only available in function component scope
useSound: (sound: Sound) -> () -> ()
- This returns a function that has the same effect as
SoundService:PlayLocal(sound)
warning
This function is only available in function component scope
useStylesheet: (stylesheet: {}) -> ()
- Applies a stylesheet to a component.
newContext: (initialValue: any?) -> (Context)
- Creates a new context.
newLocalizationTable: (localizationTable: {}) -> ({Provider: LocalizationProvider})
- Creates a new localization table container and returns localizationTable + Provider
- Supports autocomplete for localization table
memo: (component: Component) -> (Component)
Memoizes a component.(COMING SOON)
render: (element: Element, rendererInstance: Instance) -> ()
- Renders an element.
rbxassetid: (assetId: number | string) -> (string)
- Converts an asset ID number to a rbxasset string.
issues
Bugs may occur if these functions are used with or after a function that yields a thread.
warning
This function is only available in function component scope
setTimeout: (func: () -> (), seconds: number) -> ()
- Sets a timeout for a function.
warning
This function is only available in function component scope
setInterval: (func: () -> (), seconds: number) -> (number)
- Sets an interval for a function.
warning
This function is only available in function component scope
clearInterval: (intervalId: number) -> ()
- Clears an interval.
warning
This function is only available in function component scope
async: (func: () -> ()) -> (() -> ())
- Executes a function asynchronously.
warning
This function is only available in function component scope
await: (func: () -> ()) -> (any)
- Awaits the result of an asynchronous function.
- Asynchronous functions may not work as expected or may produce errors or bugs.
- Function Koact.render() is little bit messy -> bugs can be seen.
- Koact.memo()
- More optimized performance
- More features for Koact.useSound()
- @facebook for inspiration and solutions
- @qwreey75 for quad/round, UIDragger, UIReszier and for providing the necessary knowledge about React and providing a lot of help.
- @Fractality for UI Blur
- @nuttolum for UIParticle
- @roblox for roact/type, roact/symbol