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

lambda.html

v2.2.2

Published

Lambda.html is a TypeScript-based HTML builder framework that leverages functional programming principles to provide a declarative, composable, and extensible approach for building dynamic web interfaces. Designed for robustness and maintainability, it in

Downloads

707

Readme

Lambda.html

Overview

Lambda.html is a TypeScript HTML builder framework designed to streamline the creation of HTML documents. It uses functional programming to offer a declarative way to build web interfaces, ensuring clean and maintainable code. It works well with CSS frameworks like Tailwind CSS and is ideal for developers aiming for high reliability and maintainability in web projects.

Features

  • Robustness: Focuses on creating predictable and reliable software with zero dependencies.
  • HTMX Integration: Supports easy integration with HTMX for AJAX-driven applications.
  • Extensibility: Allows for custom components and attributes to suit diverse needs.
  • Type Safety: Utilizes TypeScript for static type checking, enhancing code reliability.
  • Tailwind CSS Compatibility: Ensures smooth integration with Tailwind CSS for styling.

Core Concepts

  • Robust Design: Built to produce robust, predictable components.
  • Seamless Style Integration: Compatible with any CSS framework, facilitating easy styling by passing class names directly to HTML elements.

Installation

To get started with Lambda.html, follow these simple steps:

  1. Install via npm:

    npm install lambda.html
  2. Import in your project:

    import { Div, Button, Text, render } from 'lambda.html';
  3. Example usage:

    const myButton = Button({
      class: "btn btn-primary",
      child: Text("Click Me"),
      htmx: hx("/submit-form", {
        method: "post",
      })
    });
    
    const myPage = Div({
      child: myButton
    });
    
    console.log(render(myPage));

This section outlines how to install and begin using Lambda.html in your projects. For detailed API documentation, comprehensive examples, and best practices, refer to the subsequent sections.

Composability and Reusable Components

Lambda.html emphasizes composability, allowing developers to construct complex UIs from smaller, reusable components. Utilizing pure functions, these components can be combined without side effects, ensuring consistent behavior.

Creating Reusable Components

For effective composability, define reusable components as pure functions. Here’s an example of creating a ContactDetailsView component in Lambda.html:

import { Div, Img, P, A, Text, HStack, render } from 'lambda.html';

// Define a reusable component as a pure function.
function ContactDetailsView(name: string, phone: string): View {
  return Div({
    child: HStack([
      Img({ src: "call.svg" }),
      Div({
        child: [
          P({ child: Text(name) }),
          P({ 
            class: "orange", 
            child: A({ href: `tel:${phone}`, child: Text(phone) }) 
          }),
        ],
      })
    ])
  });
}

const contactInfo: View = [
  ContactDetailsView("Alice Johnson", "+1234567890"),
  ContactDetailsView("John Wick", "+9876543210"),
];

console.log(render(contactInfo));

This example demonstrates how to encapsulate and reuse a contact card component, which includes an image, name, and clickable phone number, across different parts of your application.

Benefits of Composability

  1. Modularity: Components are developed, tested, and maintained independently, simplifying the construction of complex interfaces.
  2. Reusability: Components can be reused throughout an application or across multiple projects, enhancing efficiency.
  3. Maintainability: Localized changes in components minimize unintended impacts, improving application stability.

Best Practices for Component Design

  • Focus: Keep components small and dedicated to a single task.
  • Clarity: Use names that clearly indicate what the component does.
  • Flexibility: Design components to accept parameters, allowing for customization and broader use.

These practices, combined with Lambda.html's composability, enable the development of robust, maintainable, and scalable web applications.

Examples

import { Div, Text, render } from 'lambda.html';

const greeting = Div({
  class: "p-4 text-center text-lg",
  child: Text("Hello, world!")
});

console.log(render(greeting));

This example creates a div with padding and centered text, demonstrating how easy it is to apply Tailwind CSS classes.

Conditional Rendering with IfThen and IfThenElse

Lambda.html provides IfThen and IfThenElse for conditional rendering of HTML elements. Here's how you can use these building blocks:

import { Div, Text, IfThen, IfThenElse, render } from 'lambda.html';

function UserProfile(state: string | undefined): View {
  return IfThenElse(
    state,
    () => Text(`Welcome back, ${state}!`),
    () => Text("Please log in.")
  );
);

const profile = UserProfile("Alice");
console.log(render(profile));

This example shows how to conditionally render different text based on whether the user is logged in.

Conditional Rendering with SwitchCase

import { Text, SwitchCase, render } from 'lambda.html';

// Example user data
const user = {
  name: "Alice",
  role: "admin"
};

// Define the SwitchCase component for conditional rendering
const greeting = SwitchCase(
  [
    {
      condition: () => user.role === "admin",
      component: Text("Welcome, admin!")
    },
    {
      condition: () => user.role === "user",
      component: Text("Welcome, user!")
    },
    {
      condition: () => user.role === "guest",
      component: Text("Welcome, guest!")
    }
  ], 
  () => Text("Role not recognized."),
);

// Render the greeting based on user role
console.log(render(greeting));

This example demonstrates how SwitchCase simplifies conditional rendering in Lambda.html. By encapsulating conditions within a structured format, it enhances code clarity and maintainability, focusing on what to render rather than the logic to determine it.

Looping with ForEach

ForEach is used to render lists of elements. Here's an example:

import { Ul, Li, ForEach, Text, render } from 'lambda.html';

