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

litstate-app

v0.1.4

Published

TypeScript framework for fast web app creation

Downloads

11

Readme

litState

Overview

litState is a lightweight TypeScript framework for creating web applications quickly and efficiently. It provides:

  • Zero dependencies: Streamlines your project setup.
  • Simple API: Easy to learn and use.
  • Reactive Components: Optimize your UI with precise updates.
  • State Management: Utilize proxies for effortless state handling.
  • Fast Project Setup: Ideal for small projects with its quick setup.

Check out the full documentation or for more details.

Installation

To get started, install litState using npm:

npm install litstate-app

Usage

Setting Up Global State

Import and create a global state object:

import { createState } from 'litstate-app';

const initialState = {
  count: 0,
};

export const globalState = createState(initialState);

Creating Components

Build components that interact with the global state:

import { component, html, handler } from 'litstate-app';
import { globalState } from './globalState';

export const Counter = component(() => {
  return html`
    <div>
      <p>Count: ${globalState.count}</p>
    </div>
  `;
});

export const IncrementButton = component(() => {
  const incrementHandler = handler(() => {
    globalState.count++;
  });

  return html`
    <div>
      <button onclick="${incrementHandler}">Increment</button>
    </div>
  `;
});

Root Component

Create a root component to render other components:

import { component, html } from 'litstate-app';
import { Counter, IncrementButton } from './components';

export const App = component(() => {
  return html` <div>${Counter()} ${IncrementButton()}</div> `;
});

Mounting the App

Mount the root component to the DOM:

import { mount } from 'litstate-app';
import { App } from './App';

// HTML element where the app will mount
// <div id="app"></div>;

// Mount the App component to the 'app' element
mount(App, 'app');

Component Function

Define a reusable UI component:

export const MyComponent = component(({ title, content }) => {
  return html`
    <div>
      <h1>${title}</h1>
      <p>${content}</p>
    </div>
  `;
});

Instantiate the component with the desired props:

import { MyComponent } from './MyComponent';

export const App = component(() => {
  return html`
    <div>${MyComponent({ title: 'My Title', content: 'My Content' })}</div>
  `;
});

The component's unique identifier, id, can be included in the props object. If not provided, the id is automatically generated based on the component's position in the call stack and is appended to the props. When defining components that may be instantiated multiple times within a loop, it's important to provide an id prop to ensure each instance maintains a unique identity:

import { component, html } from '../../../src';

export const LoopComponent = component(props => {
  const { id } = props; // Destructure the id from props if needed

  return html`
    <div>
      <!-- some HTML -->
    </div>
  `;
});

// Use the component in a loop with unique 'id' props
html`
  ${yourArray.map((item, index) =>
    LoopComponent({ ...item, id: item.uniqueId || index })
  )}
`;

State Management

litState provides a straightforward state management system designed to enable both global and local states, leveraging the power of JavaScript proxies for reactivity. These states are deeply reactive due to the recursive use of proxies, ensuring updates are precise and components re-render only when necessary.

import {
  createState,
  addListener,
  removeListener,
  batchUpdate,
  html,
} from 'litstate-app';

// Create a global state object
export const appState = createState({
  user: {
    name: 'Jane Doe',
    age: 25,
  },
  theme: 'light',
  isLoggedIn: false,
});

// Create a component that uses the global and local states
export const MyComponent = component(() => {
  // Create a local state object
  const localState = createState({
    count: 0,
  });

  const incrementHandler = handler(() => {
    // Update the local state
    localState.count++;
  });

  const userNameSetter = handler(() => {
    // Update the global state
    appState.user.name = 'John Doe';
  });

  return html`
    <div>
      <p>Global state: ${appState.user.name}</p>
      <p>Local state: ${localState.count}</p>
      <button onclick="${incrementHandler}">Increment</button>
      <button onclick="${userNameSetter}">Set User Name</button>
    </div>
  `;
});

State updates can be done from anywhere in your application, including outside of components:

import { appState } from './appState';

// Update the global state
appState.user.name = 'John Doe';

Batch State Updates

Batch state updates are useful to prevent unnecessary re-renders. Multiple state updates can be batched together using the batchUpdate function. Components will only re-render once all state updates are complete.

import { appState } from './appState';
import { batchUpdate } from 'litstate-app';

// Batch state updates
batchUpdate(() => {
  appState.user.name = 'John Doe';
  appState.user.age = 30;
});

Adding and Removing Listeners

To listen for state changes outside of components, use the addListener function. These listeners execute once upon creation, monitoring the accessed state properties, and are reinvoked whenever those properties undergo changes. When creating listeners within loops or multiple instances, ensure to provide a unique id for each listener to maintain the correct tracking and to provide the capability to remove them individually if needed.

import { appState } from './appState';
import { addListener, removeListener } from 'litstate-app';

// Create a listener with an ID
addListener(() => {
  console.log('User name:', appState.user.name);
}, 'user-name-listener'); // The ID is optional unless you need to remove the listener later, or it is within a loop

// Later, remove the listener
removeListener('user-name-listener');

HTML Function

Utilize the html function to create and manage dynamic HTML content:

import { html } from 'litstate-app';

export const Greeting = component(({ name }) => {
  return html` <div>Hello, ${name}!</div> `;
});

Handler Function

Handle events within your components:

export const IncrementButton = component(() => {
  const incrementHandler = handler((event, element) => {
    console.log('Event:', event);
    console.log('Element:', element);
    globalState.count++;
  });

  return html`
    <div>
      <button onclick="${incrementHandler}">Increment</button>
    </div>
  `;
});

Mount Method

Render your component into the DOM:

// In your HTML file
// <div id="app"></div>

import { mount } from 'litstate-app';
import { App } from './App';

mount(App, 'app');

Router and Link Components

Implement client-side routing:

import { Router, Link, navigate } from 'litstate-app/components';
import { Home, About, NotFound } from './components';

const NavBar = () => {
  return html`
    <div>
      ${Link({ to: '/', children: 'Home' })} ${Link({
        to: '/about',
        children: 'About',
      })}
    </div>
  `;
};

const routes = {
  '/': Home,
  '/about': About,
  '*': NotFound,
};

const App = () => {
  return html`
    <div>
      <Router routes=${routes} />
    </div>
  `;
};

// Use navigate to change routes programmatically
navigate('/about');

License

MIT License

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.