Module:MBNavbox

From MB Wiki
Revision as of 02:41, 19 December 2025 by Ais (talk | contribs) (Created page with "local p = {} function p.main(frame) local args = frame:getParent().args -- Color values extracted from your CSS local colors = { -- Light theme (default) theme_border_color = '#a1e9dc', theme_accent_label_color = '#ffffff', teal_600 = '#2c7a7b', teal_800 = '#234e52', teal_050 = '#e6fffa', teal_100 = '#b2f5ea', teal_200 = '#81e6d9', teal_700 = '#285e61', teal_900 = '#1d4044',...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

local p = {}

function p.main(frame)
    local args = frame:getParent().args
    
    -- Color values extracted from your CSS
    local colors = {
        -- Light theme (default)
        theme_border_color = '#a1e9dc',
        theme_accent_label_color = '#ffffff',
        teal_600 = '#2c7a7b',
        teal_800 = '#234e52',
        teal_050 = '#e6fffa',
        teal_100 = '#b2f5ea',
        teal_200 = '#81e6d9',
        teal_700 = '#285e61',
        teal_900 = '#1d4044',
        theme_page_background_color = '#f5fdfb',
        theme_page_background_color_secondary = '#e8f5f3',
        theme_link_color = '#007d7a',
        theme_link_color_hover = '#005652',
        theme_accent_color = '#38b2ac',
        gray_300 = '#e2e8f0',
        
        -- Dark theme colors for reference (can be added if needed)
        dark_theme_border_color = '#4d6872',
        dark_teal_700 = '#285e61',
        dark_teal_900 = '#1d4044',
        dark_card_bg_main = '#2a363d',
        dark_card_bg_sub = '#3a464d',
        dark_teal_200 = '#81e6d9',
        dark_teal_100 = '#b2f5ea'
    }
    
    -- Create main container
    local navbox = mw.html.create('table')
        :addClass('navbox')
        :css('width', '100%')
        :css('border-spacing', '0')
        :css('border', '2px solid ' .. colors.theme_border_color)
        :css('border-radius', '8px')
        :css('background', colors.theme_page_background_color_secondary)
        :css('margin', '16px 0')
        :css('overflow', 'hidden')
        :css('box-shadow', '0 1px 3px rgba(0, 0, 0, 0.12)')
        :attr('role', 'navigation')
        :attr('aria-labelledby', (args.name or 'navbox') .. '-title')
    
    -- Add custom class if provided
    if args.class then
        navbox:addClass(args.class)
    end
    
    -- Title row
    if args.title then
        local titleRow = mw.html.create('tr')
        
        local titleCell = mw.html.create('th')
            :attr('colspan', '2')
            :attr('id', (args.name or 'navbox') .. '-title')
            :attr('scope', 'col')
            :css('text-align', 'center')
            :css('font-weight', '700')
            :css('font-size', '18px')
            :css('padding', '8px 12px')
            :css('background', 'linear-gradient(135deg, ' .. colors.teal_600 .. ' 0%, ' .. colors.teal_800 .. ' 100%)')
            :css('color', colors.theme_accent_label_color)
            :css('border-bottom', '1px solid ' .. colors.theme_border_color)
            :css('text-shadow', '0 1px 2px rgba(0,0,0,0.2)')
            :css('letter-spacing', '0.5px')
            :wikitext(args.title)
        
        titleRow:node(titleCell)
        navbox:node(titleRow)
    end
    
    -- Build table body
    local tbody = mw.html.create('tbody')
    
    -- Process groups and lists
    local hasContent = false
    
    -- Method 1: Check for numbered groups/lists
    for i = 1, 10 do
        if args['group' .. i] or args['list' .. i] then
            hasContent = true
            
            -- Group row if present
            if args['group' .. i] then
                local groupRow = mw.html.create('tr')
                    :css('background', colors.teal_050)
                    :css('border-bottom', '1px solid ' .. colors.theme_border_color .. '80') -- 80 = 50% opacity
                
                local groupCell = mw.html.create('th')
                    :attr('scope', 'row')
                    :css('text-align', 'center')
                    :css('vertical-align', 'top')
                    :css('width', '1%')
                    :css('white-space', 'nowrap')
                    :css('padding', '4px 16px')
                    :css('color', colors.teal_800)
                    :css('font-weight', '600')
                    :css('font-size', '14px')
                    :css('text-transform', 'uppercase')
                    :css('letter-spacing', '0.5px')
                    :css('border-right', '1px solid ' .. colors.theme_border_color .. '80')
                    :wikitext(args['group' .. i])
                
                groupRow:node(groupCell)
                tbody:node(groupRow)
            end
            
            -- List row
            if args['list' .. i] then
                local listRow = mw.html.create('tr')
                
                local listCell = mw.html.create('td')
                    :css('padding', '8px 12px')
                    :css('vertical-align', 'top')
                    :css('background', colors.theme_page_background_color)
                    :css('color', '#1a2a2a') -- From your --theme-page-text-color
                    :css('line-height', '1.6')
                
                -- Set colspan if no group for this item
                if not args['group' .. i] then
                    listCell:attr('colspan', '2')
                end
                
                -- Process list content with proper styling
                local content = args['list' .. i]
                
                -- Check if content starts with asterisk (list items)
                if content:match('^%*') then
                    -- Wrap in a div with hlist class styling
                    local listDiv = mw.html.create('div')
                        :css('margin', '0')
                    
                    -- Process each line
                    for line in content:gmatch('[^\n]+') do
                        if line:match('^%s*%*') then
                            -- It's a list item
                            local listItem = mw.html.create('div')
                                :css('margin', '4px 0')
                                :css('padding-left', '1.2em')
                                :css('position', 'relative')
                            
                            -- Add bullet
                            local bullet = mw.html.create('span')
                                :css('position', 'absolute')
                                :css('left', '0')
                                :css('top', '0')
                                :css('color', colors.teal_600)
                                :wikitext('• ')
                            
                            -- Add content
                            local itemContent = mw.html.create('span')
                            
                            -- Process bold text
                            local processedLine = line:gsub('%*%*%*([^*]+)%-%*%*%*', function(text)
                                return '<span style="font-weight: bold; font-style: italic;">' .. text .. '</span>'
                            end)
                            processedLine = processedLine:gsub('%*%*([^*]+)%*%*', function(text)
                                return '<strong>' .. text .. '</strong>'
                            end)
                            processedLine = processedLine:gsub('%*([^*]+)%*', function(text)
                                return '<em>' .. text .. '</em>'
                            end)
                            
                            -- Remove leading asterisk and spaces
                            processedLine = processedLine:gsub('^%s*%*%s*', '')
                            
                            itemContent:wikitext(processedLine)
                            
                            listItem:node(bullet)
                            listItem:node(itemContent)
                            listDiv:node(listItem)
                        else
                            -- Regular text line
                            local textLine = mw.html.create('div')
                                :css('margin', '4px 0')
                                :wikitext(line)
                            listDiv:node(textLine)
                        end
                    end
                    
                    listCell:node(listDiv)
                else
                    -- Regular content (not a list)
                    local contentDiv = mw.html.create('div')
                    
                    -- Process any bold/italic markup in regular content
                    local processedContent = content
                    processedContent = processedContent:gsub('%*%*%*([^*]+)%-%*%*%*', function(text)
                        return '<span style="font-weight: bold; font-style: italic;">' .. text .. '</span>'
                    end)
                    processedContent = processedContent:gsub('%*%*([^*]+)%*%*', function(text)
                        return '<strong>' .. text .. '</strong>'
                    end)
                    processedContent = processedContent:gsub('%*([^*]+)%*', function(text)
                        return '<em>' .. text .. '</em>'
                    end)
                    
                    contentDiv:wikitext(processedContent)
                    listCell:node(contentDiv)
                end
                
                -- Style links within the content
                listCell:css('word-wrap', 'break-word')
                
                listRow:node(listCell)
                tbody:node(listRow)
            end
            
            -- Add spacer row between sections if not last
            local nextHasContent = false
            for j = i + 1, 10 do
                if args['group' .. j] or args['list' .. j] then
                    nextHasContent = true
                    break
                end
            end
            
            if nextHasContent then
                local spacerRow = mw.html.create('tr')
                local spacerCell = mw.html.create('td')
                    :attr('colspan', '2')
                    :css('height', '5px')
                    :css('background', 'transparent')
                    :css('border-top', '1px dashed ' .. colors.theme_border_color .. '80')
                spacerRow:node(spacerCell)
                tbody:node(spacerRow)
            end
        end
    end
    
    -- Method 2: Check for simple content (no numbers)
    if not hasContent and args.content then
        local contentRow = mw.html.create('tr')
        local contentCell = mw.html.create('td')
            :attr('colspan', '2')
            :css('padding', '12px')
            :css('background', colors.theme_page_background_color)
            :css('line-height', '1.6')
            :wikitext(args.content)
        
        contentRow:node(contentCell)
        tbody:node(contentRow)
    end
    
    -- Add body to table
    navbox:node(tbody)
    
    -- Add link styling via JavaScript-like approach (will be applied to all links in navbox)
    local styleTag = mw.html.create('style')
        :wikitext([[
            .navbox[style*="border: 2px solid #a1e9dc"] a {
                color: ]] .. colors.theme_link_color .. [[;
                text-decoration: none;
                border-bottom: 1px dotted ]] .. colors.gray_300 .. [[;
                transition: all 0.15s ease;
            }
            .navbox[style*="border: 2px solid #a1e9dc"] a:hover {
                color: ]] .. colors.theme_link_color_hover .. [[;
                border-bottom: 2px solid ]] .. colors.theme_accent_color .. [[;
                background: ]] .. colors.teal_050 .. [[;
                border-radius: 4px;
                padding: 0 2px;
            }
            .navbox[style*="border: 2px solid #a1e9dc"] strong {
                font-weight: 700;
                color: ]] .. colors.teal_700 .. [[;
            }
            .navbox[style*="border: 2px solid #a1e9dc"] em {
                font-style: italic;
                color: ]] .. colors.teal_600 .. [[;
            }
        ]])
    
    return tostring(styleTag) .. tostring(navbox)
end

return p