@engrate/components 0.1.11 → 0.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,625 @@
1
+ ---
2
+ name: engrate-components
3
+ description: Use and integrate Engrate's React component library in applications. This skill covers importing components, using design tokens, and building UIs with the library. Use when building user interfaces that consume @engrate/components, styling applications with Engrate's design system, or integrating the component library into React projects.
4
+ ---
5
+
6
+ # Engrate Components Library
7
+
8
+ ## Overview
9
+
10
+ `@engrate/components` is a React component library implementing Engrate's design system. Built with TypeScript, Tailwind CSS v4, and accessible by default.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @engrate/components
16
+ ```
17
+
18
+ Peer dependencies (React 18 or 19):
19
+
20
+ ```bash
21
+ npm install react react-dom
22
+ ```
23
+
24
+ ## Basic Setup
25
+
26
+ ### Importing Styles
27
+
28
+ Always import the component styles in your application:
29
+
30
+ ```tsx
31
+ import '@engrate/components/styles.css'
32
+ ```
33
+
34
+ ### With Tailwind CSS v4
35
+
36
+ If your project uses Tailwind CSS v4, import in your CSS file to get access to all design tokens:
37
+
38
+ ```css
39
+ @import 'tailwindcss';
40
+ @import '@engrate/components/styles.css';
41
+ ```
42
+
43
+ ## Available Components
44
+
45
+ ### Layout Components
46
+
47
+ | Component | Purpose |
48
+ | ------------- | ---------------------------------------- |
49
+ | `Stack` | Vertical/horizontal flex layout with gap |
50
+ | `Grid` | CSS Grid layout wrapper |
51
+ | `Card` | Container with border and background |
52
+ | `Divider` | Visual separator line |
53
+ | `EngrateLogo` | Brand logo with compact mode (icon only) |
54
+
55
+ ### Typography Components
56
+
57
+ | Component | Purpose |
58
+ | --------- | ------------------------------- |
59
+ | `Heading` | h1-h6 headings with brand fonts |
60
+ | `Text` | Body text with size variants |
61
+ | `Eyebrow` | Small uppercase label text |
62
+ | `Link` | Styled anchor element |
63
+
64
+ ### Form Components
65
+
66
+ | Component | Purpose |
67
+ | ---------------- | --------------------------- |
68
+ | `Button` | Primary action element |
69
+ | `Input` | Text input field |
70
+ | `Textarea` | Multi-line text input |
71
+ | `Checkbox` | Boolean input |
72
+ | `Radio` | Single selection from group |
73
+ | `Slider` | Value selection via drag |
74
+ | `Switch` | Toggle on/off |
75
+ | `Select` | Dropdown selection |
76
+ | `DatePicker` | Date selection |
77
+ | `DateTimePicker` | Date and time selection |
78
+ | `Label` | Form field label |
79
+ | `FormField` | Field wrapper with label |
80
+ | `FormMessage` | Validation message display |
81
+
82
+ ### Feedback Components
83
+
84
+ | Component | Purpose |
85
+ | ------------------- | ------------------------- |
86
+ | `Toast` | Temporary notification |
87
+ | `Banner` | Persistent message banner |
88
+ | `Badge` | Status indicator |
89
+ | `Spinner` | Loading indicator |
90
+ | `Skeleton` | Content placeholder |
91
+ | `ProgressIndicator` | Progress visualization |
92
+
93
+ ### Navigation Components
94
+
95
+ | Component | Purpose |
96
+ | ------------- | ----------------------------------- |
97
+ | `Breadcrumbs` | Navigation path |
98
+ | `TabList` | Tab navigation |
99
+ | `Pagination` | Page navigation |
100
+ | `Sidebar` | Collapsible application sidebar nav |
101
+ | `Header` | Page header with logo and nav |
102
+ | `Footer` | Page footer with links and info |
103
+
104
+ ### Overlay Components
105
+
106
+ | Component | Purpose |
107
+ | -------------- | ------------------- |
108
+ | `Modal` | Dialog overlay |
109
+ | `AlertDialog` | Confirmation dialog |
110
+ | `Tooltip` | Hover information |
111
+ | `DropdownMenu` | Action menu |
112
+ | `ContextMenu` | Right-click menu |
113
+
114
+ ### Data Display Components
115
+
116
+ | Component | Purpose |
117
+ | ----------- | -------------------- |
118
+ | `Table` | Tabular data |
119
+ | `Accordion` | Collapsible sections |
120
+ | `BarChart` | Bar chart |
121
+ | `LineChart` | Line chart |
122
+ | `PieChart` | Pie chart |
123
+
124
+ ## Component Usage Patterns
125
+
126
+ ### Basic Import and Use
127
+
128
+ ```tsx
129
+ import { Button, Card, Heading, Text, Stack } from '@engrate/components'
130
+
131
+ function MyComponent() {
132
+ return (
133
+ <Card>
134
+ <Stack gap="md">
135
+ <Heading level="h2">Welcome</Heading>
136
+ <Text>This is a card with stacked content.</Text>
137
+ <Button variant="primary">Get Started</Button>
138
+ </Stack>
139
+ </Card>
140
+ )
141
+ }
142
+ ```
143
+
144
+ ### Button Variants
145
+
146
+ ```tsx
147
+ import { Button } from '@engrate/components'
148
+
149
+ // Primary (Sunflower yellow background)
150
+ <Button variant="primary">Primary Action</Button>
151
+
152
+ // Secondary (bordered, transparent)
153
+ <Button variant="secondary">Secondary</Button>
154
+
155
+ // Ghost (no background)
156
+ <Button variant="ghost">Ghost</Button>
157
+
158
+ // Sizes: sm, default, lg, icon
159
+ <Button size="lg">Large Button</Button>
160
+
161
+ // As child (for Next.js Link, etc.)
162
+ <Button asChild>
163
+ <a href="/page">Link Button</a>
164
+ </Button>
165
+ ```
166
+
167
+ ### Form Layout
168
+
169
+ ```tsx
170
+ import { FormField, Input, Button, Stack } from '@engrate/components'
171
+
172
+ function LoginForm() {
173
+ return (
174
+ <form>
175
+ <Stack gap="lg">
176
+ <FormField label="Email" htmlFor="email">
177
+ <Input id="email" type="email" placeholder="you@example.com" />
178
+ </FormField>
179
+ <FormField label="Password" htmlFor="password">
180
+ <Input id="password" type="password" />
181
+ </FormField>
182
+ <Button type="submit" variant="primary">
183
+ Sign In
184
+ </Button>
185
+ </Stack>
186
+ </form>
187
+ )
188
+ }
189
+ ```
190
+
191
+ ### Typography Hierarchy
192
+
193
+ ```tsx
194
+ import { Heading, Text, Eyebrow, Stack } from '@engrate/components'
195
+ ;<Stack gap="md">
196
+ <Eyebrow>Category</Eyebrow>
197
+ <Heading level="hero">Hero Title</Heading>
198
+ <Heading level="h1">Page Title</Heading>
199
+ <Text variant="lead">Lead paragraph with larger text.</Text>
200
+ <Text variant="semi-lead">Semi lead paragraph.</Text>
201
+ <Text variant="body">Regular body text for content.</Text>
202
+ <Text variant="descriptive">Descriptive smaller text.</Text>
203
+ </Stack>
204
+ ```
205
+
206
+ ### Layout with Grid
207
+
208
+ ```tsx
209
+ import { Grid, Card } from '@engrate/components'
210
+ ;<Grid cols={3} gap="lg">
211
+ <Card>Column 1</Card>
212
+ <Card>Column 2</Card>
213
+ <Card>Column 3</Card>
214
+ </Grid>
215
+ ```
216
+
217
+ ### Modal Dialog
218
+
219
+ ```tsx
220
+ import {
221
+ Modal,
222
+ ModalTrigger,
223
+ ModalContent,
224
+ ModalHeader,
225
+ ModalTitle,
226
+ ModalDescription,
227
+ ModalFooter,
228
+ ModalClose,
229
+ Button,
230
+ Stack,
231
+ Text,
232
+ } from '@engrate/components'
233
+
234
+ function Example() {
235
+ return (
236
+ <Modal>
237
+ <ModalTrigger asChild>
238
+ <Button>Open Modal</Button>
239
+ </ModalTrigger>
240
+ <ModalContent>
241
+ <ModalHeader>
242
+ <ModalTitle>Confirm Action</ModalTitle>
243
+ <ModalDescription>This action cannot be undone.</ModalDescription>
244
+ </ModalHeader>
245
+ <Text>Are you sure you want to proceed?</Text>
246
+ <ModalFooter>
247
+ <ModalClose asChild>
248
+ <Button variant="secondary">Cancel</Button>
249
+ </ModalClose>
250
+ <Button variant="primary">Confirm</Button>
251
+ </ModalFooter>
252
+ </ModalContent>
253
+ </Modal>
254
+ )
255
+ }
256
+ ```
257
+
258
+ ### Sidebar Navigation
259
+
260
+ ```tsx
261
+ import {
262
+ Sidebar,
263
+ SidebarContent,
264
+ SidebarFooter,
265
+ SidebarGroup,
266
+ SidebarGroupLabel,
267
+ SidebarHeader,
268
+ SidebarItem,
269
+ SidebarSeparator,
270
+ SidebarTrigger,
271
+ EngrateLogo,
272
+ } from '@engrate/components'
273
+ import { Home, Settings, BarChart3, LogOut } from 'lucide-react'
274
+
275
+ function AppLayout() {
276
+ return (
277
+ <div style={{ display: 'flex', height: '100vh' }}>
278
+ <Sidebar aria-label="Main navigation">
279
+ <SidebarHeader>
280
+ <EngrateLogo size="sm" compact />
281
+ </SidebarHeader>
282
+ <SidebarContent>
283
+ <SidebarGroup>
284
+ <SidebarGroupLabel>Main</SidebarGroupLabel>
285
+ <SidebarItem icon={<Home className="h-4 w-4" />} active>
286
+ Dashboard
287
+ </SidebarItem>
288
+ <SidebarItem icon={<BarChart3 className="h-4 w-4" />}>
289
+ Analytics
290
+ </SidebarItem>
291
+ </SidebarGroup>
292
+ <SidebarSeparator />
293
+ <SidebarGroup>
294
+ <SidebarGroupLabel>Settings</SidebarGroupLabel>
295
+ <SidebarItem icon={<Settings className="h-4 w-4" />}>
296
+ Preferences
297
+ </SidebarItem>
298
+ </SidebarGroup>
299
+ </SidebarContent>
300
+ <SidebarFooter>
301
+ <SidebarItem icon={<LogOut className="h-4 w-4" />}>
302
+ Logout
303
+ </SidebarItem>
304
+ </SidebarFooter>
305
+ </Sidebar>
306
+ <main className="flex-1 p-6">{/* Main content */}</main>
307
+ </div>
308
+ )
309
+ }
310
+ ```
311
+
312
+ ### Header and Footer
313
+
314
+ ```tsx
315
+ import {
316
+ Header,
317
+ HeaderLogo,
318
+ HeaderNav,
319
+ HeaderActions,
320
+ Footer,
321
+ FooterContent,
322
+ FooterSection,
323
+ FooterHeading,
324
+ FooterLinks,
325
+ FooterBottom,
326
+ FooterCopyright,
327
+ EngrateLogo,
328
+ Button,
329
+ Link,
330
+ } from '@engrate/components'
331
+
332
+ function PageLayout() {
333
+ return (
334
+ <>
335
+ <Header sticky>
336
+ <HeaderLogo>
337
+ <EngrateLogo />
338
+ </HeaderLogo>
339
+ <HeaderNav>
340
+ <Link variant="nav" href="/about">
341
+ About
342
+ </Link>
343
+ <Link variant="nav" href="/services">
344
+ Services
345
+ </Link>
346
+ </HeaderNav>
347
+ <HeaderActions>
348
+ <Button variant="primary">Sign In</Button>
349
+ </HeaderActions>
350
+ </Header>
351
+
352
+ <main>{/* Page content */}</main>
353
+
354
+ <Footer>
355
+ <FooterContent>
356
+ <FooterSection>
357
+ <FooterHeading>Company</FooterHeading>
358
+ <FooterLinks>
359
+ <Link href="/about">About</Link>
360
+ <Link href="/careers">Careers</Link>
361
+ </FooterLinks>
362
+ </FooterSection>
363
+ </FooterContent>
364
+ <FooterBottom>
365
+ <FooterCopyright>© 2026 Engrate</FooterCopyright>
366
+ </FooterBottom>
367
+ </Footer>
368
+ </>
369
+ )
370
+ }
371
+ ```
372
+
373
+ ## Design Tokens
374
+
375
+ The library exposes CSS custom properties for use in custom components.
376
+
377
+ ### Colors
378
+
379
+ | Token | Usage |
380
+ | ------------------------------- | ------------------------ |
381
+ | `--color-sunflower` | Primary brand color |
382
+ | `--color-sunflower-hover` | Sunflower hover state |
383
+ | `--color-primary` | Primary text color |
384
+ | `--color-secondary` | Secondary text color |
385
+ | `--color-tertiary` | Tertiary text color |
386
+ | `--color-main` (background) | Main page background |
387
+ | `--color-alt` (background) | Alternative background |
388
+ | `--color-card` (background) | Card background |
389
+ | `--color-contrast` (background) | High contrast background |
390
+ | `--color-border` | Border color |
391
+ | `--color-error` | Error state color |
392
+
393
+ ### Typography
394
+
395
+ | Token | Usage |
396
+ | ---------------- | ---------------------------- |
397
+ | `--font-display` | Libre Baskerville (headings) |
398
+ | `--font-sans` | Work Sans (body text) |
399
+ | `--font-mono` | IBM Plex Mono (code) |
400
+
401
+ ### Using Tokens in Custom Components
402
+
403
+ ```tsx
404
+ // With Tailwind CSS v4 (tokens are auto-detected)
405
+ function CustomCard({ children }) {
406
+ return (
407
+ <div className="bg-card border-border text-primary rounded-lg border p-4">
408
+ {children}
409
+ </div>
410
+ )
411
+ }
412
+
413
+ // Using CSS custom properties directly
414
+ function CustomBanner() {
415
+ return (
416
+ <div
417
+ style={{
418
+ backgroundColor: 'var(--color-sunflower)',
419
+ color: 'var(--color-primary)',
420
+ }}
421
+ >
422
+ Custom styled banner
423
+ </div>
424
+ )
425
+ }
426
+ ```
427
+
428
+ ## Common Patterns
429
+
430
+ ### Responsive Layouts
431
+
432
+ ```tsx
433
+ <Grid cols={{ base: 1, md: 2, lg: 3 }} gap="lg">
434
+ {items.map((item) => (
435
+ <Card key={item.id}>{item.content}</Card>
436
+ ))}
437
+ </Grid>
438
+ ```
439
+
440
+ ### Loading States
441
+
442
+ ```tsx
443
+ import { Skeleton, Spinner, Stack } from '@engrate/components'
444
+
445
+ // Skeleton for content placeholders
446
+ <Stack gap="sm">
447
+ <Skeleton width="60%" height="1.5rem" />
448
+ <Skeleton width="100%" height="1rem" />
449
+ <Skeleton width="80%" height="1rem" />
450
+ </Stack>
451
+
452
+ // Spinner for loading indicators
453
+ <Spinner size="lg" />
454
+ ```
455
+
456
+ ### Toast Notifications
457
+
458
+ ```tsx
459
+ import {
460
+ Toast,
461
+ ToastProvider,
462
+ ToastViewport,
463
+ ToastTitle,
464
+ ToastDescription,
465
+ ToastClose,
466
+ Button,
467
+ } from '@engrate/components'
468
+ import { useState } from 'react'
469
+
470
+ function Example() {
471
+ const [open, setOpen] = useState(false)
472
+
473
+ return (
474
+ <ToastProvider>
475
+ <Button
476
+ onClick={() => {
477
+ setOpen(true)
478
+ setTimeout(() => setOpen(false), 3000)
479
+ }}
480
+ >
481
+ Save
482
+ </Button>
483
+ <Toast open={open} onOpenChange={setOpen} variant="success">
484
+ <div className="grid gap-1">
485
+ <ToastTitle>Success</ToastTitle>
486
+ <ToastDescription>Your changes have been saved.</ToastDescription>
487
+ </div>
488
+ <ToastClose />
489
+ </Toast>
490
+ <ToastViewport />
491
+ </ToastProvider>
492
+ )
493
+ }
494
+ ```
495
+
496
+ ## Accessibility
497
+
498
+ All components are built with accessibility in mind:
499
+
500
+ - Proper ARIA attributes
501
+ - Keyboard navigation support
502
+ - Focus management
503
+ - Screen reader friendly
504
+
505
+ ## TypeScript Support
506
+
507
+ All components export their prop types:
508
+
509
+ ```tsx
510
+ import { Button, type ButtonProps } from '@engrate/components'
511
+
512
+ // Use types for custom wrappers
513
+ interface MyButtonProps extends ButtonProps {
514
+ loading?: boolean
515
+ }
516
+ ```
517
+
518
+ ## Layout Guidelines
519
+
520
+ Follow these layout principles when building UIs with Engrate components:
521
+
522
+ ### Text Alignment & Width
523
+
524
+ - **Always left-align text** — creates clarity and readability
525
+ - **Body text max 65 characters wide** — use `max-width: 65ch` or equivalent
526
+ - Heading should be **at least twice as large** as body text
527
+
528
+ ### Spacing & Grid
529
+
530
+ - **Grid spacing should be 50% tighter than typical defaults** — creates cohesive layouts
531
+ - **Even margins** — equal margins to top and left side creates natural squares
532
+ - **Card headline-to-body gap** — use 100% of body text line height for breathing room
533
+
534
+ ### Content Width
535
+
536
+ - Tables, charts, and text blocks should be ~60-70% of container width (not full width)
537
+ - Keep content blocks relatively **square in proportion** — avoid ultra-wide, thin layouts
538
+ - Exception: photographs may span full width as backgrounds or hero images
539
+
540
+ ### Backgrounds
541
+
542
+ - **Never use pure white (#FFFFFF)** for backgrounds
543
+ - Use light gray backgrounds: `bg-main` (#FAFAFA), `bg-alt` (#F5F5F5), `bg-card` (#F9F9F9)
544
+ - Light yellow backgrounds (Vanilla, Eggshell) can highlight sections
545
+
546
+ ## Spacing
547
+
548
+ The component library uses a consistent spacing scale based on Tailwind's default values.
549
+
550
+ ### Gap Values
551
+
552
+ Use `Stack` and `Grid` components with the `gap` prop:
553
+
554
+ | Gap | Value | Tailwind | Use Case |
555
+ | ----- | ------- | -------- | ---------------------------------- |
556
+ | `xs` | 0.25rem | `gap-1` | Tight spacing (icon + label) |
557
+ | `sm` | 0.5rem | `gap-2` | Compact layouts |
558
+ | `md` | 1rem | `gap-4` | Default spacing (cards, form rows) |
559
+ | `lg` | 1.5rem | `gap-6` | Section spacing |
560
+ | `xl` | 2rem | `gap-8` | Major sections |
561
+ | `2xl` | 3rem | `gap-12` | Page sections |
562
+
563
+ ### Spacing Guidelines
564
+
565
+ ```tsx
566
+ // Form fields — use md gap
567
+ <Stack gap="md">
568
+ <FormField label="Name"><Input /></FormField>
569
+ <FormField label="Email"><Input /></FormField>
570
+ </Stack>
571
+
572
+ // Button groups — use sm gap
573
+ <Stack direction="horizontal" gap="sm">
574
+ <Button variant="secondary">Cancel</Button>
575
+ <Button variant="primary">Save</Button>
576
+ </Stack>
577
+
578
+ // Page sections — use xl or 2xl gap
579
+ <Stack gap="xl">
580
+ <section>Hero content</section>
581
+ <section>Features</section>
582
+ </Stack>
583
+ ```
584
+
585
+ ### Brand Spacing Rules
586
+
587
+ - **Grid spacing 50% tighter than defaults** — prefer `sm` over `md`, `md` over `lg`
588
+ - **Card headline-to-body gap** — use 100% of body text line height
589
+ - **Even margins** — equal top and left margins create natural squares
590
+
591
+ ## Design Rules
592
+
593
+ Critical rules to maintain brand consistency:
594
+
595
+ ### Color Usage
596
+
597
+ | Rule | Description |
598
+ | ------------------------ | ------------------------------------------------------------------------------ |
599
+ | **10/90 Rule** | 10% color, 90% grayscale — colors look best when used sparingly |
600
+ | **No colored text** | All text must be grayscale only — never use Sunflower or other colors for text |
601
+ | **Sunflower is primary** | When only one color can be used, use Sunflower (#FFBE26) |
602
+
603
+ ### Typography
604
+
605
+ | Rule | Description |
606
+ | ----------------------- | ------------------------------------------------------------- |
607
+ | **-5% letter spacing** | All text above 10pt uses -5% tracking (built into components) |
608
+ | **Libre Baskerville** | Only for hero headings ≥60pt |
609
+ | **Work Sans Regular** | Everything else — no Bold, Medium, or Light weights allowed |
610
+ | **Grayscale text only** | Prioritize black (#1A1A1A), use gray only for hierarchy |
611
+
612
+ ### Design Checklist
613
+
614
+ Before shipping, verify:
615
+
616
+ - [ ] Following 10/90 color vs grayscale ratio
617
+ - [ ] All text is grayscale (no colored text)
618
+ - [ ] Text is left-aligned
619
+ - [ ] Body text max 65 characters wide
620
+ - [ ] Using light gray backgrounds, not pure white
621
+
622
+ ## Related Resources
623
+
624
+ - **Storybook Documentation**: Interactive component examples at https://engrate.github.io/eg-components
625
+ - **Design Guidelines**: See `.github/skills/engrate-designer/SKILL.md` for brand and design tokens
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@engrate/components",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Engrate Component Library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs.js",
@@ -19,11 +19,12 @@
19
19
  "require": "./dist/index.cjs.js"
20
20
  },
21
21
  "./styles.css": "./dist/styles.css",
22
- "./fonts/*": "./dist/fonts/*"
22
+ "./fonts/*": "./dist/fonts/*",
23
+ "./skills/engrate-component-user.md": "./dist/skills/engrate-component-user.md"
23
24
  },
24
25
  "scripts": {
25
26
  "dev": "storybook dev -p 6006",
26
- "build": "tsc -p tsconfig.app.json && vite build",
27
+ "build": "tsc -p tsconfig.app.json && vite build && mkdir -p dist/skills && cp SKILL.md dist/skills/engrate-component-user.md",
27
28
  "test": "vitest run",
28
29
  "test:watch": "vitest",
29
30
  "test:coverage": "vitest run --coverage",