npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@swimlane/swimlane-element

v2.2.0

Published

`SwimlaneElement` is a simple base class for creating Swimlane platform widgets using [lit-html](https://lit-html.polymer-project.org/) templating.

Downloads

24,836

Readme

SwimlaneElement

SwimlaneElement is a simple base class for creating Swimlane platform widgets using lit-html templating.

Building

Run npm run build to build SwimlaneElement. The build artifacts will be stored in the build/ directory.

Development server

Run npm run start to serve the demo.

Release

  • Checkout master (git checkout master)
  • Pull master (git pull)
  • Refresh node modules (npm ci)
  • Examine log to determine next version (X.Y.Z)
  • Run git checkout -b release/X.Y.Z
  • Update version in package.json.
  • Update changelog in CHANGELOG.md
  • Run git commit -am "(release): X.Y.Z"
  • Run git tag X.Y.Z
  • Run git push origin HEAD --tags
  • Run npm run publish
  • Submit PR

Overview

LitElement (https://lit-element.polymer-project.org/) is a webcomponent base class that uses lit-html (https://lit-html.polymer-project.org/) templating library. LitElement (https://lit-element.polymer-project.org/) uses lit-html to render into the element's Shadow DOM and adds API to react to changes in properties.

SwimlaneElement extends from LitElement to add API for interacting with records or reports in the Swimlane platform.

Getting Started

/**
 * Import `SwimlaneElement` class.
 * The `css` and `html` methods are also imported from `swimlane-element`.
 */
import { SwimlaneElement, css, html } from '@swimlane/swimlane-element@1';

/**
 * The `recordFrameTemplate` is a template function see templates below.
 */
import { recordFrameTemplate } from '@swimlane/swimlane-element@1/templates.js';

/**
 * A Swimlane widget is implemented as an anonymous class which extends the `SwimlaneElement` class.
 */
export default class extends SwimlaneElement {
  /**
   * The `styles()` getter is a static class getter, in other words, it is a property defined on the class constructor.
   * This style getter method does not have access to any properties stored in the objects.
   * This getter defines styles common to all instances of this widget.
   * Defining this in your widget is optional.
   */
  static get styles() {
    return [super.styles, css`
      .frame::after {
        content: "Record Output";
      }
    `];
  }

  /**
   * The `render` method is an instance method and, therefore, has access to properties  stored in the object (i.e. `record` and `report`, see properties below.
   * The render method is scheduled by `LitElement` Lifecycle events and must return a `lit-html` template.
   * Defining this method in your widget is required.
   */
  render() {
    return recordFrameTemplate(html`
      <pre>${JSON.stringify(this.record, undefined, 2)}</pre>
    `);
  }
}

Properties

LitElement efficiently manages declared properties and attributes. By default SwimlaneElement declares record or report properties as well as the 'contextData' property. Documentation on how LitElement handles properties and attributes can be found here.

  • this.record - Available to record widgets, an object containing key-value pairs for each field on the record.
  • this.report - Available to report widgets, an object containing data, rawData, and query.
  • this.contextData - Available to both record and report widgets, an object containing data such as application, currentUser, origin, and token.

Templates

To define a template for a SwimlaneElement component, write a render function that returns a lit-html template. More details on writing render methods can be found in the documentation for LitElement and lit-html. The swimlane-element library includes predefined templates designed for the Swimlane platform. These templates can be imported from @swimlane/swimlane-element@1/templates.js.

  • recordFrameTemplate - A base template for rendering a frame on the record page. This function takes as arguments a template to render inside the frame and an optional rows height value. Without a defined rows value the frame will auto size to the content.
  • reportFrameTemplate - A base template for rendering a frame on the dashboards. This function takes as arguments a template to render inside the frame and an optional rows height value. Without a defined rows value the frame will auto size to the content.

Styles

As with LitElement there are "three main places in which you can define styles for your host element" ref. The two most common methods for SwimlaneElements will be to Define styles in a static styles property or Define styles in a style element.

Events

Documentation on how to handle events in LitElement can be found here. SwimlaneElement adds the following methods for emitting Swimlane widget events:

  • this.updateRecordValue(key, value) : Available to record widgets. Updates record data by field key.
  • this.addComment(key, value) : Available to record widgets. Adds a new comment by field key.
  • this.triggerIntegration(taskId) : Available to record widgets. Triggers an integration.
  • this.triggerSave() : Available to record widgets. Triggers record save on the record page.
  • this.triggerButton(buttonId) : Available to record widgets. Triggers the specified button on the record page.

Lifecycle

LitElement watches properties and attributes for changes and asynchronously renders the template to the element's shadow DOM. Documentation of LitElement lifecycle methods and properties can be found here. In addition to the HtmlElement and LitElement lifecycle methods, SwimlaneElement adds the resizedCallback method.

  • resizedCallback - This method (called whenever the element is resized) but default simply calls requestUpdate.

Examples

Basic

// SwimlaneElement and html are the basic required imports
import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';

// Create and export a class definition for your widget that extends the SwimlaneElement base class
export default class extends SwimlaneElement {
  // The render callback renders your element's template.
  // It should always return the same template given the same properties and should not perform
  // any side effects such as setting properties or manipulating the DOM.
  render() {
    // Return the template using the html template tag.
    return html`
      <div>Hello world!</div>
    `;
  }
}

Record data

import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';

export default class extends SwimlaneElement {
  // The render callback is called each time the record data changes.
  // lit-html is optimized for handling frequent updates and updating the DOM efficiently
  render() {
    return html`
      <div>
        Current count: ${this.record['count']}
      </div>
    `;
  }
}

Handling events

import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';

export default class extends SwimlaneElement {
  render() {
    return html`
      <div>
        Current count: [${this.record['count']}]
        <!-- Use @[eventname] syntax to register inline event handlers -->
        <button @click=${() => this.updateRecordValue('count', this.record['count'] + 1)}>+</button>
        <!-- You can also pass a function reference directly. -->
        <button @click=${this._onDecrement}>-</button>
      </div>
    `;
  }

  _onDecrement() {
    this.updateRecordValue('count', this.record['count'] - 1)
  }
}

Styles in a static styles property

import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';

export default class extends SwimlaneElement {
  /**
   * Styles should be added as a static getter. They are evaluated once, and then added
   * in the element's shadow dom.
   */
  static get styles() {
    return css`
      :host {
        display: block;
      }
      .message {
        color: blue;
      }
    `;
  }

  render() {
    return html`
      <div class="message">
        Current count: ${this.record['count']}
      </div>
    `;
  }
}

Swimlane styles

import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';
import { recordFrameTemplate } from '@swimlane/swimlane-element@1/templates.js';

export default class extends SwimlaneElement {
  /**
   * The styles getter may return a array.
   * Add `super.styles` to get swimlane default styles.
   * Overide the `.frame::after` style to set a label for the frame.
   */
  static get styles() {
    return [super.styles, css`
      :host {
        display: block;
      }
      .message {
        color: blue;
      }
      .frame::after {
        content: "Current Count";
      }
    `];
  }

  /**
   * Wrap the template in `recordFrameTemplate` function to add a frame.
   * The seoncd argument (optional) is the row count height.
   */
  render() {
    return recordFrameTemplate(html`
      <div class="message">
        ${this.record['count']}
      </div>
    `, 2);
  }
}

Styles in a style element.

import { SwimlaneElement, html } from '@swimlane/swimlane-element@1';

export default class extends SwimlaneElement {
  render() {
    const color = this.record['count'] > 10 ? 'red' : 'blue';
    return html`
      <-- styles defined here are dynamic, and will update when properties update.
      <style>
        .message {
          color: ${color};
        }
      </style>
      <div class="message">
        Current count: ${this.record['count']}
      </div>
    `;
  }
}

Full Demo

import { SwimlaneElement, css, html } from '@swimlane/swimlane-element@1';
import { recordFrameTemplate } from '@swimlane/swimlane-element@1/templates.js';

export default class extends SwimlaneElement {
  static get styles() {
    return [super.styles, css`
      :host {
        text-align: center;
      }
      .frame::after {
        content: "Current Count";
      }
      button {
        font-size: xx-large;
        margin-top: 10px;
        height: 60px;
        width: 60px;
        border-radius: 5px;
        background-color: #ffbb47;
        color: #07080b;
        bordeR: 0;
      }
      .message {
        font-size: xx-large;
      }
    `];
  }

  render() {
    const color = this.record['count'] > 10 ? '#FF4514' : '#1483FF';
    return recordFrameTemplate(html`
      <style>
        .message {
          color: ${color};
        }
      </style>
      <div>
        <div class="message">
          ${this.record['count']}
        </div>
        <button @click=${this._onIncrement}>+</button>
        <button @click=${this._onDecrement}>-</button>
      </div>
    `, 2);
  }

  _onIncrement() {
    this.updateRecordValue('count', this.record['count'] + 1)
  }

  _onDecrement() {
    this.updateRecordValue('count', this.record['count'] - 1)
  }
}

Credits

SwimlaneElement is a Swimlane open-source project; we believe in giving back to the open-source community by sharing some of the projects we build for our application. Swimlane is an automated cyber security operations and incident response platform that enables cyber security teams to leverage threat intelligence, speed up incident response and automate security operations.