Module:UtilsLayout/Tabs: Difference between revisions
Jump to navigation
Jump to search
PhantomCaleb (talk | contribs) No edit summary |
PhantomCaleb (talk | contribs) No edit summary |
||
Line 9: | Line 9: | ||
local collapse = options.collapse | local collapse = options.collapse | ||
local defaultTab = options.default or 1 | local defaultTab = options.default or 1 | ||
local stretch = options.stretch | |||
local fixedWidth = options.fixedWidth | local fixedWidth = options.fixedWidth | ||
local fixedHeight = options.fixedHeight | local fixedHeight = options.fixedHeight | ||
Line 16: | Line 17: | ||
end | end | ||
local tabContainer = h.tabContainer(data, defaultTab, format, align, columns) | local tabContainer = h.tabContainer(data, defaultTab, format, align, columns, stretch) | ||
local tabContents = h.tabContents(data, defaultTab, align, fixedWidth, fixedHeight) | local tabContents = h.tabContents(data, defaultTab, align, fixedWidth, fixedHeight) | ||
local html = mw.html.create("div") | local html = mw.html.create("div") | ||
Line 30: | Line 31: | ||
end | end | ||
function h.tabContainer(data, defaultTab, format, align, columns) | function h.tabContainer(data, defaultTab, format, align, columns, stretch) | ||
local tabContainer = mw.html.create("div"):addClass("tabcontainer tabcontainer-" .. format) | local tabContainer = mw.html.create("div"):addClass("tabcontainer tabcontainer-" .. format) | ||
if align then | if align then | ||
tabContainer:addClass("tabcontainer--"..align) | tabContainer:addClass("tabcontainer--"..align) | ||
end | |||
if stretch then | |||
tabContainer:addClass("tabcontainer--stretch") | |||
end | |||
if columns then | |||
tab:addClass("tabcontainer--columns") | |||
end | end | ||
Line 46: | Line 53: | ||
end | end | ||
if columns then | if columns then | ||
tab:css({ | tab:css({ | ||
["max-width"] = "calc(100%/"..columns.." - 3*"..columns.."px)" | ["max-width"] = "calc(100%/"..columns.." - 3*"..columns.."px)" | ||
Line 63: | Line 69: | ||
tabContents:css("text-align", align) | tabContents:css("text-align", align) | ||
end | end | ||
if fixedWidth then | if fixedWidth then | ||
tabContents:addClass("tabcontents--fixed-width") | tabContents:addClass("tabcontents--fixed-width") | ||
Line 138: | Line 143: | ||
default = mw.dumpObject("left"), | default = mw.dumpObject("left"), | ||
desc = "Horizontal alignment for tabs and their content.", | desc = "Horizontal alignment for tabs and their content.", | ||
}, | |||
{ | |||
name = "stretch", | |||
type = "boolean", | |||
desc = "If true, then tabs will stretch to fill the available space in their container.", | |||
}, | }, | ||
{ | { | ||
name = "columns", | name = "columns", | ||
type = "number", | type = "number", | ||
desc = "If specified, the tabs will attempt to arrange themselves in N columns of equal width." | desc = "If specified, the tabs will attempt to arrange themselves in N columns of equal width. This option is not compatible with <code>stretch</code>." | ||
}, | }, | ||
{ | { | ||
Line 215: | Line 225: | ||
{ collapse = true } | { collapse = true } | ||
} | } | ||
}, | |||
{ | |||
args = { | |||
{ | |||
{ | |||
label = "Tab1", | |||
content = "Content1", | |||
}, | |||
{ | |||
label = "Tab2", | |||
content = "Content2" | |||
}, | |||
}, | |||
{ | |||
stretch = true, | |||
}, | |||
}, | |||
}, | }, | ||
} | } |
Revision as of 19:44, 3 August 2020
Lua error in Module:Documentation/Module at line 351: attempt to call field 'Documentation' (a table value).
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 columns = options.columns
local collapse = options.collapse
local defaultTab = options.default or 1
local stretch = options.stretch
local fixedWidth = options.fixedWidth
local fixedHeight = options.fixedHeight
if #data == 1 and collapse then
return data[1].content
end
local tabContainer = h.tabContainer(data, defaultTab, format, align, columns, stretch)
local tabContents = h.tabContents(data, defaultTab, align, fixedWidth, fixedHeight)
local html = mw.html.create("div")
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, align, columns, stretch)
local tabContainer = mw.html.create("div"):addClass("tabcontainer tabcontainer-" .. format)
if align then
tabContainer:addClass("tabcontainer--"..align)
end
if stretch then
tabContainer:addClass("tabcontainer--stretch")
end
if columns then
tab:addClass("tabcontainer--columns")
end
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
if columns then
tab:css({
["max-width"] = "calc(100%/"..columns.." - 3*"..columns.."px)"
})
end
tabContainer:node(tab)
end
return tabContainer
end
function h.tabContents(data, defaultTab, align, fixedWidth)
local tabContents = mw.html.create("div")
:addClass("tabcontents")
if align then
tabContents:css("text-align", align)
end
if fixedWidth then
tabContents:addClass("tabcontents--fixed-width")
end
if fixedHeight then
tabContents:addClass("tabcontents--fixed-height")
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 = "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 = "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 = "stretch",
type = "boolean",
desc = "If true, then tabs will stretch to fill the available space in their container.",
},
{
name = "columns",
type = "number",
desc = "If specified, the tabs will attempt to arrange themselves in N columns of equal width. This option is not compatible with <code>stretch</code>."
},
{
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)."
},
{
name = "fixedHeight",
type = "boolean",
desc = "If truthy, the tab container will always assume the height of the tallest tab (as opposed to that 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 }
}
},
{
args = {
{
{
label = "Tab1",
content = "Content1",
},
{
label = "Tab2",
content = "Content2"
},
},
{
stretch = true,
},
},
},
}
}
}
return p