Module:Sandbox/Shanecrowley/NestedBoxes
Description
Renders a series of nested boxes, one per component, with each component's label placed inside its own box.
Usage
Currently invoked directly, without a template:
{{#invoke:Sandbox/Shanecrowley/NestedBoxes|main|Outside|Between|Inside}}
Parameters
1, 2, 3, ...- Component labels, listed from outermost to innermost. At least one is required.
Example
Apps
Shell
Kernel
Hardware
-- Module:NestedBoxes
--
-- Renders a series of nested boxes, one per component, with each component's
-- label placed inside its own box so it never overlaps a border or a nested
-- box.
local p = {}
local BOX_PADDING = '0.6em'
local LABEL_GAP = '0.5em'
local BORDER = '1.5px solid currentColor'
local FONT_FAMILY = "'Ubuntu Sans', sans-serif"
local function getLabels( frame )
local origArgs = frame.args
local parent = frame:getParent()
if parent then
for key, value in pairs( parent.args ) do
if origArgs[ key ] == nil then
origArgs[ key ] = value
end
end
end
local labels = {}
local index = 1
while origArgs[ index ] and origArgs[ index ] ~= '' do
table.insert( labels, origArgs[ index ] )
index = index + 1
end
return labels
end
function p.main( frame )
local labels = getLabels( frame )
if #labels == 0 then
return '<strong class="error">Nested boxes: no component names given.</strong>'
end
local wrapper = mw.html.create( 'div' )
:css( 'display', 'inline-flex' )
:css( 'font-family', FONT_FAMILY )
local container = wrapper
for index, label in ipairs( labels ) do
local isInnermost = index == #labels
local box = container:tag( 'div' )
:css( 'display', 'flex' )
:css( 'flex-direction', 'column' )
:css( 'align-items', 'center' )
:css( 'padding', BOX_PADDING )
:css( 'border', BORDER )
:css( 'border-radius', '4px' )
local labelSpan = box:tag( 'span' )
:css( 'font-weight', 'bold' )
:css( 'white-space', 'nowrap' )
:wikitext( label )
if not isInnermost then
labelSpan:css( 'margin-bottom', LABEL_GAP )
end
container = box
end
return tostring( wrapper )
end
return p