Skip to content

Feature: add signal:map() method #19

Closed
@b0o

Description

@b0o

I often find myself wanting to use several different signal values in a single prop. I'm currently doing something like this:

local n = require 'nui-components'

local renderer = n.create_renderer {
  width = math.min(vim.o.columns, 64),
  height = math.min(vim.o.lines, 20),
}

local signal = n.create_signal {
  foo = false,
  bar = false,
  qux = false,
}

renderer:render(
  --
  n.rows(
    n.paragraph {
      is_focusable = false,

      -- This is the important part:
      lines = signal.foo:map(function()
        local val = signal:get_value()
        return {
          n.line(n.text('Foo: ', 'Keyword'), tostring(val.foo)),
          n.line(n.text('Bar: ', 'Keyword'), tostring(val.bar)),
          n.line(n.text('Qux: ', 'Keyword'), tostring(val.qux)),
        }
      end),

    },
    n.gap(1),
    n.columns(
      { flex = 0 },
      n.button {
        label = ' Toggle Foo ',
        autofocus = true,
        on_press = function()
          signal.foo = not signal.foo:get_value()
        end,
      },
      n.gap(1),
      n.button {
        label = ' Toggle Bar ',
        on_press = function()
          signal.bar = not signal.bar:get_value()
        end,
      },
      n.gap(1),
      n.button {
        label = ' Toggle Qux ',
        on_press = function()
          signal.qux = not signal.qux:get_value()
        end,
      }
    )
  )
)

In the above example, although I'm mapping over the foo signal value, the function seems to be called when any of the signal's values change. In fact, it seems we can map over any signal field, even if it doesn't exist, like signal.baz:map(fn).

My request: It would be nice to be able to map directly over the signal, signal:map(fn). The function fn should be called with the full value of the signal as the argument whenever any of the signal’s values change:

n.paragraph {
  is_focusable = false,
  lines = signal:map(function(val)
    return {
      n.line(n.text('Foo: ', 'Keyword'), tostring(val.foo)),
      n.line(n.text('Bar: ', 'Keyword'), tostring(val.bar)),
      n.line(n.text('Qux: ', 'Keyword'), tostring(val.qux)),
    }
  end),
},

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions