learning_ai_common_plat/packages/ui
Saravana Achu Mac 8f541c9f87 chore(audit): unblock workspace lint pipeline + 13 mechanical fixes
The first `pnpm -r exec eslint .` run was bailing at the very first
package (design-tokens), hiding any lint state in the rest of the 69
workspace packages. This commit fixes the structural blockers so the
pipeline runs end-to-end, then sweeps the small, low-risk lint errors
in the next 4 packages it surfaces. Real lint debt that remains
(85 errors, mostly @typescript-eslint/no-unused-vars across many
unrelated packages) is cataloged in docs/AUDIT_PLATFORM.md for follow-
up by package owners.

Structural fixes (eslint config):
  - eslint.config.js (root):
      • New flat-config block for **/*.cjs and **/scripts/**/*.{js,cjs}
        with Node globals (process, console, require, module, __dirname)
        and no-console disabled. CLI scripts legitimately print to
        stdout. This alone clears the 45 errors in design-tokens'
        validate-tokens.cjs.
      • Added XMLHttpRequest + ProgressEvent to browser globals so
        feedback-client compiles.
  - packages/ui/eslint.config.js:
      • Added @typescript-eslint/parser — the package-local override
        replaced (didn't merge with) the root config, so TS syntax was
        being parsed by espree and erroring on every `interface` /
        type import.
      • Added ignores for dist/** (root's ignores aren't inherited).
      • Extended the files glob to .storybook/**/*.{ts,tsx}.

Mechanical lint fixes (no behaviour change):
  - design-tokens/scripts/{validate,token-coverage}.cjs: empty catch
    binding (catch (e) → catch).
  - feedback-client/src/index.ts:
      • captureScreen(): preserve caught error via `{ cause: err }`
        on the rethrown Error (preserve-caught-error rule, real bug —
        previous chain dropped the original stack).
      • captureElement(): rename unused parity params mimeType/quality
        to _mimeType/_quality and document why they exist.
  - logger/__tests__/logger.test.ts: drop unused `LoggerConfig` import.
  - extraction-service/{lib/circuit-breaker,modules/extract/{sidecar-
    monitor,usage}}.test.ts: drop 3 unused vitest/type imports.
  - tracker-web/__tests__/tracker-proxy.test.ts: rename unused local
    `url` → `_url`.

New: docs/AUDIT_PLATFORM.md
  Tooling-backed audit summary (pnpm install / typecheck / test / lint
  results), classification of remaining lint debt by rule, and an
  ordered hand-off plan for package owners to clear the rest with
  `pnpm --filter <pkg> lint:fix` followed by an eyeball review.

Verified before commit:
  - `pnpm typecheck` → pass (all 69 packages compile)
  - `pnpm test`      → pass (~2,200 tests across 18+ suites)
  - `pnpm lint`      → 85 pre-existing errors surfaced (none introduced
    by this commit; all in unrelated packages — see AUDIT_PLATFORM.md
    section P).

Out of scope (left untouched in working tree):
  - In-progress nomgap-on-Vercel migration: docker-compose.ecosystem.yml,
    products/nomgap/product.json, services/platform-service/src/
    modules/flags/seed.ts.
  - pnpm-lock.yaml: my `pnpm install -r` regenerated it (+2.9k/-8.5k
    lines) — not part of the audit, owner should commit deliberately.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 14:21:34 -07:00
..
.storybook feat(ui): add Storybook for @bytelyst/ui component library 2026-03-28 00:59:25 -07:00
src fix(ui): use extensionless imports + bundler resolution for source-consumed package 2026-03-29 02:03:48 -07:00
eslint.config.js chore(audit): unblock workspace lint pipeline + 13 mechanical fixes 2026-05-04 14:21:34 -07:00
package.json refactor(gitea): robust manifest-based publish pipeline 2026-04-13 01:47:03 -07:00
README.md feat(ui): add Sidebar, StatCard, LoadingSpinner components + README docs — Level 3 component coverage 2026-03-29 00:19:45 -07:00
tsconfig.json chore(platform): align docker and package outputs 2026-03-29 23:41:08 +00:00

@bytelyst/ui

Shared component library for the ByteLyst ecosystem. Built with Radix UI primitives, Lucide icons, and CSS custom properties from @bytelyst/design-tokens.

Install

pnpm add @bytelyst/ui

Peer dependencies: react, react-dom.

Components (15)

Button

5 variants (primary, secondary, ghost, destructive, outline), 3 sizes, loading state with spinner.

import { Button } from '@bytelyst/ui';

<Button variant="primary" size="md" loading={saving}>Save</Button>
<Button variant="destructive" onClick={onDelete}>Delete</Button>
<Button variant="ghost" size="sm">Cancel</Button>

Input

Text input with error/success states. Supports aria-invalid automatically when error is truthy.

import { Input } from '@bytelyst/ui';

<Input placeholder="Email" type="email" />
<Input error="Required field" />

Textarea

Auto-resize textarea with error states.

import { Textarea } from '@bytelyst/ui';

<Textarea placeholder="Description" rows={4} />;

Select

Styled <select> with keyboard navigation.

import { Select } from '@bytelyst/ui';

<Select
  options={[
    { value: 'a', label: 'Option A' },
    { value: 'b', label: 'Option B' },
  ]}
  value={selected}
  onChange={setSelected}
/>;

Modal / Dialog

Radix @radix-ui/react-dialog with focus trap, Esc close, and aria-modal.

import { Modal } from '@bytelyst/ui';

<Modal open={isOpen} onOpenChange={setOpen} title="Edit item">
  <p>Modal content here</p>
</Modal>;

ConfirmDialog

Radix AlertDialog for destructive/warning confirmations. Supports async onConfirm.

import { ConfirmDialog } from '@bytelyst/ui';

<ConfirmDialog
  open={showConfirm}
  onOpenChange={setShowConfirm}
  title="Delete item?"
  description="This action cannot be undone."
  onConfirm={handleDelete}
  variant="destructive"
/>;

Toast

4 types (success, error, warning, info), auto-dismiss, role="alert". Use ToastProvider in your root layout and toast() anywhere.

import { ToastProvider, toast } from '@bytelyst/ui';

// In providers.tsx
<ToastProvider>{children}</ToastProvider>;

// Anywhere in app
toast('Saved successfully', 'success');
toast('Something went wrong', 'error');

Card

Container with default, elevated, and interactive variants. Includes CardHeader, CardTitle, CardDescription sub-components.

import { Card, CardHeader, CardTitle, CardDescription } from '@bytelyst/ui';

<Card>
  <CardHeader>
    <CardTitle>Dashboard</CardTitle>
    <CardDescription>Overview of your data</CardDescription>
  </CardHeader>
  {children}
</Card>;

Badge

Status/count/risk-level badges, color-coded by semantic tokens.

import { Badge } from '@bytelyst/ui';

<Badge variant="success">Active</Badge>
<Badge variant="danger">Critical</Badge>
<Badge variant="warning" count={5} />

EmptyState

Placeholder for empty lists with icon, description, and optional CTA.

import { EmptyState } from '@bytelyst/ui';

<EmptyState
  icon={<FileText size={48} />}
  title="No items yet"
  description="Create your first item to get started."
  action={<Button onClick={onCreate}>Create</Button>}
/>;

Label

Styled form label.

import { Label } from '@bytelyst/ui';

<Label htmlFor="email">Email address</Label>;

Separator

Horizontal/vertical divider.

import { Separator } from '@bytelyst/ui';

<Separator />
<Separator orientation="vertical" />

Sidebar

Responsive collapsible sidebar with mobile toggle, overlay, and navigation items.

import { Sidebar, SidebarItem } from '@bytelyst/ui';

<Sidebar
  collapsed={collapsed}
  onToggle={() => setCollapsed(!collapsed)}
  header={<span>MyApp</span>}
  footer="v1.0.0"
>
  <SidebarItem href="/dashboard" label="Dashboard" icon={<Home size={18} />} active />
  <SidebarItem href="/settings" label="Settings" icon={<Settings size={18} />} />
</Sidebar>;

StatCard

Dashboard metric card with trend indicator.

import { StatCard } from '@bytelyst/ui';

<StatCard label="Total Users" value="1,234" trend="up" trendValue="+12%" />
<StatCard label="Errors" value={42} trend="down" trendValue="-8%" icon={<AlertCircle />} />

LoadingSpinner

Accessible loading indicator with aria-busy and prefers-reduced-motion support.

import { LoadingSpinner } from '@bytelyst/ui';

<LoadingSpinner size="md" label="Loading data…" />
<LoadingSpinner size="sm" label="" />  {/* spinner only, no text */}

Design Token Integration

All components use CSS custom properties with --bl- prefix and sensible fallbacks. Override them per-product:

:root {
  --bl-accent: var(--jj-accent); /* JarvisJr */
  --bl-surface-card: var(--fm-surface); /* FlowMonk */
}

Accessibility

Every component includes:

  • focus-visible ring styles
  • ARIA attributes (aria-label, aria-modal, aria-busy, aria-invalid, aria-current)
  • Keyboard navigation (Esc to close, Tab focus trap in modals)
  • prefers-reduced-motion respected via Tailwind's animate-spin

Storybook

pnpm --filter @bytelyst/ui storybook

Storybook is configured with @storybook/addon-a11y for automated accessibility checks.