> 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).

![](/files/-MVNjxUPlvQ-2sXyzUuO)

## 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).
