Module:UtilsLayout/Tabs

From DM Live - the Depeche Mode live encyclopedia for the masses
Jump to navigationJump to search

Documentation for this module may be created at Module:UtilsLayout/Tabs/doc

local p = {}
local h = {}

function p.tabs(data, options)
	local options = options or {}
	local format = options.format or "top"
	local align = options.align or "left"
	local collapse = options.collapse
	local defaultTab = options.default or 1
	local fixedWidth = options.fixedWidth
	
	if #data == 1 and collapse then
		return data[1].content
	end
	
	local tabContainer = h.tabContainer(data, defaultTab, format)
	local tabContents = h.tabContents(data, defaultTab, fixedWidth)
	local html = mw.html.create("div")
		:css("text-align", align)
	
	if format == "top" then
		html:node(tabContainer)
			:node(tabContents)
	else
		html:node(tabContents)
			:node(tabContainer)
	end
	return tostring(html)
end

function h.tabContainer(data, defaultTab, format)
	local tabContainer = mw.html.create("div")
		:addClass("tabcontainer tabcontainer-" .. format)
	
	for i, tabData in ipairs(data) do
		local tab = mw.html.create("span")
			:addClass("tab explain")
			:attr("title", tabData.tooltip)
			:wikitext(tabData.label)
		if i == defaultTab then
			tab:addClass("active")
		end
		tabContainer:node(tab)
	end
	return tabContainer
end

function h.tabContents(data, defaultTab, fixedWidth)
	local tabContents = mw.html.create("div")
		:addClass("tabcontents")
		
	if fixedWidth then
		tabContents:addClass("tabcontents--fixed-width")
	end
		
	for i, tabData in ipairs(data) do
		local content = mw.html.create("div")
			:addClass("content")
			:wikitext(tabData.content)
		if i == defaultTab then
			content:addClass("content--active")
		end
		tabContents:node(content)
	end
	return tabContents
end

p.Schemas = {
	tabs = {
		data = {
			type = "array",
			required = true,
			items = {
				type = "record",
				properties = {
					{
						name = "label",
						type = "string",
						required = true,
						desc = "Button text for the tab."
					},
					{
						name = "tooltip",
						type = "string",
						desc = "Tooltip for the tab button",
					},
					{
						name = "content",
						type = "string",
						required = true,
						desc = "Content for the tab.",
					},
				}
			}
		},
		options = {
			type = "record",
			properties = {
				{
					name = "format",
					type = "string",
					enum = {"top", "bottom"},
					default = mw.dumpObject("top"),
					desc = "If <code>top</code>, the tabs are placed above their content. If <code>bottom</code>, then the opposite."
				},
				{
					name = "align",
					type = "string",
					enum = {"left", "center", "right"},
					default = mw.dumpObject("left"),
					desc = "Horizontal alignment for tabs and their content.",
				},
				{
					name = "default",
					type = "number",
					default = 1,
					desc = "Index of default tab.",
				},
				{
					name = "collapse",
					type = "boolean",
					desc = "If truthy, tabs will not be rendered if there is only one tab. The content of that tab will simply be rendered instead."
				},
				{
					name = "fixedWidth",
					type = "boolean",
					desc = "If truthy, the tab container will always assume the width of the largest tab (as opposed to the width of the current tab)."
				},
			}
		},
	}
}

p.Documentation = {
	tabs = {
		params = {"data", "options"},
		returns = "HTML markup rendering tabs.",
		cases = {
			resultOnly = true,
			{
				args = {
					{
						{
							label = "Tab1",
							content = "Content1",
						},
						{
							label = "Tab2",
							content = "Content2"
						},
					},
				}
			},
			{
				args = {
					{
						{
							label = "Tab1",
							tooltip = "This is the first tab.",
							content = "Content1"
						},
						{
							label = "Tab2",
							tooltip = "This is the second tab.",
							content = "Content2"
						},
						{
							label = "Tab3",
							tooltip = "This is the third tab.",
							content = "Content3"
						}
					},
					{
						format = "bottom",
						align = "center",
						default = 2,
					}
				}
			},
			{
				args = {
					{{ label = "Single Tab", content = "Content" }}
				}
			},
			{
				args = {
					{{ label = "Single Tab", content = "Content" }},
					{ collapse = true }
				}
			},
		}
	}
}

return p