PhantomCaleb (talk | contribs) No edit summary |
PhantomCaleb (talk | contribs) mNo edit summary |
||
(14 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
function p.tabs(data, options) |
function p.tabs(data, options) |
||
local options = options or {} |
local options = options or {} |
||
− | local |
+ | local tabOptions = options.tabOptions or {} |
− | local |
+ | local labelOptions = options.labelOptions or {} |
− | local |
+ | local contentOptions = options.contentOptions or {} |
+ | |||
− | local collapse = options.collapse |
||
local defaultTab = options.default or 1 |
local defaultTab = options.default or 1 |
||
− | local |
+ | local align = options.align or "left" |
⚫ | |||
⚫ | |||
− | if #data == 1 and collapse then |
+ | if #data == 1 and tabOptions.collapse then |
return data[1].content |
return data[1].content |
||
end |
end |
||
− | local tabContainer = h.tabContainer(data, defaultTab |
+ | local tabContainer = h.tabContainer(data, defaultTab, align, tabOptions, labelOptions) |
− | local tabContents = h.tabContents(data, defaultTab, align, |
+ | local tabContents = h.tabContents(data, defaultTab, align, contentOptions) |
⚫ | |||
⚫ | |||
− | if format == "top" then |
||
+ | if tabOptions.position == "bottom" then |
||
⚫ | |||
⚫ | |||
⚫ | |||
html:node(tabContents) |
html:node(tabContents) |
||
:node(tabContainer) |
:node(tabContainer) |
||
⚫ | |||
⚫ | |||
⚫ | |||
end |
end |
||
return tostring(html) |
return tostring(html) |
||
end |
end |
||
− | function h.tabContainer(data, defaultTab |
+ | function h.tabContainer(data, defaultTab, align, tabOptions, labelOptions) |
+ | local position = tabOptions.position or "top" |
||
⚫ | |||
+ | local stretch = tabOptions.stretch |
||
⚫ | |||
+ | local columns = tabOptions.columns |
||
− | if align then |
||
+ | local labelAlignVertical = labelOptions.alignVertical or "center" |
||
⚫ | |||
− | + | ||
⚫ | |||
+ | :addClass("tabcontainer tabcontainer-"..position) |
||
⚫ | |||
+ | |||
if stretch then |
if stretch then |
||
tabContainer:addClass("tabcontainer--stretch") |
tabContainer:addClass("tabcontainer--stretch") |
||
end |
end |
||
if columns then |
if columns then |
||
− | + | tabContainer:addClass("tabcontainer--columns") |
|
end |
end |
||
for i, tabData in ipairs(data) do |
for i, tabData in ipairs(data) do |
||
local tab = mw.html.create("span") |
local tab = mw.html.create("span") |
||
− | :addClass("tab |
+ | :addClass("tab") |
+ | :addClass("explain") |
||
+ | :addClass("tab--label-align-y-"..labelAlignVertical) |
||
:attr("title", tabData.tooltip) |
:attr("title", tabData.tooltip) |
||
:wikitext(tabData.label) |
:wikitext(tabData.label) |
||
Line 54: | Line 58: | ||
if columns then |
if columns then |
||
tab:css({ |
tab:css({ |
||
− | ["max-width"] = "calc(100%/"..columns.." - |
+ | ["max-width"] = "calc(100%/"..columns.." - 2*"..(columns-1).."px)" -- the subtraction is to account for tab margins |
}) |
}) |
||
end |
end |
||
Line 62: | Line 66: | ||
end |
end |
||
− | function h.tabContents(data, defaultTab, align, |
+ | function h.tabContents(data, defaultTab, align, contentOptions) |
+ | local alignVertical = contentOptions.alignVertical or "top" |
||
⚫ | |||
⚫ | |||
+ | |||
local tabContents = mw.html.create("div") |
local tabContents = mw.html.create("div") |
||
:addClass("tabcontents") |
:addClass("tabcontents") |
||
+ | :addClass("tabcontents--align-x-"..align) |
||
⚫ | |||
+ | :addClass("tabcontents--align-y-"..alignVertical) |
||
− | if align then |
||
+ | |||
⚫ | |||
⚫ | |||
if fixedWidth then |
if fixedWidth then |
||
tabContents:addClass("tabcontents--fixed-width") |
tabContents:addClass("tabcontents--fixed-width") |
||
+ | if type(fixedWidth) == "number" then |
||
⚫ | |||
⚫ | |||
end |
end |
||
if fixedHeight then |
if fixedHeight then |
||
tabContents:addClass("tabcontents--fixed-height") |
tabContents:addClass("tabcontents--fixed-height") |
||
+ | if type(fixedHeight) == "number" then |
||
+ | tabContents:css("height", fixedHeight .. "px") |
||
+ | end |
||
end |
end |
||
Line 109: | Line 122: | ||
{ |
{ |
||
name = "content", |
name = "content", |
||
− | type = "string", |
+ | type = "string", |
required = true, |
required = true, |
||
desc = "Content for the tab.", |
desc = "Content for the tab.", |
||
Line 124: | Line 137: | ||
default = 1, |
default = 1, |
||
desc = "Index of default tab.", |
desc = "Index of default tab.", |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
}, |
}, |
||
{ |
{ |
||
Line 145: | Line 146: | ||
}, |
}, |
||
{ |
{ |
||
− | name = " |
+ | name = "tabOptions", |
− | type = " |
+ | type = "record", |
− | desc = " |
+ | desc = "Display options for the tabs themselves.", |
+ | properties = { |
||
⚫ | |||
+ | name = "position", |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | }, |
||
+ | { |
||
⚫ | |||
⚫ | |||
⚫ | |||
+ | }, |
||
+ | { |
||
⚫ | |||
⚫ | |||
+ | desc = "If true, then tabs will stretch to fill the available space in their container.", |
||
+ | }, |
||
+ | { |
||
⚫ | |||
⚫ | |||
⚫ | |||
+ | }, |
||
+ | }, |
||
}, |
}, |
||
{ |
{ |
||
− | name = " |
+ | name = "labelOptions", |
− | type = " |
+ | type = "record", |
+ | desc = "Display options for the tab labels.", |
||
⚫ | |||
+ | properties = { |
||
+ | { |
||
+ | name = "alignVertical", |
||
⚫ | |||
+ | enum = {"center", "bottom"}, |
||
+ | default = mw.dumpObject("center"), |
||
+ | desc = "Vertical alignment of the label with respect to its tab. Options are: <code>center</code> (default) and <code>bottom</code>.", |
||
+ | }, |
||
+ | }, |
||
}, |
}, |
||
{ |
{ |
||
− | name = " |
+ | name = "contentOptions", |
− | type = " |
+ | type = "record", |
+ | desc = "Display options for the tab contents.", |
||
⚫ | |||
+ | properties = { |
||
+ | { |
||
+ | name = "fixedContentWidth", |
||
+ | oneOf = { |
||
+ | { type = "boolean" }, |
||
+ | { type = "number" }, |
||
+ | }, |
||
⚫ | |||
+ | }, |
||
+ | { |
||
+ | name = "fixedContentHeight", |
||
+ | oneOf = { |
||
+ | { type = "boolean" }, |
||
+ | { type = "number" }, |
||
+ | }, |
||
⚫ | |||
+ | }, |
||
+ | { |
||
+ | name = "alignVertical", |
||
⚫ | |||
+ | enum = {"top", "center", "bottom"}, |
||
+ | default = mw.dumpObject("top"), |
||
+ | desc = "Vertical alignment of tab contents with respect to the tab container. Useful only alonside <code>fixedHeight</code>." |
||
+ | }, |
||
+ | }, |
||
}, |
}, |
||
− | + | }, |
|
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
}, |
}, |
||
} |
} |
||
Line 188: | Line 242: | ||
}, |
}, |
||
} |
} |
||
⚫ | |||
⚫ | |||
+ | args = { |
||
⚫ | |||
+ | { |
||
+ | label = "Tab1", |
||
+ | content = "Content1", |
||
+ | }, |
||
+ | { |
||
+ | label = "Tab2", |
||
+ | content = "Content2" |
||
+ | }, |
||
+ | }, |
||
⚫ | |||
+ | tabOptions = { |
||
+ | stretch = true, |
||
+ | } |
||
+ | }, |
||
⚫ | |||
}, |
}, |
||
{ |
{ |
||
Line 209: | Line 282: | ||
}, |
}, |
||
{ |
{ |
||
⚫ | |||
⚫ | |||
default = 2, |
default = 2, |
||
+ | align = "center", |
||
+ | tabOptions = { |
||
+ | position = "bottom", |
||
+ | }, |
||
} |
} |
||
} |
} |
||
}, |
}, |
||
{ |
{ |
||
+ | desc = "Tabs display even for a single tab unless <code>collapse</code> is set to true.", |
||
args = { |
args = { |
||
{{ label = "Single Tab", content = "Content" }} |
{{ label = "Single Tab", content = "Content" }} |
||
Line 223: | Line 299: | ||
args = { |
args = { |
||
{{ label = "Single Tab", content = "Content" }}, |
{{ label = "Single Tab", content = "Content" }}, |
||
− | { |
+ | { |
+ | tabOptions = { |
||
+ | collapse = true |
||
+ | } |
||
+ | }, |
||
} |
} |
||
}, |
}, |
||
{ |
{ |
||
+ | desc = "<code>fixedContentWidth</code> and <code>fixedContentHeight</code> determine how the overall tab container is sized.", |
||
args = { |
args = { |
||
{ |
{ |
||
+ | { label = "Small Tab", content = "meep" }, |
||
⚫ | |||
− | + | { label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep" }, |
|
− | + | { label = "Tall tab", content = "m\ne\ne\ne\ne\np" }, |
|
+ | }, |
||
⚫ | |||
+ | }, |
||
⚫ | |||
+ | args = { |
||
+ | { |
||
+ | { label = "Small Tab", content = "meep" }, |
||
+ | { label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep" }, |
||
+ | { label = "Tall tab", content = "m\ne\ne\ne\ne\np" }, |
||
+ | }, |
||
+ | { |
||
+ | contentOptions = { |
||
+ | fixedWidth = true, |
||
}, |
}, |
||
− | + | }, |
|
− | + | }, |
|
+ | }, |
||
⚫ | |||
+ | { |
||
+ | args = { |
||
+ | { |
||
+ | { label = "Small Tab", content = "meep" }, |
||
+ | { label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep" }, |
||
+ | { label = "Tall tab", content = "m\ne\ne\ne\ne\np" }, |
||
+ | }, |
||
+ | { |
||
+ | contentOptions = { |
||
+ | fixedHeight = true, |
||
}, |
}, |
||
}, |
}, |
||
+ | }, |
||
+ | }, |
||
+ | { |
||
+ | args = { |
||
{ |
{ |
||
− | + | { label = "Small Tab", content = "meep" }, |
|
+ | { label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep" }, |
||
+ | { label = "Tall tab", content = "m\ne\ne\ne\ne\np" }, |
||
+ | }, |
||
+ | { |
||
+ | contentOptions = { |
||
+ | fixedWidth = true, |
||
+ | fixedHeight = true, |
||
+ | alignVertical = "center", |
||
+ | }, |
||
+ | }, |
||
+ | }, |
||
+ | }, |
||
+ | { |
||
+ | args = { |
||
+ | { |
||
+ | { label = "Small Tab", content = "meep" }, |
||
+ | { label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep" }, |
||
+ | { label = "Tall tab", content = "m\ne\ne\ne\ne\np" }, |
||
+ | }, |
||
+ | { |
||
+ | contentOptions = { |
||
+ | fixedWidth = 80, |
||
+ | fixedHeight = 80, |
||
+ | alignVertical = "center", |
||
+ | }, |
||
+ | }, |
||
+ | }, |
||
+ | }, |
||
+ | { |
||
+ | desc = "When images are used as tab labels, the label alignment options can be useful.", |
||
+ | args = { |
||
+ | { |
||
+ | { label = "[[File:ST Engine Icon.png|link=]]", content = "Engines" }, |
||
+ | { label = "[[File:ST Passenger Car Icon.png|link=]]", content = "Passenger Cars" }, |
||
+ | }, |
||
+ | { |
||
+ | labelOptions = { |
||
+ | alignVertical = "bottom", |
||
+ | }, |
||
}, |
}, |
||
}, |
}, |
||
}, |
}, |
||
− | } |
+ | }, |
− | } |
+ | }, |
} |
} |
||
Revision as of 13:43, 26 September 2020
This module exports the following functions.
tabs
tabs(data, [options])
Parameters
[options]
[default=1]
- Index of default tab.
[align="\"left\""]
- Horizontal alignment for tabs and their content.
[tabOptions]
- Display options for the tabs themselves.
[position="\"top\""]
- If
top
(default), the tabs are placed above their content. Ifbottom
, then the opposite. [collapse]
- If truthy, tabs will not be rendered if there is only one tab. The content of that tab will simply be rendered instead.
[stretch]
- If true, then tabs will stretch to fill the available space in their container.
[columns]
- If specified, the tabs will attempt to arrange themselves in N columns of equal width. This option is not compatible with
stretch
.
[labelOptions]
- Display options for the tab labels.
[alignVertical="\"center\""]
- Vertical alignment of the label with respect to its tab. Options are:
center
(default) andbottom
.
[contentOptions]
- Display options for the tab contents.
[fixedContentWidth]
- Width for the tab container in
px
. Or, if set totrue
, the tab container will assume the width of the largest tab. By default, the tab container assumes the width of the current tab. [fixedContentHeight]
- Height for the tab container in
px
. Or, if set totrue
, the tab container will assume the height of the largest tab. By default, the tab container assumes the height of the current tab. [alignVertical="\"top\""]
- Vertical alignment of tab contents with respect to the tab container. Useful only alonside
fixedHeight
.
Returns
- HTML markup rendering tabs.
Examples
# | Input | Result | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | tabs({
{
content = "Content1",
label = "Tab1",
},
{
content = "Content2",
label = "Tab2",
},
})
| Tab1Tab2 Content1 Content2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | tabs(
{
{
content = "Content1",
label = "Tab1",
},
{
content = "Content2",
label = "Tab2",
},
},
{
tabOptions = { stretch = true },
}
)
| Tab1Tab2 Content1 Content2 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3 | tabs(
{
{
tooltip = "This is the first tab.",
content = "Content1",
label = "Tab1",
},
{
tooltip = "This is the second tab.",
content = "Content2",
label = "Tab2",
},
{
tooltip = "This is the third tab.",
content = "Content3",
label = "Tab3",
},
},
{
align = "center",
default = 2,
tabOptions = { position = "bottom" },
}
)
| Content1 Content2 Content3 Tab1Tab2Tab3 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tabs display even for a single tab unless collapse is set to true. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | tabs({
{
content = "Content",
label = "Single Tab",
},
})
| Single Tab Content | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
5 | tabs(
{
{
content = "Content",
label = "Single Tab",
},
},
{
tabOptions = { collapse = true },
}
)
| Content | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fixedContentWidth and fixedContentHeight determine how the overall tab container is sized. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | tabs({
{
content = "meep",
label = "Small Tab",
},
{
content = "meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep",
label = "Wide Tab",
},
{
content = "m\ne\ne\ne\ne\np",
label = "Tall tab",
},
})
| Small TabWide TabTall tab meep meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep m
e e e e p | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
7 | tabs(
{
{
content = "meep",
label = "Small Tab",
},
{
content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep",
label = "Wide Tab",
},
{
content = "m\ne\ne\ne\ne\np",
label = "Tall tab",
},
},
{
contentOptions = { fixedWidth = true },
}
)
| Small TabWide TabTall tab meep meeeeeeeeeeeeeeeeeeeeeeeeeeep m
e e e e p | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
8 | tabs(
{
{
content = "meep",
label = "Small Tab",
},
{
content = "meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep",
label = "Wide Tab",
},
{
content = "m\ne\ne\ne\ne\np",
label = "Tall tab",
},
},
{
contentOptions = { fixedHeight = true },
}
)
| Small TabWide TabTall tab meep meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep m
e e e e p | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
9 | tabs(
{
{
content = "meep",
label = "Small Tab",
},
{
content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep",
label = "Wide Tab",
},
{
content = "m\ne\ne\ne\ne\np",
label = "Tall tab",
},
},
{
contentOptions = {
fixedWidth = true,
alignVertical = "center",
fixedHeight = true,
},
}
)
| Small TabWide TabTall tab meep meeeeeeeeeeeeeeeeeeeeeeeeeeep m
e e e e p | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
10 | tabs(
{
{
content = "meep",
label = "Small Tab",
},
{
content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep",
label = "Wide Tab",
},
{
content = "m\ne\ne\ne\ne\np",
label = "Tall tab",
},
},
{
contentOptions = {
fixedWidth = 80,
alignVertical = "center",
fixedHeight = 80,
},
}
)
| Small TabWide TabTall tab meep meeeeeeeeeeeeeeeeeeeeeeeeeeep m
e e e e p | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
When images are used as tab labels, the label alignment options can be useful. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
11 | tabs(
{
{
content = "Engines",
label = "[[File:ST Engine Icon.png|link=]]",
},
{
content = "Passenger Cars",
label = "[[File:ST Passenger Car Icon.png|link=]]",
},
},
{
labelOptions = { alignVertical = "bottom" },
}
)
| Engines Passenger Cars |
local p = {}
local h = {}
function p.tabs(data, options)
local options = options or {}
local tabOptions = options.tabOptions or {}
local labelOptions = options.labelOptions or {}
local contentOptions = options.contentOptions or {}
local defaultTab = options.default or 1
local align = options.align or "left"
if #data == 1 and tabOptions.collapse then
return data[1].content
end
local tabContainer = h.tabContainer(data, defaultTab, align, tabOptions, labelOptions)
local tabContents = h.tabContents(data, defaultTab, align, contentOptions)
local html = mw.html.create("div")
if tabOptions.position == "bottom" then
html:node(tabContents)
:node(tabContainer)
else
html:node(tabContainer)
:node(tabContents)
end
return tostring(html)
end
function h.tabContainer(data, defaultTab, align, tabOptions, labelOptions)
local position = tabOptions.position or "top"
local stretch = tabOptions.stretch
local columns = tabOptions.columns
local labelAlignVertical = labelOptions.alignVertical or "center"
local tabContainer = mw.html.create("div")
:addClass("tabcontainer tabcontainer-"..position)
:addClass("tabcontainer--align-x-"..align)
if stretch then
tabContainer:addClass("tabcontainer--stretch")
end
if columns then
tabContainer:addClass("tabcontainer--columns")
end
for i, tabData in ipairs(data) do
local tab = mw.html.create("span")
:addClass("tab")
:addClass("explain")
:addClass("tab--label-align-y-"..labelAlignVertical)
: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.." - 2*"..(columns-1).."px)" -- the subtraction is to account for tab margins
})
end
tabContainer:node(tab)
end
return tabContainer
end
function h.tabContents(data, defaultTab, align, contentOptions)
local alignVertical = contentOptions.alignVertical or "top"
local fixedWidth = contentOptions.fixedWidth
local fixedHeight = contentOptions.fixedHeight
local tabContents = mw.html.create("div")
:addClass("tabcontents")
:addClass("tabcontents--align-x-"..align)
:addClass("tabcontents--align-y-"..alignVertical)
if fixedWidth then
tabContents:addClass("tabcontents--fixed-width")
if type(fixedWidth) == "number" then
tabContents:css("width", fixedWidth .. "px")
end
end
if fixedHeight then
tabContents:addClass("tabcontents--fixed-height")
if type(fixedHeight) == "number" then
tabContents:css("height", fixedHeight .. "px")
end
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 = "align",
type = "string",
enum = {"left", "center", "right"},
default = mw.dumpObject("left"),
desc = "Horizontal alignment for tabs and their content.",
},
{
name = "tabOptions",
type = "record",
desc = "Display options for the tabs themselves.",
properties = {
{
name = "position",
type = "string",
enum = {"top", "bottom"},
default = mw.dumpObject("top"),
desc = "If <code>top</code> (default), the tabs are placed above their content. If <code>bottom</code>, then the opposite."
},
{
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 = "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 = "labelOptions",
type = "record",
desc = "Display options for the tab labels.",
properties = {
{
name = "alignVertical",
type = "string",
enum = {"center", "bottom"},
default = mw.dumpObject("center"),
desc = "Vertical alignment of the label with respect to its tab. Options are: <code>center</code> (default) and <code>bottom</code>.",
},
},
},
{
name = "contentOptions",
type = "record",
desc = "Display options for the tab contents.",
properties = {
{
name = "fixedContentWidth",
oneOf = {
{ type = "boolean" },
{ type = "number" },
},
desc = "Width for the tab container in <code>px</code>. Or, if set to <code>true</code>, the tab container will assume the width of the largest tab. By default, the tab container assumes the width of the current tab."
},
{
name = "fixedContentHeight",
oneOf = {
{ type = "boolean" },
{ type = "number" },
},
desc = "Height for the tab container in <code>px</code>. Or, if set to <code>true</code>, the tab container will assume the height of the largest tab. By default, the tab container assumes the height of the current tab.",
},
{
name = "alignVertical",
type = "string",
enum = {"top", "center", "bottom"},
default = mw.dumpObject("top"),
desc = "Vertical alignment of tab contents with respect to the tab container. Useful only alonside <code>fixedHeight</code>."
},
},
},
},
},
}
}
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",
content = "Content1",
},
{
label = "Tab2",
content = "Content2"
},
},
{
tabOptions = {
stretch = true,
}
},
},
},
{
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"
}
},
{
default = 2,
align = "center",
tabOptions = {
position = "bottom",
},
}
}
},
{
desc = "Tabs display even for a single tab unless <code>collapse</code> is set to true.",
args = {
{{ label = "Single Tab", content = "Content" }}
}
},
{
args = {
{{ label = "Single Tab", content = "Content" }},
{
tabOptions = {
collapse = true
}
},
}
},
{
desc = "<code>fixedContentWidth</code> and <code>fixedContentHeight</code> determine how the overall tab container is sized.",
args = {
{
{ label = "Small Tab", content = "meep" },
{ label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep" },
{ label = "Tall tab", content = "m\ne\ne\ne\ne\np" },
},
},
},
{
args = {
{
{ label = "Small Tab", content = "meep" },
{ label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep" },
{ label = "Tall tab", content = "m\ne\ne\ne\ne\np" },
},
{
contentOptions = {
fixedWidth = true,
},
},
},
},
{
args = {
{
{ label = "Small Tab", content = "meep" },
{ label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeep" },
{ label = "Tall tab", content = "m\ne\ne\ne\ne\np" },
},
{
contentOptions = {
fixedHeight = true,
},
},
},
},
{
args = {
{
{ label = "Small Tab", content = "meep" },
{ label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep" },
{ label = "Tall tab", content = "m\ne\ne\ne\ne\np" },
},
{
contentOptions = {
fixedWidth = true,
fixedHeight = true,
alignVertical = "center",
},
},
},
},
{
args = {
{
{ label = "Small Tab", content = "meep" },
{ label = "Wide Tab", content = "meeeeeeeeeeeeeeeeeeeeeeeeeeep" },
{ label = "Tall tab", content = "m\ne\ne\ne\ne\np" },
},
{
contentOptions = {
fixedWidth = 80,
fixedHeight = 80,
alignVertical = "center",
},
},
},
},
{
desc = "When images are used as tab labels, the label alignment options can be useful.",
args = {
{
{ label = "[[File:ST Engine Icon.png|link=]]", content = "Engines" },
{ label = "[[File:ST Passenger Car Icon.png|link=]]", content = "Passenger Cars" },
},
{
labelOptions = {
alignVertical = "bottom",
},
},
},
},
},
},
}
return p