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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@kraftwerkdesign/c7-components

v0.1.8

Published

Lit-based Commerce7 web components.

Readme

@kraftwerkdesign/c7-components

Lit-based Commerce7 web components for Kraftwerk Design projects.

Install

npm install @kraftwerkdesign/c7-components

Usage

import { setC7Config } from '@kraftwerkdesign/c7-components'
import '@kraftwerkdesign/c7-components'

setC7Config({
  tenant: 'your-tenant',
  tenantId: 'your-tenant',
  apiBase: 'https://api.commerce7.com',
})
<c7-add-to-cart product-slug="sample-product" quantity="1"></c7-add-to-cart>

Components

<c7-add-to-cart>

Attributes:

  • product-slug (required): Commerce7 product slug.
  • quantity (optional): Quantity to add, defaults to 1.

CSS parts:

  • wrapper: The outermost div wrapping the entire component.
  • button-wrapper: The clickable wrapper container around the button slot.
  • button: The default button element (when not using a slot).
  • status: The status message element.
  • price-wrapper: The wrapper div around the default price display.
  • price: The primary (actual) price span.
  • compare-price: The struck-through list price span, rendered only when addToCartPrice differs from price.

CSS custom properties:

  • --c7wc-btn-bg
  • --c7wc-btn-bg-hover
  • --c7wc-btn-text
  • --c7wc-btn-border
  • --c7wc-btn-disabled-bg
  • --c7wc-btn-disabled-text
  • --c7wc-status-text
  • --c7wc-price-text: Color of the primary price. Defaults to inherit.
  • --c7wc-compare-price-text: Color of the compare (strikethrough) price. Defaults to #9c8d82.

Slots

The component supports three named slots for full customization:

  • price slot: Custom price display. Rendered before the button. To populate it with the API price, add data-c7-price / data-c7-add-to-cart-price to elements inside the slot — see Custom Price Markup.
  • button slot: Custom button HTML. The entire slot content is clickable.
  • status slot: Custom status message display.
<!-- Default (shows price + button automatically) -->
<c7-add-to-cart product-slug="sample-product"></c7-add-to-cart>

<!-- Custom price display -->
<c7-add-to-cart product-slug="sample-product">
  <div slot="price" class="my-price"><!-- rendered by your own logic --></div>
</c7-add-to-cart>

<!-- Default button (baseline) -->
<c7-add-to-cart product-slug="sample-product"></c7-add-to-cart>

<!-- Custom button with Tailwind-style classes -->
<c7-add-to-cart product-slug="sample-product">
  <button slot="button" class="bg-blue-600 text-white px-6 py-3 rounded-lg">Add to Cart</button>
</c7-add-to-cart>

<!-- Button with icon -->
<c7-add-to-cart product-slug="sample-product">
  <span slot="button" class="flex items-center gap-2 bg-green-600 text-white px-4 py-2 rounded">
    <svg><!-- cart icon --></svg>
    <span>Add to Cart</span>
  </span>
</c7-add-to-cart>

<!-- Custom status message -->
<c7-add-to-cart product-slug="sample-product">
  <span slot="status" class="text-green-600 text-sm font-medium">✓ Successfully added!</span>
</c7-add-to-cart>

<!-- Fully customized -->
<c7-add-to-cart product-slug="sample-product">
  <button slot="button" class="custom-btn">🛒 Buy Now - $29.99</button>
  <div slot="status" class="custom-status">✅ Added to your cart!</div>
</c7-add-to-cart>

Custom Price Markup

Place data-c7-price, data-c7-add-to-cart-price, or data-c7-compare-price on any element inside <c7-add-to-cart> to have it automatically filled with the formatted price from the API response. This works anywhere in the component's light DOM — inside a slot or alongside one.

<c7-add-to-cart product-slug="champagne-glasses">
  <div slot="price" class="my-price">
    <strong data-c7-add-to-cart-price></strong>
    <del data-c7-price></del>
  </div>
</c7-add-to-cart>

| Attribute | Populated with | | --------------------------- | ------------------------------------------------- | | data-c7-price | Formatted retail price (e.g. "$65.00") | | data-c7-compare-price | Formatted API compare price, or "" if none | | data-c7-add-to-cart-price | Formatted add-to-cart/club price, or "" if none |

  • Values are re-written whenever product-slug changes.
  • Multiple elements with the same attribute are all populated.
  • Elements are left empty ("") when the corresponding price is null.

State-Based Styling

The component exposes state as data attributes on the host element for CSS targeting:

/* Default state */
c7-add-to-cart {
  /* idle/ready */
}

/* Loading or adding state */
c7-add-to-cart[data-state='loading'],
c7-add-to-cart[data-state='adding'] {
  /* loading styles */
}

/* Disabled states (sold out, retired, etc.) */
c7-add-to-cart[data-disabled='true'] {
  /* disabled styles */
}

/* When product is available for purchase */
c7-add-to-cart[data-available='true'] {
  /* available styles */
}

/* Example: Style custom slotted button based on state */
c7-add-to-cart[data-disabled='true'] [slot='button'] {
  opacity: 0.6;
  cursor: not-allowed;
}

c7-add-to-cart[data-state='adding'] [slot='button'] {
  animation: pulse 1s infinite;
}

/* Example: Custom sold-out styling */
c7-add-to-cart[data-state='sold-out'] [slot='button'] {
  background: #fee2e2;
  color: #dc2626;
}

JavaScript Access

Access component state and methods programmatically:

const cart = document.querySelector('c7-add-to-cart')

// Get current state
console.log(cart.state) // 'idle', 'loading', 'ready', 'adding', 'success', 'error', etc.

// Get current status message
console.log(cart.statusMessage) // 'Added', 'Sold Out', etc.

// Manually trigger add to cart
cart._productTask.run()

Notes:

  • Requires global configuration via setC7Config for tenant and tenantId.
  • Optional apiBase can be set to point to a different Commerce7 API host.
  • If window.c7action.showSideCart and window.c7action.reloadCart are defined, they will be called after a successful add.
  • When using slots, the click handler is automatically attached to the slot wrapper.
  • The component is keyboard accessible - Enter and Space keys trigger the add-to-cart action.

Development

npm run dev

Tests

npm test

Environment Variables

Configure tests with these env variables (must use VITE_ prefix):

VITE_C7_TEST_TENANT=my-tenant VITE_C7_TEST_TENANT_ID=my-id VITE_C7_TEST_API_BASE=https://api.example.com npm test
  • VITE_C7_TEST_TENANT - Tenant name (default: test-tenant)
  • VITE_C7_TEST_TENANT_ID - Tenant ID (default: test-tenant-id)
  • VITE_C7_TEST_API_BASE - API base URL (default: https://api.commerce7.com)

Stubbing Network Requests

Use the fetch mock utility to mock API calls in tests:

import { createFetchMock } from './test/fetch-mock'

const stubs = {
  'my-product': { webStatus: 'Available', variants: [{ sku: 'SKU-001', hasInventory: true }] },
}
const { mock, restore } = createFetchMock(stubs)
window.fetch = mock

// run tests...

restore()

Generate stubs from real API responses:

# Show available product slugs from Storybook stories
npm run generate-stubs --

# Generate stubs for all products in Storybook stories
npm run generate-stubs -- --from-stories

# Generate specific stubs
npm run generate-stubs -- product-1 product-2

# Override API base URL
VITE_C7_TEST_API_BASE=https://api.example.com npm run generate-stubs -- my-product

This extracts product slugs from src/stories/c7-add-to-cart.stories.ts and saves API responses to test/stubs/products/.