const items = ["Apple", "Banana", "Cherry"];

const itemList = Ul({
  child: ForEach(items, item => Li({
    child: Text(item)
  }))
});

console.log(render(itemList));

This example creates an unordered list of fruit names, demonstrating how ForEach can be used to iterate over an array of data.

Sometimes, it is useful to know the index of the item. Use ForEach1 in those cases:

import { Div, Input, Label, ForEach1, Text, render } from 'lambda.html';

// Example tasks array
const tasks = [
  "Finish the report",
  "Call the client",
  "Prepare meeting agenda",
];

// Function to render a single task
function TaskView(task: string, index: number): View {
  return Div({
    child: [
      Input({ type: "checkbox", id: `task-${index + 1}` }),
      Text(`${index + 1}. ${task}`),
    ],
  });
}

// Create the list of tasks using ForEach1
function TasksView(tasks: string[]): View {
  return ForEach1(tasks, TaskView);
}

// Render the task list
const view = TasksView(tasks);
console.log(render(view));

Combined Example: A Dynamic User Profile

Let's combine these concepts to create a more complex example:

import { Div, H1, P, IfThenElse, ForEach, Text, render } from 'lambda.html';

function UserProfileView(name: string, loggedIn: boolean, interests: string[]): View {
  return Div({
    child: [
      H1({
        child: Text(`Profile: ${name}`)
      }),
      IfThenElse(
        isLoggedIn,
        () => P({ child: Text("Status: Online") }),
        () => P({ child: Text("Status: Offline") }),
      ),
      P({
        child: Text("Interests:")
      }),
      Ul({
        child: ForEach(interests, interest => Li({
          child: Text(interest)
        }))
      })
    ]
  });
}

const userProfile = UserProfileView("Alice", true, ["Reading", "Hiking", "Coding"]);
console.log(render(userProfile));

This example demonstrates creating a dynamic user profile page using Lambda.html. It incorporates the user's name, online status, and interests list, utilizing IfThenElse for conditional rendering and ForEach for iterating over arrays. This approach exemplifies how to build complex and interactive HTML structures with Lambda.html's functional and declarative syntax.

Using HTMX for Interactive Elements

import { Form, Input, Button, Text, render } from 'lambda.html';

const interactiveForm = Form({
  action: "/submit",
  method: "post",
  htmx: hx("/submit-form", {
    method: "post",
    swap: "outerHTML",
    trigger: "submit"
  }),
  child: [
    Input({
      type: "text",
      name: "username",
      placeholder: "Enter your username"
    }),
    Button({
      type: "submit",
      child: Text("Submit")
    })
  ]
});

console.log(render(interactiveForm));

This example demonstrates how to use HTMX with Lambda.html to create an interactive form. The form submits data to "/submit-form" using a POST request upon submission, and the server's response replaces the form in the DOM, enhancing user experience without full page reloads.

Using Tailwind CSS for Styling

import { Div, H1, P, Text, render } from 'lambda.html';

const styledPage = Div({
  class: "bg-gray-200 p-4",
  child: [
    H1({
      class: "text-xl font-bold text-center text-blue-500",
      child: Text("Welcome to Lambda.html")
    }),
    P({
      class: "text-base text-gray-700",
      child: Text("Start building beautiful and interactive web pages easily.")
    })
  ]
});

console.log(render(styledPage));

1. Dashboard Layout

Create a dashboard layout with a sidebar, header, and content area. This example can demonstrate how to use Div and HStack to create a layout structure, and how to integrate interactive elements using HTMX.

import { Div, HStack, Button, Text, render } from 'lambda.html';

function DashboardLayout(sidebarContent: View, mainContent: View): View {
  return Div({
    class: "min-h-screen flex",
    child: HStack({
      children: [
        Div({ class: "w-64 bg-gray-800 text-white", child: sidebarContent }),
        Div({
          child: [
            Div({ class: "bg-gray-200 p-4 shadow", child: Text("Header") }),
            mainContent
          ]
        })
      ]
    })
  });
}

function MyDashboard(): View {
  return DashboardLayout(
    [
      Button({ child: Text("Home"), class: "p-2 hover:bg-gray-700" }),
      Button({ child: Text("Settings"), class: "p-2 hover:bg-gray-700" })
    ],
    Div({ class: "p-4", child: Text("Welcome to the dashboard!") }),
  );
}

const dashboard = MyDashboard();
console.log(render(dashboard));

2. Interactive Data Table

Build a data table component that supports sorting and pagination. This component can utilize ForEach to render rows based on data and IfThenElse for conditional rendering of table states.

import { Div, Button, Text, ForEach, IfThenElse, render } from 'lambda.html';

function DataTable(headers: string[], data: any[]): View {
  return Table({
    child: [
      Thead({
        child: Tr({
          child: ForEach(headers, header => Th({ child: Text(header), class: "font-bold p-2" }))
        })
      }),
      Tbody({
        child: ForEach(data, row => 
          Tr({
            child: ForEach(Object.values(row), (value: any) => Td({ child: Text(value.toString()), class: "p-2" }))
          })
        )
      })
    ]
  });
}

const headers = ["Name", "Age", "Location"];
const data = [
  { Name: "Alice", Age: 28, Location: "New York" },
  { Name: "Bob", Age: 25, Location: "California" }
];

const table = DataTable(headers, data);
console.log(render(table));