@tvashtr/ui

A rich, high-performance Nuxt 4 UI Layer providing reusable e-commerce components, reactive state composables, and client-side plugins.
1,700
Install
npm install @tvashtr/ui
Latest Version:1.0.8
Last Updated:Oct 12, 2026
Links: GitHub  ·  npm
Maintainer: gunjanpatel

@tvashtr/ui

A rich, high-performance Nuxt 4 UI Layer providing reusable e-commerce components, reactive state composables, and client-side plugins.

@tvashtr/ui is the frontend core of the Tvashtr Suite. Built as a native Nuxt 4 Layer, it automatically injects generic storefront components, reactive cart state managers, shipping threshold calculators, and geolocation boundary helpers into any tenant store application extending it.


📦 Installation

This package is designed to be used internally within the Tvashtr Suite monorepo npm workspace:

{
  "dependencies": {
    "@tvashtr/ui": "*"
  }
}

🔌 Extending the Layer in your Store

To enable @tvashtr/ui inside an app, extend the package path inside your tenant's nuxt.config.ts:

// apps/your-store-name/nuxt.config.ts
export default defineNuxtConfig({
  extends: [
    '@tvashtr/ui' // Auto-imports all components, composables, and plugins!
  ],
  future: {
    compatibilityVersion: 4 // Requires Nuxt 4 architecture compatibility
  }
})

🧱 Reusable Storefront Components

All UI components are built using Nuxt UI and TailwindCSS v4, utilizing dynamic brand parameters specified inside each tenant store's store.config.ts.

🛒 Cart & Navigation

  • NavBar.vue: Elegant, responsive navigation bar supporting custom logos, category listings, a dynamic cart badge, and a global product search. On desktop the search input is embedded inline. On mobile, a magnifying glass icon in the topbar opens a full-width, auto-focused search overlay without requiring the hamburger menu.
  • CartDrawer.vue: Flyout side panel showing items in the cart, item quantities, variant options, shipping thresholds, and the checkout form with Turnstile forms embedded.
  • FooterBar.vue: Clean, modular footer containing brand links, support contacts, and license labels.

🏷️ Product Cards & Sliders

  • ProductCard.vue: Card component featuring high-quality images, interactive variant selectors, pricing, and "Add to Cart" triggers.
  • ProductSlider.vue & HomeProductSlider.vue: Responsive sliders that display product arrays (e.g. popular items) in a clean, scrollable card line.

🍳 Recipe Hub

  • RecipeCard.vue: Clean grids displaying recipe categories, prep times, and image covers.
  • RecipeSection.vue: Full-page details listing markdown steps, bulleted ingredient check-boxes, and an interactive section letting customers add all matching ingredients to their shopping cart in a single click.

🛡️ Bot Security

  • TurnstileWidget.vue: Standard wrapper component that mounts Cloudflare Turnstile's captcha client, emitting verification tokens securely upon human checks.

🧬 Product Attributes

  • ProductAttributesTable.vue: Generic attribute display component. Accepts title, subtitle, and attributes props. Renders nothing when attributes is empty — zero DOM footprint. Suitable for any store type: Nutrition for food stores, Specifications for electronics, Features for service businesses. Stores can extend this with their own styled variant (e.g. NutritionLabelA.vue) using the same props.

🧪 Reactive Composables

The package exports robust state engines to drive client-side actions:

🔍 useProductFilters(products, categories)

A unified composable that manages both product search and category filtering with automatic, bidirectional URL query-parameter syncing. Drop it into any products page for instant search + filter functionality:

const {
  // State
  activeFilters,        // Set<string> of active category slugs
  dietaryCategories,    // Computed — categories where type === 'dietary'
  usageCategories,      // Computed — categories where type === 'usage'
  filteredProducts,     // Computed — products after search + category filters applied

  // Actions
  toggleFilter,         // Toggle a category slug on/off
  clearFilters,         // Clear all active category filters
  isRowClear,           // Check if an entire filter row (dietary/usage) is inactive
  clearRowFilters,      // Clear all filters in a row
  countForCategory,     // Count products matching a given category slug
} = useProductFilters(products, categories)

URL sync is automatic — ?q= for search, ?categories= for filters — both are read on mount and kept in sync on every change.

🛍️ useCart()

Handles reactive shopping cart state, syncing choices to LocalStorage or client Cookies:

const { cart, add, remove, updateQty, totalItems, totalPrice, clear } = useCart()

// Add item to shopping cart
add({
  sku: 'FLOUR-001',
  name: 'Wheat Flour',
  image: '/assets/flour.jpg',
  price: 4.99,
  variant: '1kg',
  qty: 1
})

🚚 useDelivery()

Manages delivery calculations, threshold limits, and free-shipping boundaries.

const { selectedDelivery, deliveryOptions, subtotal, totalWithDelivery } = useDelivery()

📍 useGeoRestriction()

Prevents shipping submissions outside delivery perimeters (e.g., restricting postcodes to Danish region bounds 1000-9999 or specific local zones).

const { isRestricted, checkPostcode } = useGeoRestriction()

🧬 useProductAttributes(sku)

Returns the attribute map for a given product SKU, sourced from the product attributes sheet loaded by productAttributes.client.ts. Returns an empty object when the sheet is not configured or the SKU has no row — the component self-hides automatically.

const { attributes, hasAttributes } = useProductAttributes(sku)
// attributes: { Calories: '340 kcal', Protein: '13 g', ... }
// hasAttributes: true

🏗️ Design System & Theming

@tvashtr/ui does not lock you into a single aesthetic. It abstracts colors and fonts into Tailwind variables, letting storefronts create completely unique brand identities:

/* apps/your-store-name/app/assets/main.css */
@theme {
  --color-primary-50: var(--ui-color-amber-50);
  --color-primary-500: var(--ui-color-amber-500);
  --color-primary-950: var(--ui-color-amber-950);
  
  --font-sans: 'Outfit', sans-serif;
}

🚀 Hydration Plugins (app/plugins/)

The UI layer automatically boots plugins to hydrate store data from sheet endpoints:

  1. products.client.ts: Populates products state in the application during early initialization.
  2. recipes.client.ts: Safely loads and parses sheet recipe lists.
  3. delivery.client.ts: Validates initial cookie states for addresses and postcodes.
  4. categories.client.ts: Fetches and parses store categories from the categories sheet.
  5. productAttributes.client.ts: Fetches the product attributes sheet if NUXT_PUBLIC_PRODUCT_ATTRIBUTES_SHEET_ID is configured. Silently provides an empty map if not — opt-in with zero noise for stores that don't use it.

Version History

Version Released License
1.0.8
1.0.7
1.0.6
1.0.5
1.0.4