aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2025-08-11 16:48:24 +0530
committerAkshay Nair <phenax5@gmail.com>2025-08-11 16:48:24 +0530
commit50cee0498e5b254015e31df9010833a29c0cb2a8 (patch)
treea30638ae9feae763ca22f78bec2a1a8ea0854ba8
parent9e8abe4f466cf771a420b6c551926c5e917f7b76 (diff)
downloadnull-browser-50cee0498e5b254015e31df9010833a29c0cb2a8.tar.gz
null-browser-50cee0498e5b254015e31df9010833a29c0cb2a8.zip
Tabline ui experiments
-rw-r--r--init.lua92
-rw-r--r--lua/null-browser/extras/html.lua1
-rw-r--r--lua/null-browser/extras/statusline.lua2
-rw-r--r--lua/null-browser/extras/tabline.lua31
4 files changed, 118 insertions, 8 deletions
diff --git a/init.lua b/init.lua
index 937fdeb..d2a8e23 100644
--- a/init.lua
+++ b/init.lua
@@ -54,9 +54,99 @@ web.event.add_listener('NotificationReceived', {
end,
})
+local extra_styles = [[
+ .fancy-tabline {
+ padding: 8px;
+ }
+ .quick {
+ display: flex;
+ justify-contents: space-between;
+ gap: 8px;
+ padding: 8px 0;
+ }
+ .quick .quick-link {
+ all: unset;
+ display: block;
+ width: 100%;
+ padding: 8px;
+ border: 1px solid #999;
+ text-align: center;
+ border-radius: 6px;
+ text-decoration: none;
+ color: white;
+ }
+ .url-info {
+ background-color: rgba(255, 255, 255, 0.1);
+ font-size: 8px;
+ padding: 6px;
+ border-radius: 8px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ text-wrap: nowrap;
+ }
+ .tabs-wrapper { }
+ .tabs.vertical {
+ padding: 8px 0;
+ width: 100vw;
+ gap: 4px;
+ }
+ .tabs.vertical .tab {
+ background-color: rgba(255, 255, 255, 0.07);
+ padding: 6px 8px;
+ border-radius: 6px;
+ }
+ .tabs.vertical .tab.current {
+ background-color: rgba(255, 255, 255, 0.2);
+ }
+]]
-- Tabline
require 'null-browser.extras.tabline'.init {
- decoration = web.decorations.top,
+ decoration = web.decorations.left,
+ vertical_size = 300,
+ on_window_setup = function(win_id)
+ -- TODO: This should happen after toggle
+ web.schedule(function()
+ web.view.expose('open_url_in_view', function(args)
+ print(web.inspect(args))
+ local url = args and args.url
+ if url then web.view.set_url(url) end
+ end, { view = web.decorations.left.view() })
+ end)
+ end,
+ transform_html = function(tabs_html)
+ local html = require 'null-browser.extras.html'
+
+ local function current_url()
+ local views = web.view.list()
+ local view = views[web.view.current_index()]
+ return view and view.url or ''
+ end
+
+ local quicklinks = {
+ { icon = "λ", url = "https://ediblemonad.dev", },
+ { icon = "🦆", url = "https://duckduckgo.com", },
+ { icon = "🤮", url = "https://google.com", },
+ }
+
+ local quickhtml = {}
+ for _, link in ipairs(quicklinks) do
+ table.insert(quickhtml, html.button(
+ {
+ class = 'quick-link',
+ onclick = '_nullbrowser.rpc.open_url_in_view({url: this.dataset.href})',
+ ['data-href'] = link.url,
+ },
+ { link.icon }
+ ))
+ end
+
+ return html.div({ class = 'fancy-tabline' }, {
+ html.div({ class = 'url-info' }, { current_url() }),
+ html.div({ class = 'quick' }, quickhtml),
+ tabs_html,
+ html.style({}, { html.raw(extra_styles) }),
+ })
+ end,
}
-- Statusline
diff --git a/lua/null-browser/extras/html.lua b/lua/null-browser/extras/html.lua
index d247090..db4e864 100644
--- a/lua/null-browser/extras/html.lua
+++ b/lua/null-browser/extras/html.lua
@@ -38,6 +38,7 @@ html.span = html.create_el('span')
html.button = html.create_el('button')
html.style = html.create_el('style')
html.a = html.create_el('a')
+html.input = html.create_el('input')
function html.escape_string(str)
str = str:gsub('&', '&amp;')
diff --git a/lua/null-browser/extras/statusline.lua b/lua/null-browser/extras/statusline.lua
index b23c3a6..ecc40fb 100644
--- a/lua/null-browser/extras/statusline.lua
+++ b/lua/null-browser/extras/statusline.lua
@@ -82,7 +82,7 @@ end
function statusline.current_url()
local views = web.view.list()
local view = views[web.view.current_index()]
- return view and view.url or ""
+ return view and view.url or ''
end
local function segment_html(segment)
diff --git a/lua/null-browser/extras/tabline.lua b/lua/null-browser/extras/tabline.lua
index 81983a8..1c2436d 100644
--- a/lua/null-browser/extras/tabline.lua
+++ b/lua/null-browser/extras/tabline.lua
@@ -1,9 +1,14 @@
local html = require 'null-browser.extras.html'
local tabline = {
- config = { decoration = web.decorations.top }
+ config = {
+ decoration = web.decorations.top,
+ transform_html = nil,
+ on_window_setup = nil,
+ vertical_size = 200,
+ horizontal_size = 20,
+ },
}
--- TODO: vertical tabs
function tabline.init(opts)
tabline.config = web.utils.table_merge(tabline.config, opts)
local decoration = tabline.config.decoration
@@ -13,10 +18,14 @@ function tabline.init(opts)
decoration.enable({ win = event.win_id })
tabline.show_tabs_in_window(event.win_id, decoration);
+ local size = tabline.config.horizontal_size
if tabline.is_vertical() then
- tabline.config.decoration.set_size(200, { win = event.win_id })
- else
- tabline.config.decoration.set_size(20, { win = event.win_id })
+ size = tabline.config.vertical_size
+ end
+ tabline.config.decoration.set_size(size, { win = event.win_id })
+
+ if type(tabline.config.on_window_setup) == 'function' then
+ tabline.config.on_window_setup(event.win_id)
end
end,
})
@@ -63,11 +72,15 @@ function tabline.tabs_html()
table.insert(tab_list, tab)
end
- local tabs_html = html.div({}, {
+ local tabs_html = html.div({ class = 'tabs-wrapper' }, {
html.style({}, { html.raw(tabline.css()) }),
html.div({ class = 'tabs' .. (tabline.is_vertical() and ' vertical' or '') }, tab_list)
})
+ if type(tabline.config.transform_html) == 'function' then
+ tabs_html = tabline.config.transform_html(tabs_html)
+ end
+
return html.to_string(tabs_html)
end
@@ -80,15 +93,21 @@ function tabline.css()
html, body {
background: #000;
}
+ body * { min-width: 0; box-sizing: border-box; }
+ .tabs-wrapper {
+ width: 100%;
+ }
.tabs {
display: flex;
align-items: stretch;
height: 100vh;
+ width: 100%;
}
.tabs.vertical {
flex-direction: column;
justify-contents: flex-start;
align-items: flex-start;
+ height: auto;
}
.tabs.vertical .tab {
border-left: none;