Jump to content
Search

The new Ubuntu Wiki is live. Legacy content may be unavailable and page links may have changed. Read the announcement on Discourse.

Module:Sandbox/Shanecrowley/NestedBoxes

From Ubuntu Wiki

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