Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
80bbf9f
link widget to widget3
ElectricalBoy May 11, 2026
d287fe0
extract HtmlProps type
ElectricalBoy May 11, 2026
75364b5
copytoclipboard widget to widget3
ElectricalBoy May 11, 2026
34a560d
button to widget3
ElectricalBoy May 11, 2026
3de7e05
dialog to widget3
ElectricalBoy May 11, 2026
4fe5fe4
label to widget3
ElectricalBoy May 11, 2026
5ea20ae
slider to widget3
ElectricalBoy May 11, 2026
125ad9f
carousel to widget3
ElectricalBoy May 11, 2026
271fff9
update type
ElectricalBoy May 11, 2026
a3a274e
box to widget3
ElectricalBoy May 11, 2026
6b9c7fd
dropdown item to widget3
ElectricalBoy May 11, 2026
1a24947
dropdown container to widget3
ElectricalBoy May 11, 2026
9c02199
fontawesome icon to widget3
ElectricalBoy May 11, 2026
516ade0
image widget to widget3
ElectricalBoy May 11, 2026
5354d14
access modifier
ElectricalBoy May 11, 2026
8a99166
fix type definition
ElectricalBoy May 11, 2026
bef77c2
type casting
ElectricalBoy May 11, 2026
816ca09
fix type annotation
ElectricalBoy May 11, 2026
a8b4646
datatable to widget3
ElectricalBoy May 11, 2026
2c031fc
collapsible chevron toggle to widget3
ElectricalBoy May 11, 2026
92c4eb2
collapsible toggle to widget3
ElectricalBoy May 11, 2026
45f3c3c
collapsible to widget3
ElectricalBoy May 11, 2026
86fbe8e
rename html props type
ElectricalBoy May 11, 2026
31cf310
correctly pass props
ElectricalBoy May 11, 2026
b872aad
slightly better
ElectricalBoy May 11, 2026
fd2902a
fix dropdown
ElectricalBoy May 11, 2026
6759b65
fix test
ElectricalBoy May 11, 2026
2d6e031
kick class anno
ElectricalBoy May 11, 2026
262e001
revert rendering in test
ElectricalBoy May 11, 2026
82af789
attempt 2
ElectricalBoy May 11, 2026
ebf8fa3
cast non-nil
ElectricalBoy May 11, 2026
bc96e74
attempt 3
ElectricalBoy May 11, 2026
5b5a950
suggestion from feedback
ElectricalBoy May 11, 2026
a87bcea
adjust access
ElectricalBoy May 11, 2026
538f3c2
fix link widget misbehaving
ElectricalBoy May 11, 2026
d171364
restore widget2 version of button
ElectricalBoy May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lua/definitions/mw.lua
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ function mw.html:tag(tagName, args) end
---@param name string
---@param value string|number|nil
---@return self
---@overload fun(self, param: {[string]: string})
---@overload fun(self, param: {[string]: string|number|nil})
function mw.html:attr(name, value) end

---Get the value of a html attribute previously set using html:attr() with the given name.
Expand Down
13 changes: 11 additions & 2 deletions lua/spec/infobox_shop_merch_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ local ShopMerch = require('Module:Widget/Infobox/ShopMerch')
local function render(args)
local widget = ShopMerch{args = args}
local rendered = widget:render()
return rendered and mw.text.jsonEncode(rendered) or nil
if not rendered then
return
end
for i in ipairs(rendered) do
rendered[i] = tostring(rendered[i])
end
return mw.text.jsonEncode(rendered)
end

