Jump to content
Toggle menu
  • 12,3 E szócikkek
  • 21,5 E fájlok
  • 4 felhasználók
  • 63,9 E szerkesztések
SCWIKI
Toggle preferences menu
Toggle personal menu
Nem vagy bejelentkezve
Your IP address will be publicly visible if you make any edits.
Module documentation[view][edit][history][purge]
This documentation is transcluded from Modul:ButtonLua/doc. Changes can be proposed in the talk page.
Function list
L 25 — normalizeProps
L 36 — getIconSrc
L 45 — getButtonWikitext
L 83 — p.render
L 114 — p.main

Renders a Codex button as a link. Pass a Lua table of props and get back a fake-button link with optional icon, action, weight, and size variants.

Usage

local button = require( 'Module:ButtonLua' )

function p.main( frame )
    local args = require( 'Module:Arguments' ).getArgs( frame )

    return button.render( {
        label = 'View on Galactapedia',
        url = 'https://robertsspaceindustries.com/galactapedia',
        action = 'progressive',
        weight = 'primary',
        icon = 'Link.svg',
    } )
end

Or directly from wikitext via the main entry point:

{{#invoke:ButtonLua|main|label=Buy now|link=Aurora MR|weight=primary}}

render returns an HTML string with <templatestyles> included. One of link or url is required; the module raises an error if neither is provided.

Data Reference

Field Type Required Default Description
label string Yes Button text. Used as the aria-label when iconOnly is set.
link string Yes* Internal wiki page to link to, rendered as a wikilink.
url string Yes* External URL to link to, rendered as an external link.
action string No default Visual style: default, progressive, or destructive.
weight string No normal Visual weight: normal or primary.
size string No medium Button size: small, medium, or large.
icon string No Icon file name. Injected as a CSS background image (MediaWiki disallows <img> inside <a>).
iconOnly boolean No false Show only the icon and hide the label. Requires icon; label becomes the accessible name.
disabled boolean No false Render in a disabled style.
class string No Additional CSS class on the button.

* Provide exactly one of link or url.

Examples

Internal link button

button.render( {
    label = 'Aurora MR',
    link = 'Aurora MR',
} )

External link with icon

button.render( {
    label = 'Pledge store',
    url = 'https://robertsspaceindustries.com/pledge',
    action = 'progressive',
    weight = 'primary',
    icon = 'OcShoppingCart.svg',
} )

Icon-only button

button.render( {
    label = 'Edit',
    link = 'Special:EditPage',
    icon = 'OcPencil.svg',
    iconOnly = true,
    size = 'small',
} )

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