Module:MBNavbox
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