describe('Infobox/ShopMerch', function()
Expand Down Expand Up @@ -37,12 +43,14 @@ describe('Infobox/ShopMerch', function()
it('uses default shop url when shoplink=true', function()
local output = render{shoplink = 'true'}
assert.is_not_nil(output)
---@cast output -nil
assert.is_truthy(output:find('https://links.liquipedia.net/tlstore', 1, true))
end)

it('strips leading slashes from slugs', function()
local output = render{shoplink = '/test'}
assert.is_not_nil(output)
---@cast output -nil
assert.is_truthy(output:find('https://links.liquipedia.net/test', 1, true))

local output2 = render{shoplink = '///test'}
Expand All @@ -61,6 +69,7 @@ describe('Infobox/ShopMerch', function()
-- 'ö' is 2 bytes in Lua, but %C3%B6 is 6 chars in URL
local output = render{shoplink = 'töst'}
assert.is_not_nil(output)
---@cast output -nil
assert.is_truthy(output:find('https://links.liquipedia.net/t%C3%B6st', 1, true))
end)

Expand Down Expand Up @@ -89,4 +98,4 @@ describe('Infobox/ShopMerch', function()
local expanding_slug = string.rep('ö', 500)
assert.has_error(function() render{shoplink = expanding_slug} end)
end)
end)
end)
41 changes: 18 additions & 23 deletions lua/wikis/commons/Widget/Basic/Box.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
local Lua = require('Module:Lua')

local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')

local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Widget = Lua.import('Module:Widget')
local Component = Lua.import('Module:Widget/Component')
local Html = Lua.import('Module:Widget/Html')

---@class BoxProps
---@field children Renderable[]|Renderable
Expand All @@ -22,36 +21,32 @@ local Widget = Lua.import('Module:Widget')
---@field width string?
---@field height string?

---@class Box: Widget
---@operator call(BoxProps): Box
---@field props BoxProps
local Box = Class.new(Widget)

---@return Widget|Renderable
function Box:render()
local children = self.props.children
---@param props BoxProps
---@return Renderable
local function Box(props)
local children = props.children
if not Array.isArray(children) then
return self.props.children
return props.children
end
---@cast children -Renderable
---@cast children Renderable[]

return HtmlWidgets.Div{
css = {['max-width'] = self.props.maxWidth},
return Html.Div{
css = {['max-width'] = props.maxWidth},
children = Array.map(children, function(child)
return HtmlWidgets.Div{
return Html.Div{
classes = {'template-box'},
css = {
['padding-left'] = self.props.paddingLeft,
['padding-bottom'] = self.props.paddingBottom,
['padding-right'] = self.props.paddingRight,
width = self.props.width,
height = self.props.height,
overflow = self.props.height and 'hidden' or nil,
['padding-left'] = props.paddingLeft,
['padding-bottom'] = props.paddingBottom,
['padding-right'] = props.paddingRight,
width = props.width,
height = props.height,
overflow = props.height and 'hidden' or nil,
},
children = child,
}
end)
}
end

return Box
return Component.component(Box)
38 changes: 16 additions & 22 deletions lua/wikis/commons/Widget/Basic/Carousel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@
local Lua = require('Module:Lua')

local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local Table = Lua.import('Module:Table')

local Widget = Lua.import('Module:Widget')
local Component = Lua.import('Module:Widget/Component')
local IconWidget = Lua.import('Module:Widget/Image/Icon/Fontawesome')
local Button = Lua.import('Module:Widget/Basic/Button')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Div = HtmlWidgets.Div
local Span = HtmlWidgets.Span
local Html = Lua.import('Module:Widget/Html')
local Div = Html.Div
local Span = Html.Span

---@class CarouselWidgetParameters
---@field children Renderable[]
Expand All @@ -25,34 +24,29 @@ local Span = HtmlWidgets.Span
---@field classes string[]?
---@field css table?

---@class CarouselWidget: Widget
---@operator call(CarouselWidgetParameters): CarouselWidget
---@field props CarouselWidgetParameters
local Carousel = Class.new(Widget)
Carousel.defaultProps = {
local defaultProps = {
itemWidth = '200px',
gap = '0.5rem',
classes = {},
css = {},
}

---@return Widget
function Carousel:render()
assert(self.props.children, 'Carousel: children is required')
assert(Array.isArray(self.props.children), 'Carousel: children must be an array')
---@param props CarouselWidgetParameters
---@return HtmlNode
local function Carousel(props)
assert(props.children, 'Carousel: children is required')
assert(Array.isArray(props.children), 'Carousel: children must be an array')

local carouselCss = Table.mergeInto({
gap = self.props.gap,
}, self.props.css)
gap = props.gap,
}, props.css)

local carouselContent = Div{
classes = {'carousel-content'},
css = carouselCss,
children = Array.map(self.props.children, function(child)
children = Array.map(props.children, function(child)
return Div{
classes = {'carousel-item'},
css = {
width = self.props.itemWidth,
width = props.itemWidth,
},
children = {child},
}
Expand Down Expand Up @@ -87,7 +81,7 @@ function Carousel:render()
local rightFade = Div{classes = {'carousel-fade', 'carousel-fade--right'}}

return Div{
classes = Array.extend({'carousel'}, self.props.classes),
classes = Array.extendWith({'carousel'}, props.classes),
children = {
leftButton,
rightButton,
Expand All @@ -98,4 +92,4 @@ function Carousel:render()
}
end

return Carousel
return Component.component(Carousel, defaultProps)
25 changes: 9 additions & 16 deletions lua/wikis/commons/Widget/Basic/CopyToClipboard.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,32 @@

local Lua = require('Module:Lua')

local Class = Lua.import('Module:Class')

local Widget = Lua.import('Module:Widget')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Span = HtmlWidgets.Span
local Component = Lua.import('Module:Widget/Component')
local Html = Lua.import('Module:Widget/Html')
local Span = Html.Span

---@class CopyToClipboardProps
---@field children Renderable|Renderable[]?
---@field textToCopy string? text to be copied to clipboard
---@field successText string?

---@class CopyToClipboardWidget: Widget
---@operator call(CopyToClipboardProps): CopyToClipboardWidget
---@field props CopyToClipboardProps
local CopyToClipboard = Class.new(Widget)

---@return Widget
function CopyToClipboard:render()
local props = self.props
---@param props CopyToClipboardProps
---@return HtmlNode
local function CopyToClipboard(props)
return Span{
classes = {'copy-to-clipboard'},
attributes = {['data-copied-text'] = props.successText},
children = {
Span{
classes = {'copy-this'},
children = self.props.textToCopy,
children = props.textToCopy,
},
Span{
classes = {'see-this'},
children = self.props.children,
children = props.children,
}
}
}
end

return CopyToClipboard
return Component.component(CopyToClipboard)
44 changes: 21 additions & 23 deletions lua/wikis/commons/Widget/Basic/DataTable.lua
Comment thread
ElectricalBoy marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,37 @@

local Lua = require('Module:Lua')

local Class = Lua.import('Module:Class')
local Logic = Lua.import('Module:Logic')

local Widget = Lua.import('Module:Widget')
local Component = Lua.import('Module:Widget/Component')
local WidgetUtil = Lua.import('Module:Widget/Util')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Div = HtmlWidgets.Div
local Table = HtmlWidgets.Table
local Html = Lua.import('Module:Widget/Html')
local Div = Html.Div
local Table = Html.Table

---@class WidgetDataTable: Widget
local DataTable = Class.new(Widget)
DataTable.defaultProps = {
classes = {},
wrapperClasses = {},
sortable = false,
}
---@class DataTableProps: HtmlNodeProps
---@field sortable boolean?
---@field tableCss? table<string, string|number?>
---@field tableAttributes? table<string, string|number?>
---@field wrapperClasses? string[]

---@return Widget
function DataTable:render()
local isSortable = Logic.readBool(self.props.sortable)
---@param props DataTableProps
---@return HtmlNode
local function DataTable(props)
local isSortable = Logic.readBool(props.sortable)
return Div{
children = {
Table{
children = self.props.children,
classes = WidgetUtil.collect('wikitable', isSortable and 'sortable' or nil, self.props.classes),
css = self.props.tableCss,
attributes = self.props.tableAttributes,
children = props.children,
classes = WidgetUtil.collect('wikitable', isSortable and 'sortable' or nil, props.classes),
css = props.tableCss,
attributes = props.tableAttributes,
},
},
classes = WidgetUtil.collect('table-responsive', self.props.wrapperClasses),
attributes = self.props.attributes,
css = self.props.css,
classes = WidgetUtil.collect('table-responsive', props.wrapperClasses),
attributes = props.attributes,
css = props.css,
}
end

return DataTable
return Component.component(DataTable)
20 changes: 7 additions & 13 deletions lua/wikis/commons/Widget/Basic/Dialog.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,21 @@
local Lua = require('Module:Lua')

local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local Logic = Lua.import('Module:Logic')

local Widget = Lua.import('Module:Widget')
local HtmlWidgets = Lua.import('Module:Widget/Html/All')
local Div = HtmlWidgets.Div
local Component = Lua.import('Module:Widget/Component')
local Html = Lua.import('Module:Widget/Html')
local Div = Html.Div

---@class DialogWidgetProps
---@field dialogClasses? string[]
---@field title? Renderable|Renderable[]
---@field trigger? Renderable|Renderable[]
---@field children? Renderable|Renderable[]

---@class DialogWidget: Widget
---@operator call(DialogWidgetProps): DialogWidget
---@field props DialogWidgetProps
local DialogWidget = Class.new(Widget)

---@return Widget?
function DialogWidget:render()
local props = self.props
---@param props DialogWidgetProps
---@return HtmlNode?
local function DialogWidget(props)
if Logic.isEmpty(props.title) or Logic.isEmpty(props.trigger) or Logic.isEmpty(props.children) then
return
end
Expand Down Expand Up @@ -57,4 +51,4 @@ function DialogWidget:render()
}
end

return DialogWidget
return Component.component(DialogWidget)
Loading
Loading