> For the complete documentation index, see [llms.txt](https://thebuildex.gitbook.io/enoria/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://thebuildex.gitbook.io/enoria/guide/widgets.md).

# Widgets

Widgets can be basic Roblox UI elements such as `TextLabels`, `TextButtons`, etc. But, in Enoria, it can also be more complex elements, such as `Forms`, `ListBuilders`, `Columns`, and many more.&#x20;

For example, if we want to create a `TextLabel` :

```lua
e.TextLabel("Enter your text here", {
    TextColor3 = Color3.fromRGB(0, 255, 0)
})
```

The first parameter is just the text that you want to display. Then, you create a dictionnary as the second argument and you can set any properties (or events, but we'll get to that later).

![](https://4168240174-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MVNO0zjZpyCwODX_imL%2F-MVNizJpVoMuEEu4Xac0%2F-MVNjxUPlvQ-2sXyzUuO%2FScreenshot_13.png?alt=media\&token=c9b11e68-00d1-4aaf-a8c8-d25933ca0441)

## Creating custom widgets

You can also create custom widgets as well! These are useful when you don't want to repeat yourself.

### Function based widgets

It is possible (and really fast) to create custom widgets. The fastest way is by creating a function that returns a widget tree:

```lua
...
function ColoredContainer(color)
	return e.Container({ 
		BackgroundColor3 = color, 
		Size = UDim2.fromScale(1/3, 1) 
	})
end

e:RunApp({
	Name = "MyApp",
	Home = e.Row({
		Children = {
			ColoredContainer(Color3.fromRGB(255, 85, 0)),
			ColoredContainer(Color3.fromRGB(255, 170, 255)),
			ColoredContainer(Color3.fromRGB(85, 255, 127)),
		}
	})
})
```

The only downside is that they do not support state management.

### "Object-oriented based" widgets

There is another way to create custom widgets. There are some things that you need to know:

* How metatables (object-oriented programming) in Lua works.
* Your class need to inherit Enoria's base Widget class.
* You need to implement a build method.

Here's how you can do that:

{% code title="(in a new module script)" %}

```lua
local e = require(_G.EnoriaPath)
local Widget = require(_G.EnoriaPath.Parent.Widgets.Widget)

local ColoredContainer = {}
ColoredContainer.__index = ColoredContainer
setmetatable(ColoredContainer, Widget)

function ColoredContainer.new(context, color)
	local self = Widget.new(nil, nil, context)
	setmetatable(self, ColoredContainer)
	
	self.Color = color
	
	return self
end

function ColoredContainer:Build()
	return self:BuildTree(
		e.Container({ 
			BackgroundColor3 = self.Color, 
			Size = UDim2.fromScale(1/3, 1)
		})
	)
end

return ColoredContainer

```

{% endcode %}

Then, back in your Main localscript:

```lua
...
local ColoredContainer = require(script.Parent.ColoredContainer)
...
e:RunApp({
	Name = "MyApp",
	Home = e.Row({
		Children = {
			ColoredContainer.new(e.Context, Color3.fromRGB(255, 85, 0)):Build(),
			ColoredContainer.new(e.Context, Color3.fromRGB(255, 170, 255)):Build(),
			ColoredContainer.new(e.Context, Color3.fromRGB(85, 255, 127)):Build(),
		}
	})
})
```

This method is used when you want to handle [state](/enoria/state-management.md).
