# UI

As your commands become more complex and do more things, the need to communicate what is happening to users becomes increasingly important. Seeli provides a few simple and powerful ways to interact and communicate with users.

# Progress Indicators

Seeli commands have access to an instance of ora (opens new window) inside the run function. It can be controlled by the ui property. Additionally, you may use ui configuration property to change the progress spinner to any valid ora spinner.













 







'use strict'
const seeli = require('seeli')

function sleep(ms = 100) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

module.exports = new seeli.Command({
  name: 'progress'
, description: 'Displays a progress indicator'
, ui: 'bouncingBar'
, run: async function(cmd, data) {
    this.ui.start('processing...')
    await sleep(2000)
    this.ui.succeed('done')
  }
})

progress

All available spinners spinners

# Messages

By assigning a string to the text property of the ui instance you are able to set the text of the terminal in place. This is useful for updating users of the current status. For example, you may want to display the number of steps that have been completed by the current command.









































 





'use strict'
const seeli = require('seeli')

function sleep(ms = 100) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

const messages = [
  'Adding Hidden Agendas'
, 'Adjusting Bell Curves'
, 'Aesthesizing Industrial Areas'
, 'Aligning Covariance Matrices'
, 'Applying Feng Shui Shaders'
, 'Applying Theatre Soda Layer'
, 'Asserting Packed Exemplars'
, 'Assembling Blockchain Reservoir'
, 'Attempting to Lock Back-Buffer'
, 'Binding Sapling Root System'
, 'Buffering Physical Caches'
, 'Building Data Trees'
, 'Bureacritizing Bureaucracies'
, 'Calculating Inverse Probability Matrices'
, 'Cohorting Exemplars'
, 'Collecting Meteor Particles'
]

const randomMessage = () => {
  return messages[Math.floor(Math.random() * messages.length)]
}

module.exports = new seeli.Command({
  name: 'messages'
, description: 'Displays random messages'
, run: async function(cmd, data) {
    let x = 10
    this.ui.start('processing...')
    while (x--) {
      await sleep(1000)
      this.ui.text = randomMessage()
    }
    this.ui.succeed('done')
  }
})

messages

# Alerts

When you need to display important messages, like a command failing or prematurely stopping, you should use the alert functions. each function has a unique icon for the severity of the message. The functions available on the ui object are:

  • info
  • warn
  • fail
  • succeed
'use strict'
const seeli = require('seeli')

function sleep(ms = 100) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

module.exports = new seeli.Command({
  name: 'alerts'
, description: 'Displays a progress indicator'
, run: async function(cmd, data) {
    this.ui.start('rendering alerts')
    await sleep(1000)
    this.ui.info('info')
    await sleep(1000)
    this.ui.warn('warn')
    await sleep(1000)
    this.ui.fail('fail')
    await sleep(1000)
    this.ui.succeed('success')
  }
})

alerts

TIP

When you use one of the alery function, the progress indicator will be stopped. You must call this.ui.start(...) again to restart it

# Prompts

Seeli uses the inquirer (opens new window) to interactively collect input from users. This functionality is exposed via the prompt function. This is a direct passthrough the the inquirer function of the same name (opens new window). This makes things like conditional and branching logic based on user input significantly easier.















 
 
 
 
 





























'use strict'

const seeli = require('seeli')

function sleep(ms = 100) {
  return new Promise((resolve) => {
    setTimeout(resolve, ms)
  })
}

module.exports = new seeli.Command({
  name: 'alerts'
, description: 'Displays a progress indicator'
, run: async function(cmd, data) {
    Object.assign(data, await this.prompt({
      type: 'input'
    , name: 'name'
    , message: 'What is your name'
    }))

    Object.assign(data, await this.prompt({
      type: 'password'
    , name: 'password'
    , message: 'What is your password'
    }))

    Object.assign(data, await this.prompt({
      type: 'confirm'
    , name: 'confirm'
    , message: 'Are you sure'
    }))

    if (!data.confirm) {
      Object.assign(data, await this.prompt({
        type: 'password'
      , name: 'password'
      , message: 'What is your password'
      }))
    }

    this.ui.start('processing...')
    await sleep(2000)
    this.ui.info(`name: ${data.name}`)
    this.ui.info(`password: ${data.password}`)
    this.ui.info(`confirmed: ${data.confirm}`)
  }
})

prompts