Jump to content
Toggle menu
  • 1 articles
  • 7 files
  • 3 users
  • 102 edits
Shroudforge
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Revision as of 00:16, 27 May 2026 by starcitizen>Alistair3149 (Sync from Git (f7988cd) (via create-page on MediaWiki MCP Server))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Module documentation
<details class="t-mbox t-mbox--notice navigation-not-searchable noexcerpt t-dependencies" open="no"><summary class="t-mbox__header">Technical detailswiki-tools · uses 2</summary>
Source
Synced with wiki-tools on GitHub
Used by
Unavailable: looking up the pages that use it failed on this render. Purge the page to retry.
Uses
Requires1
Styles1
</details>
{{#seo:

|type = website |description = Module:ButtonLua is a template page used on the Star Citizen Wiki. Templates are pages that are embedded (transcluded) into other pages to allow for the repetition of information. |site_name = Star Citizen Wiki |locale = en-gb }}

Renders a Codex button as a link: a fake-button <span> wrapping a wikilink or external link, with optional icon, action, weight, and size variants.

Required by Module:CardLua, Module:Mainpage/Community, Module:Mainpage/Editing, Module:Entity/Infobox, Module:Company, and Module:Documentation; not invoked from templates.

For module editors

API

p.render(props) returns an HTML string with <templatestyles> for Module:ButtonLua/styles.css included.

Field Type Required Default Description
label string Yes Button text; becomes the aria-label when iconOnly is set.
link string one of link/url Wiki page, rendered as [[link|…]].
url string one of link/url External URL, rendered as [url …].
action string No default default, progressive, or destructive.
weight string No normal normal, primary, or quiet (no fill until hover).
size string No medium small, medium, or large.
icon string No Icon file name. MediaWiki disallows <img> inside <a>, so it renders as a currentColor mask instead of an <img>.
iconOnly boolean No false Hide the label; requires icon.
disabled boolean No false Disabled visual style.
class string No Extra CSS class(es) on the button.

p.main(frame) is the #invoke entry point, reading arguments via Module:Arguments.

Gotchas

  • render errors only when both link and url are absent; passing both is not rejected and renders two separate links (wikilink then external link) concatenated in the same span.
  • Codex exposes only small and medium icon sizes: a size = 'large' button still gets a medium icon.
  • The icon is a CSS mask stashed as a custom property (--t-button-icon-url) and consumed bare in styles.css, because the sanitizer rejects url(var()) inline but allows image-set() and a bare var().

Styles

A brand button opts in with class = 't-button--branded t-button--<brand>'; the brand block sets --t-button-ground (and color), and hover/active shades derive from it via color-mix. Module:ButtonLua/styles.css declares wiki-api, rsi, galactapedia/starmap (shared, same mark), verseguide, scmdb, patreon, kofi, and discord; a consumer can declare its own brand block in its own stylesheet instead of adding one here.


require('strict')

--- Lua interface for building a button.
--- This module uses Codex Button directly because the styles are already loaded in Citizen.

--- @class ButtonProps
--- @field label string
--- @field link string
--- @field url string
--- @field action ButtonAction
--- @field weight ButtonWeight
--- @field size ButtonSize
--- @field disabled boolean @default false
--- @field icon string
--- @field iconOnly boolean @default false
--- @field class string @default nil

--- @alias ButtonAction 'default' | 'progressive' | 'destructive' @default 'default'
--- @alias ButtonWeight 'normal' | 'primary' @default 'normal'
--- @alias ButtonSize 'small' | 'medium' | 'large' @default 'medium'

local p = {}

--- @param props ButtonProps
local function normalizeProps(props)
	props.action = props.action or 'default'
	props.weight = props.weight or 'normal'
	props.size = props.size or 'medium'
	props.iconOnly = props.iconOnly or false
end

--- Get the icon src for the button
---
--- @param icon string
--- @return string
local function getIconSrc(icon)
	return mw.getCurrentFrame():callParserFunction('filepath', {
		icon,
		'nowiki',
	})
end

--- @param props ButtonProps
--- @return string
local function getButtonWikitext(props)
	local html = mw.html.create('span')
	local isIconOnly = props.iconOnly and props.icon

	html:addClass('t-button')
		:addClass('cdx-button')
		:addClass('cdx-button--fake-button')
		:addClass('cdx-button--fake-button' .. (props.disabled and '--disabled' or '--enabled'))
		:addClass('cdx-button--action-' .. props.action)
		:addClass('cdx-button--weight-' .. props.weight)
		:addClass('cdx-button--size-' .. props.size)
		:addClass(props.class)

	-- HACK: Since MW does not allow <img> within <a> tags,
	-- we inject the icon as a background image instead.
	if props.icon then
		-- CdxButton only supports small and medium icons, so we need to map the size
		local iconSize = props.size == 'small' and 'small' or 'medium'

		html:tag('span')
			:addClass('cdx-icon')
			:addClass('cdx-icon--' .. iconSize)
			:cssText('--t-button-icon-url: "' .. getIconSrc(props.icon) .. '";')
			:done()
	end

	if not isIconOnly then
		html:wikitext(props.label)
	else
		html:attr('aria-label', props.label)
		html:addClass('cdx-button--icon-only')
	end

	return tostring(html)
end

--- @param props ButtonProps
--- @return string
function p.render(props)
	normalizeProps(props)

	if not props.link and not props.url then
		error('No link or URL provided')
	end

	local root = mw.html.create('span')

	root:addClass('t-button'):addClass('plainlinks') -- Remove external link icon

	local buttonWikitext = getButtonWikitext(props)

	if props.link then
		root:wikitext(string.format('[[%s|%s]]', props.link, buttonWikitext))
	end

	if props.url then
		root:wikitext(string.format('[%s %s]', props.url, buttonWikitext))
	end

	return mw.getCurrentFrame():extensionTag({
		name = 'templatestyles',
		args = { src = 'Module:ButtonLua/styles.css' },
	}) .. tostring(root)
end

--- Wikitext entry point for the module
---
--- @param frame mw.frame
--- @return string
function p.main(frame)
	local getArgs = require('Module:Arguments').getArgs
	return p.render(getArgs(frame))
end

return p