Entro-Zen Components

React component library for Entrolytics UI

Entro-Zen Components

The @entro314labs/entro-zen package is a React component library providing accessible, themeable UI components for Entrolytics applications.

Installation

pnpm add @entro314labs/entro-zen
npm install @entro314labs/entro-zen
yarn add @entro314labs/entro-zen
bun add @entro314labs/entro-zen

Quick Start

import { ZenProvider, Button, TextField } from '@entro314labs/entro-zen'
import '@entro314labs/entro-zen/styles.css'

function App() {
  return (
    <ZenProvider theme="light">
      <TextField label="Email" placeholder="Enter your email" />
      <Button variant="primary">Submit</Button>
    </ZenProvider>
  )
}

Setup

Import Styles

Import the CSS file in your app entry point:

// app/layout.tsx or _app.tsx
import '@entro314labs/entro-zen/styles.css'

Provider

Wrap your app with ZenProvider for theming:

import { ZenProvider } from '@entro314labs/entro-zen'

export default function RootLayout({ children }) {
  return (
    <ZenProvider theme="system">
      {children}
    </ZenProvider>
  )
}

Components

Layout

Box

Basic layout primitive.

import { Box } from '@entro314labs/entro-zen'

<Box padding="4" backgroundColor="gray1" borderRadius="2">
  Content
</Box>

Container

Centered container with max-width.

import { Container } from '@entro314labs/entro-zen'

<Container size="lg">
  Page content
</Container>

Row / Column

Flexbox layouts.

import { Row, Column } from '@entro314labs/entro-zen'

<Row gap="4" align="center">
  <Column flex={1}>Left</Column>
  <Column flex={2}>Right</Column>
</Row>

Grid

CSS Grid layout.

import { Grid } from '@entro314labs/entro-zen'

<Grid columns={3} gap="4">
  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
</Grid>

Forms

TextField

Text input with label and validation.

import { TextField } from '@entro314labs/entro-zen'

<TextField
  label="Email"
  type="email"
  placeholder="you@example.com"
  error="Invalid email"
/>

PasswordField

Password input with visibility toggle.

import { PasswordField } from '@entro314labs/entro-zen'

<PasswordField
  label="Password"
  minLength={8}
/>

SearchField

Search input with clear button.

import { SearchField } from '@entro314labs/entro-zen'

<SearchField
  placeholder="Search..."
  onSearch={(value) => console.log(value)}
/>

Select

Dropdown select.

import { Select } from '@entro314labs/entro-zen'

<Select
  label="Country"
  options={[
    { value: 'us', label: 'United States' },
    { value: 'uk', label: 'United Kingdom' },
  ]}
  onChange={(value) => console.log(value)}
/>

Checkbox

Checkbox with label.

import { Checkbox } from '@entro314labs/entro-zen'

<Checkbox
  label="I agree to the terms"
  checked={agreed}
  onChange={setAgreed}
/>

Switch

Toggle switch.

import { Switch } from '@entro314labs/entro-zen'

<Switch
  label="Enable notifications"
  checked={enabled}
  onChange={setEnabled}
/>

RadioGroup

Radio button group.

import { RadioGroup } from '@entro314labs/entro-zen'

<RadioGroup
  label="Plan"
  options={[
    { value: 'free', label: 'Free' },
    { value: 'pro', label: 'Pro' },
  ]}
  value={plan}
  onChange={setPlan}
/>

Buttons

Button

Primary button component.

import { Button } from '@entro314labs/entro-zen'

<Button variant="primary" size="md">
  Click me
</Button>

<Button variant="secondary" disabled>
  Disabled
</Button>

<Button variant="danger" loading>
  Deleting...
</Button>

Variants: primary, secondary, outline, ghost, danger Sizes: sm, md, lg

LoadingButton

Button with loading state.

import { LoadingButton } from '@entro314labs/entro-zen'

<LoadingButton
  loading={isSubmitting}
  onClick={handleSubmit}
>
  Save Changes
</LoadingButton>

CopyButton

Button that copies text to clipboard.

import { CopyButton } from '@entro314labs/entro-zen'

<CopyButton text="https://example.com/tracking.js" />

Feedback

AlertBanner

Alert message banner.

import { AlertBanner } from '@entro314labs/entro-zen'

<AlertBanner variant="success">
  Website created successfully!
</AlertBanner>

<AlertBanner variant="error" dismissible onDismiss={() => {}}>
  Failed to save changes.
</AlertBanner>

Variants: info, success, warning, error

Toast

Toast notifications via hook.

import { useToast, Toaster } from '@entro314labs/entro-zen'

function App() {
  return (
    <>
      <Toaster />
      <MyComponent />
    </>
  )
}

function MyComponent() {
  const { toast } = useToast()

  return (
    <Button onClick={() => toast.success('Saved!')}>
      Save
    </Button>
  )
}

Loading

Loading spinner.

import { Loading, Spinner } from '@entro314labs/entro-zen'

<Loading /> // Full page loader
<Spinner size="sm" /> // Inline spinner

ProgressBar

Progress indicator.

import { ProgressBar } from '@entro314labs/entro-zen'

