fix(core): remove outdated plugin example code

This commit is contained in:
Prad Nukala
2026-07-13 12:18:17 -04:00
parent b56b724b22
commit fa8e3459f7
6 changed files with 0 additions and 333 deletions
-43
View File
@@ -1,43 +0,0 @@
--!nonstrict
-- Declarative bar widget: renders a ui.* tree with barWidget.render() instead
-- of the imperative setText/setGlyph patches (hello.luau). The tree replaces
-- the built-in glyph/text row. Pointer controls (ui.button, ui.toggle, …) work
-- inline and consume their own clicks; the widget-level onClick still fires on
-- the rest of the capsule. Keyboard controls (ui.input/ui.select/ui.scroll)
-- are not available in the bar. The capsule clips to bar thickness, so keep
-- the tree one control tall.
local clicks = 0
local tick = noctalia.state.get("tick") or 0
local function render()
-- Stack along the bar: a row in a horizontal bar, a column in a side bar.
local container = barWidget.isVertical() and ui.column or ui.row
barWidget.render(container({ gap = 6, align = "center" }, {
ui.glyph({ name = "sparkles", size = 14, color = "secondary" }),
-- A filled rounded badge — something the imperative setText/setGlyph API
-- cannot draw. "secondary/0.25" is the secondary role at 25% alpha, so the
-- pill stays theme-aware while the text on it remains fully opaque.
ui.row({ fill = "secondary/0.25", radius = 8, paddingH = 6, align = "center" }, {
ui.label({ text = tostring(tick), color = "secondary", fontWeight = "bold" }),
}),
ui.button({ glyph = "plus", glyphSize = 12, variant = "ghost", onClick = "onPlus" }),
}))
end
-- Live updates from the plugin's background service (ticker.luau).
noctalia.state.watch("tick", function(value)
tick = value
render()
end)
function update()
noctalia.setUpdateInterval(1000)
render()
end
-- Inner-control callback: fires only when the ui.button is clicked.
function onPlus()
clicks += 1
noctalia.notify(noctalia.tr("title"), noctalia.trp("clicks", clicks))
end
-77
View File
@@ -1,77 +0,0 @@
--!nonstrict
-- Launcher provider for the example plugin.
--
-- Type `/ex` in the launcher. The top level lists categories; pressing Enter on
-- one calls launcher.setQuery() to rewrite the input (e.g. `/ex fruits `) and
-- drill into it WITHOUT closing the launcher. Pressing Enter on a leaf item
-- copies it and lets the launcher close normally.
--
-- launcher.setQuery() takes effect when called from a handler while the launcher
-- is open. Called synchronously from onActivate it keeps the panel open and
-- rewrites the input instead of closing — the basis for autocomplete / drill-in.
local PREFIX = "/ex"
local CATEGORIES = {
fruits = { "Apple", "Apricot", "Banana", "Cherry" },
animals = { "Aardvark", "Bear", "Cat", "Dolphin" },
colors = { "Amber", "Azure", "Crimson", "Teal" },
}
-- Top level: one row per category. Activating a row drills into it.
local function categoryRows()
local rows = {}
for name in CATEGORIES do
table.insert(rows, {
id = "category:" .. name,
title = name,
subtitle = "Browse " .. name .. " — press Enter to open",
glyph = "folder",
})
end
return rows
end
-- Inside a category: the items matching the text typed after the category name.
local function itemRows(category, filter)
local rows = {}
for _, item in CATEGORIES[category] do
if filter == "" or item:lower():find(filter:lower(), 1, true) then
table.insert(rows, {
id = item,
title = item,
subtitle = category .. " — press Enter to copy",
glyph = "tag",
})
end
end
if #rows == 0 then
rows[1] = { id = "", title = "No matches", subtitle = category, glyph = "mood-empty" }
end
return rows
end
-- `query` is the launcher text after the `/ex` prefix, leading space trimmed.
function onQuery(query)
local text = noctalia.string.trim(query)
local category, rest = text:match("^(%S+)%s*(.*)$")
if category and CATEGORIES[category] then
launcher.setResults(query, itemRows(category, noctalia.string.trim(rest)))
else
launcher.setResults(query, categoryRows())
end
end
function onActivate(id)
local category = id:match("^category:(.+)$")
if category then
-- Drill in: rewrite the launcher input (note the prefix and trailing space)
-- and stay open so the user can keep filtering within the category.
launcher.setQuery(PREFIX .. " " .. category .. " ")
return
end
if id ~= "" then
noctalia.copyToClipboard(id, "text/plain")
noctalia.notify("Example", id .. " copied to clipboard")
end
end
-67
View File
@@ -1,67 +0,0 @@
--!nonstrict
-- Minimal reference plugin entry: a bar widget that shows a configurable label
-- and glyph, counts clicks, and accepts IPC to change its text at runtime.
--
-- Demonstrates the capability surface:
-- barWidget.* presentation (text / glyph / tooltip)
-- barWidget.getConfig settings (seeded from the manifest; single-arg, no fallback)
-- noctalia.tr / trp translation against this plugin's translations/<lang>.json
-- noctalia.readFile filesystem, resolved relative to the plugin's own dir
-- noctalia.http async HTTP (off-thread; response delivered back as a callback)
-- noctalia.state.* shared data published by this plugin's [[service]] (ticker.luau)
-- noctalia.notify host notification
-- onIpc shell-triggered events
--
-- Drive it from the shell:
-- noctalia msg plugin noctalia/example:hello focused set "Hi there"
-- noctalia msg plugin noctalia/example:hello focused fetch "https://example.com"
local label = barWidget.getConfig("label")
local glyph = barWidget.getConfig("glyph")
local showGlyph = barWidget.getConfig("show_glyph")
local clicks = 0
local dataNote = noctalia.readFile("data.txt") or "(no data file)"
local tick = noctalia.state.get("tick") or 0
local function render()
if showGlyph then
barWidget.setGlyph(glyph)
end
barWidget.setText(label)
barWidget.setTooltip(`{noctalia.trp("clicks", clicks)}{dataNote} — service tick {tick}`)
end
-- Live updates from the plugin's background service (ticker.luau).
noctalia.state.watch("tick", function(value)
tick = value
render()
end)
-- Called on the widget's update interval. Static here, so slow the ticks right down.
function update()
noctalia.setUpdateInterval(1000)
render()
end
function onClick()
clicks += 1
noctalia.notify(noctalia.tr("title"), noctalia.trp("clicks", clicks))
render()
end
function onIpc(event, payload)
if event == "set" then
label = payload
render()
elseif event == "fetch" then
-- Async: the request runs off-thread and the callback fires when it lands.
noctalia.http({ url = payload }, function(res)
if res.ok then
noctalia.notify(noctalia.tr("title"), `HTTP {res.status}{#res.body} bytes`)
else
noctalia.notify(noctalia.tr("title"), "HTTP request failed")
end
end)
end
end
-102
View File
@@ -1,102 +0,0 @@
--!nonstrict
-- Reference [[panel]] entry — a settings-style panel of interactive controls.
--
-- Panels describe their UI declaratively, exactly like desktop widgets: build a
-- tree with the ui.* constructors and hand it to panel.render(). The host diffs
-- the tree against the previous one and updates retained native controls, so
-- rendering an unchanged tree is free.
--
-- panel.render(tree) replace the panel's UI tree
-- panel.close() ask the host to close this panel
-- panel.getConfig(key) settings (seeded from the manifest)
-- button/toggle/slider/... onClick / onChange call the plugin global of
-- that name; values arrive as string args
--
-- Layout notes:
-- * a Flex (column/row/scroll) centers its children on the cross axis by
-- default — pass align = "stretch" so controls fill the panel width.
-- * panel size is host-owned: declare width/height on the [[panel]] manifest
-- entry, so the surface is the same size on every open.
--
-- Stateful controls follow a controlled/uncontrolled split:
-- * toggle / slider / select are value-driven — pass the current value each
-- render; the callback reports the user's new value.
-- * input is uncontrolled — `value` seeds the field once; the host owns the
-- text buffer afterward, so re-rendering never clobbers what the user typed.
-- Observe edits via onChange (live) / onSubmit (Enter).
local enabled = true
local volume = 50
local greeting = ""
local themeIndex = 0
local themes = { "Dark", "Light", "System" }
-- A labelled section: a heading above a control. ui.column stretches children to
-- the panel width by default, so the control fills the row.
local function section(title, control)
return ui.column({ gap = 8 }, {
ui.label({ text = title, fontWeight = "medium", color = "on_surface_variant" }),
control,
})
end
local function render()
-- The panel surface already insets its content (Style::panelPadding), so this
-- adds gaps between rows, not its own outer padding.
panel.render(ui.column({ flexGrow = 1, gap = 16 }, {
-- Header: title on the left, close button pinned to the top right —
-- matching the built-in panels (no divider rule).
ui.row({ align = "center", justify = "space_between", gap = 8 }, {
ui.label({ text = "Example Panel", fontSize = 16, fontWeight = "bold", color = "on_surface", flexGrow = 1 }),
ui.button({ glyph = "close", onClick = "onCloseClicked" }),
}),
-- Body: a scrollable stack of settings.
ui.scroll({ flexGrow = 1, gap = 16 }, {
section("Notifications", ui.row({ gap = 12, align = "center" }, {
ui.toggle({ checked = enabled, onChange = "onToggle" }),
ui.label({ text = enabled and "Enabled" or "Disabled", flexGrow = 1 }),
})),
section(`Volume — {volume}%`, ui.slider({
min = 0, max = 100, step = 1, value = volume, onChange = "onVolume",
})),
section("Your name (press Enter to greet)", ui.column({ gap = 8 }, {
ui.input({ key = "name", placeholder = "Type a name…", onSubmit = "onNameSubmit" }),
ui.label({ text = greeting, color = "primary" }),
})),
section("Theme", ui.select({ options = themes, selectedIndex = themeIndex, onChange = "onTheme" })),
}),
}))
end
function onOpen(_context)
render()
end
function onToggle(value)
enabled = value == "true"
render()
end
function onVolume(value)
volume = math.floor(tonumber(value) or 0)
render()
end
function onNameSubmit(value)
greeting = value ~= "" and `Hello, {value}!` or ""
noctalia.notify("Example Panel", greeting)
render()
end
function onTheme(index, _text)
themeIndex = tonumber(index) or 0
render()
end
function onCloseClicked()
panel.close()
end
-29
View File
@@ -1,29 +0,0 @@
--!nonstrict
-- Control-center [[shortcut]] entry: a quick-toggle tile.
--
-- shortcut.setLabel(text)
-- shortcut.setIcon(on [, off]) -- one glyph, or distinct on/off glyphs
-- shortcut.setActive(bool) -- toggle/highlight state
-- shortcut.setEnabled(bool)
-- onClick() / onRightClick()
--
-- State is shared via noctalia.state, so the plugin's other entries (widget,
-- service) could react to the toggle.
local on = noctalia.state.get("toggle") == true
local function render()
shortcut.setLabel(if on then "Example On" else "Example Off")
shortcut.setIcon("puzzle")
shortcut.setActive(on)
shortcut.setEnabled(true)
end
-- Initial state at load.
render()
function onClick()
on = not on
noctalia.state.set("toggle", on)
render()
end
-15
View File
@@ -1,15 +0,0 @@
--!nonstrict
-- Headless [[service]] entry: runs in the background with no UI, ticking once a
-- second and publishing an incrementing counter to the plugin's shared state.
-- Any of this plugin's entries (the hello widget) can read it with
-- noctalia.state.get / noctalia.state.watch.
local count = 0
-- Drive this service's own tick rate
noctalia.setUpdateInterval(1000)
function update()
count += 1
noctalia.state.set("tick", count)
end