grapp-dev / nui-components.nvim

A feature-rich and highly customizable library for creating user interfaces in Neovim.
https://nui-components.grapp.dev
MIT License
303 stars 6 forks source link

All SignalValues emit when a single value is updated #32

Closed mobily closed 4 months ago

mobily commented 5 months ago

Discussed in https://github.com/grapp-dev/nui-components.nvim/discussions/29

Originally posted by **b0o** April 17, 2024 Is this the intended behavior? I would expect a SignalValue to only emit items when it is updated, not when other values in the Signal are updated. Demo: https://github.com/grapp-dev/nui-components.nvim/assets/21299126/65ccd752-84a1-4e96-b5f1-61322efad59f ```lua local n = require 'nui-components' local renderer = n.create_renderer { width = 60, height = 12, } local signal = n.create_signal { name = '', description = '', } local body = function() return n.rows( n.paragraph { is_focusable = false, lines = signal.name:map(function(name) return { -- Use math.random so we can see when renders occur: n.line(n.text('Name: ', 'Keyword'), name .. ' (' .. math.random(1, 100) .. ')'), } end), }, n.paragraph { is_focusable = false, lines = signal.description:map(function(description) return { -- Use math.random so we can see when renders occur n.line(n.text('Description: ', 'Keyword'), description .. ' (' .. math.random(1, 100) .. ')'), } end), }, n.gap(1), n.form( { id = 'form' }, n.text_input { autofocus = true, max_lines = 1, border_label = 'Name', on_change = function(val) signal.name = val end, }, n.text_input { max_lines = 1, border_label = 'Description', on_change = function(val) signal.description = val end, } ) ) end renderer:render(body) ``` --- The following patch would make it behave in the way I would expect: https://github.com/grapp-dev/nui-components.nvim/assets/21299126/15104c2e-ddea-4498-8313-5ba485d1e34d ```patch diff --git a/lua/nui-components/signal/init.lua b/lua/nui-components/signal/init.lua index 9446bd5..f6cdd92 100644 --- a/lua/nui-components/signal/init.lua +++ b/lua/nui-components/signal/init.lua @@ -47,7 +47,7 @@ function Signal.create(object) end, __newindex = function(t, key, value) t[self.__index][key] = value - self._private.subject(t[self.__index]) + self._private.subject(t[self.__index], key) end, }) diff --git a/lua/nui-components/signal/value.lua b/lua/nui-components/signal/value.lua index 90238ae..646166d 100644 --- a/lua/nui-components/signal/value.lua +++ b/lua/nui-components/signal/value.lua @@ -10,9 +10,13 @@ function SignalValue.create(subject, key) _private = { key = key, subject = subject, - observable = subject:map(function(value) - return value[key] - end), + observable = subject + :filter(function(_, k) + return k == nil or k == key + end) + :map(function(value) + return value[key] + end), }, } ```