<ProgressBar value={75} max={100} />

Overlays

Modal dialog.

import { Modal } from '@entro314labs/entro-zen'

<Modal
  open={isOpen}
  onOpenChange={setIsOpen}
  title="Confirm Delete"
>
  <p>Are you sure you want to delete this website?</p>
  <Button variant="danger" onClick={handleDelete}>
    Delete
  </Button>
</Modal>

Dialog

Alert/confirm dialog.

import { AlertDialog, ConfirmationDialog } from '@entro314labs/entro-zen'

<ConfirmationDialog
  open={isOpen}
  title="Delete Website"
  message="This action cannot be undone."
  confirmLabel="Delete"
  onConfirm={handleDelete}
  onCancel={() => setIsOpen(false)}
/>

Popover

Popover panel.

import { Popover } from '@entro314labs/entro-zen'

<Popover
  trigger={<Button>Options</Button>}
>
  <div>Popover content</div>
</Popover>

Tooltip

Tooltip on hover.

import { Tooltip } from '@entro314labs/entro-zen'

<Tooltip content="Copy to clipboard">
  <CopyButton text="..." />
</Tooltip>

Tabs

Tab navigation.

import { Tabs } from '@entro314labs/entro-zen'

<Tabs
  items={[
    { id: 'overview', label: 'Overview', content: <Overview /> },
    { id: 'events', label: 'Events', content: <Events /> },
    { id: 'settings', label: 'Settings', content: <Settings /> },
  ]}
/>

Dropdown menu.

import { Menu } from '@entro314labs/entro-zen'

<Menu
  trigger={<Button>Actions</Button>}
  items={[
    { label: 'Edit', onClick: handleEdit },
    { label: 'Delete', onClick: handleDelete, variant: 'danger' },
  ]}
/>

Breadcrumb navigation.

import { Breadcrumbs } from '@entro314labs/entro-zen'

<Breadcrumbs
  items={[
    { label: 'Dashboard', href: '/dashboard' },
    { label: 'Websites', href: '/websites' },
    { label: 'example.com' },
  ]}
/>

Data Display

DataTable

Data table with sorting and pagination.

import { DataTable } from '@entro314labs/entro-zen'

<DataTable
  columns={[
    { key: 'name', label: 'Name', sortable: true },
    { key: 'visits', label: 'Visits', sortable: true },
    { key: 'actions', label: '', render: (row) => <Actions row={row} /> },
  ]}
  data={websites}
  pagination={{ page: 1, pageSize: 10 }}
/>

DataCard

Card for displaying metrics.

import { DataCard } from '@entro314labs/entro-zen'

<DataCard
  title="Page Views"
  value="12,345"
  change={+15.2}
  trend="up"
/>

Typography

Heading

Heading component.

import { Heading } from '@entro314labs/entro-zen'

<Heading level={1}>Dashboard</Heading>
<Heading level={2} size="lg">Websites</Heading>

Text

Text component.

import { Text } from '@entro314labs/entro-zen'

<Text size="sm" color="gray11">
  Last updated 5 minutes ago
</Text>

Code / CodeBlock

Code display.

import { Code, CodeBlock } from '@entro314labs/entro-zen'

<Code>npm install @entro314labs/entro-zen</Code>

<CodeBlock language="typescript">
{`const client = new Entrolytics({
  websiteId: 'your-id',
})`}
</CodeBlock>

Theming

Theme Provider

import { ZenProvider } from '@entro314labs/entro-zen'

// Light theme
<ZenProvider theme="light">

// Dark theme
<ZenProvider theme="dark">

// System preference
<ZenProvider theme="system">

Theme Toggle

import { ThemeButton, useTheme } from '@entro314labs/entro-zen'

// Built-in toggle button
<ThemeButton />

// Custom toggle
function CustomToggle() {
  const { theme, setTheme } = useTheme()
  return (
    <Button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
      Toggle Theme
    </Button>
  )
}

CSS Variables

Customize with CSS variables:

:root {
  --zen-primary: #0066cc;
  --zen-radius-sm: 4px;
  --zen-radius-md: 8px;
  --zen-font-sans: 'Inter', sans-serif;
}

Hooks

useTheme

Access theme state.

import { useTheme } from '@entro314labs/entro-zen'

const { theme, setTheme, resolvedTheme } = useTheme()

useToast

Toast notifications.

import { useToast } from '@entro314labs/entro-zen'

const { toast } = useToast()

toast.success('Success!')
toast.error('Error!')
toast.info('Info')
toast.warning('Warning')

useDebounce

Debounced value.

import { useDebounce } from '@entro314labs/entro-zen'

const debouncedSearch = useDebounce(searchTerm, 300)

useBreakpoint

Responsive breakpoints.

import { useBreakpoint } from '@entro314labs/entro-zen'

const { isMobile, isTablet, isDesktop } = useBreakpoint()

Accessibility

All components are built with accessibility in mind:

  • Full keyboard navigation
  • ARIA attributes
  • Focus management
  • Screen reader support
  • Built on React Aria Components

Requirements

  • React >= 18.0.0
  • React DOM >= 18.0.0

License

MIT