@sarunyu/system-one 1.2.0 → 1.3.0
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.
- package/llms.txt +24 -154
- package/package.json +1 -1
package/llms.txt
CHANGED
|
@@ -37,9 +37,6 @@ import "@sarunyu/system-one/styles.css"
|
|
|
37
37
|
|
|
38
38
|
```tsx
|
|
39
39
|
import {
|
|
40
|
-
// Layout primitives (always use these for page structure)
|
|
41
|
-
Page, PageHeader, Section, Toolbar, CardGrid, Stack,
|
|
42
|
-
// Components
|
|
43
40
|
Button, Input, TextArea, SearchInput,
|
|
44
41
|
Dropdown, DropdownMultiple, OptionList,
|
|
45
42
|
Tag, StatusTag, Chip,
|
|
@@ -373,169 +370,42 @@ import type { ButtonVariant, ButtonSize, TagVariant, ChipSize } from "@sarunyu/s
|
|
|
373
370
|
|
|
374
371
|
---
|
|
375
372
|
|
|
376
|
-
##
|
|
373
|
+
## Design Guidance
|
|
377
374
|
|
|
378
|
-
**
|
|
375
|
+
**You design the layout. The library provides the components.** Compose, arrange, and style page structure freely using Tailwind — the library does not dictate layout. Focus instead on using the components below correctly (right variants, right semantics, right props) so the visual language stays consistent with the design system.
|
|
379
376
|
|
|
380
|
-
###
|
|
377
|
+
### Anchors the library provides
|
|
381
378
|
|
|
382
|
-
|
|
379
|
+
These are all you need to keep a page visually coherent with the system:
|
|
383
380
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
<Page width="full"> {/* no max-width */}
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
**`<PageHeader>`** — the top block of a page: title, description, and optional right-side action buttons.
|
|
394
|
-
|
|
395
|
-
```tsx
|
|
396
|
-
<PageHeader
|
|
397
|
-
title="Events"
|
|
398
|
-
description="Browse and register for upcoming events."
|
|
399
|
-
actions={<Button variant="primary" size="md">New event</Button>}
|
|
400
|
-
eyebrow={<Tag text="Live" variant="green" size="small" />}
|
|
401
|
-
/>
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
Props: `title` (required), `description`, `actions`, `eyebrow`.
|
|
405
|
-
|
|
406
|
-
**`<Section>`** — a content block with an optional heading row. Stacks heading + body with the correct gap.
|
|
407
|
-
|
|
408
|
-
```tsx
|
|
409
|
-
<Section title="Upcoming" description="Events in the next 30 days.">
|
|
410
|
-
{/* body content */}
|
|
411
|
-
</Section>
|
|
412
|
-
|
|
413
|
-
<Section title="Filters" actions={<Button variant="plain" size="sm">Reset</Button>}>
|
|
414
|
-
<Toolbar>…</Toolbar>
|
|
415
|
-
</Section>
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
Props: `title`, `description`, `actions`. All optional — omit all for an unlabelled content block.
|
|
419
|
-
|
|
420
|
-
**`<Toolbar>`** — horizontal wrap-friendly row for search, filters, chips. Auto `flex-wrap` so it stays usable on narrow widths.
|
|
421
|
-
|
|
422
|
-
```tsx
|
|
423
|
-
<Toolbar end={<Button variant="outline" size="md">Export</Button>}>
|
|
424
|
-
<SearchInput placeholder="Search…" value={q} onChange={setQ} className="max-w-[320px]" />
|
|
425
|
-
<Chip label="All" selected={f === "all"} onClick={() => setF("all")} />
|
|
426
|
-
<Chip label="Active" selected={f === "active"} onClick={() => setF("active")} />
|
|
427
|
-
</Toolbar>
|
|
428
|
-
```
|
|
381
|
+
- **Typography** — `<h1>`–`<h4>` are pre-styled (size, weight, line-height). Use them as-is; do not add `text-*` or `font-*` classes to override.
|
|
382
|
+
- **Text color** — body text inherits from `--foreground`. Secondary text: `text-muted-foreground`. Don't hard-code hex colors.
|
|
383
|
+
- **Surfaces** — use `bg-background` / `bg-card` / `bg-muted` so dark mode works automatically.
|
|
384
|
+
- **Brand color** — reference via `--primary-action`, or Tailwind `text-primary-action` / `bg-primary-action`.
|
|
385
|
+
- **Spacing** — Tailwind spacing scale (4px units). Pick whatever gaps/paddings look right; the design system has no prescribed rhythm.
|
|
386
|
+
- **Radius** — `rounded-md` (6px), `rounded-lg` (8px), `rounded-xl` (12px), `rounded-full`.
|
|
429
387
|
|
|
430
|
-
|
|
388
|
+
### Component usage — the only hard rules
|
|
431
389
|
|
|
432
|
-
|
|
390
|
+
Use the library's components for these elements. Do **not** recreate them with raw HTML or Tailwind:
|
|
433
391
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
```tsx
|
|
443
|
-
<Stack gap={4}> {/* vertical, 16px gap */}
|
|
444
|
-
<Stack direction="row" gap={3} wrap> {/* horizontal, 12px gap, wraps */}
|
|
445
|
-
<Stack gap={6} align="center" justify="between">
|
|
446
|
-
```
|
|
447
|
-
|
|
448
|
-
Props: `direction` (`"col"` default | `"row"`), `gap` (1, 2, 3, 4, 6, 8, 10, 12 — default 4), `align`, `justify`, `wrap`.
|
|
449
|
-
|
|
450
|
-
### The required page skeleton
|
|
451
|
-
|
|
452
|
-
Every generated page must follow this shape. Replace content — keep the structure.
|
|
392
|
+
- Buttons → `<Button>` (never `<button>` with utility classes)
|
|
393
|
+
- Text inputs / textareas / search → `<Input>`, `<TextArea>`, `<SearchInput>`
|
|
394
|
+
- Single / multi select → `<Dropdown>`, `<DropdownMultiple>`, `<OptionList>`
|
|
395
|
+
- Date / time pickers → `<DateInput>`, `<TimeInput>`
|
|
396
|
+
- Labels / statuses / filters → `<Tag>`, `<StatusTag>`, `<Chip>`
|
|
397
|
+
- Tabs → `<TabGroup>` (never `<Tab>` alone)
|
|
398
|
+
- Event/content cards → `<Card>`
|
|
453
399
|
|
|
454
|
-
|
|
455
|
-
import { Page, PageHeader, Section, Toolbar, CardGrid, Button, SearchInput, Chip, Card } from "@sarunyu/system-one";
|
|
456
|
-
|
|
457
|
-
export default function EventsPage() {
|
|
458
|
-
return (
|
|
459
|
-
<Page>
|
|
460
|
-
<PageHeader
|
|
461
|
-
title="Events"
|
|
462
|
-
description="Browse and register for upcoming events."
|
|
463
|
-
actions={<Button variant="primary" size="md">New event</Button>}
|
|
464
|
-
/>
|
|
465
|
-
|
|
466
|
-
<Toolbar>
|
|
467
|
-
<SearchInput placeholder="Search events…" value={q} onChange={setQ} className="max-w-[320px]" />
|
|
468
|
-
<Chip label="All" selected={filter === "all"} onClick={() => setFilter("all")} />
|
|
469
|
-
<Chip label="This week" selected={filter === "week"} onClick={() => setFilter("week")} />
|
|
470
|
-
</Toolbar>
|
|
471
|
-
|
|
472
|
-
<Section title="Upcoming">
|
|
473
|
-
<CardGrid cols={3}>
|
|
474
|
-
{events.map((e) => <Card key={e.id} variant="desktop" {...e} />)}
|
|
475
|
-
</CardGrid>
|
|
476
|
-
</Section>
|
|
477
|
-
</Page>
|
|
478
|
-
);
|
|
479
|
-
}
|
|
480
|
-
```
|
|
400
|
+
Pick the correct variant / prop for the semantic role (e.g. `StatusTag type="success"` for success, `Button variant="primary"` once per context). The per-component rules below in "Design Rules" are the full reference.
|
|
481
401
|
|
|
482
|
-
###
|
|
402
|
+
### Layout freedom
|
|
483
403
|
|
|
484
|
-
|
|
485
|
-
<Page width="sm">
|
|
486
|
-
<PageHeader title="Sign in" description="Welcome back." />
|
|
487
|
-
<Section>
|
|
488
|
-
<Stack gap={4} className="max-w-[480px]">
|
|
489
|
-
<Input placeholder="Email" value={email} onChange={setEmail} />
|
|
490
|
-
<Input placeholder="Password" type="password" value={pw} onChange={setPw} />
|
|
491
|
-
<Stack direction="row" gap={3}>
|
|
492
|
-
<Button variant="primary" size="md">Sign in</Button>
|
|
493
|
-
<Button variant="outline" size="md">Cancel</Button>
|
|
494
|
-
</Stack>
|
|
495
|
-
</Stack>
|
|
496
|
-
</Section>
|
|
497
|
-
</Page>
|
|
498
|
-
```
|
|
404
|
+
Structure the page however you like — any combination of flex, grid, max-width containers, custom spacing, hero compositions, sidebars, split layouts, dashboards, etc. Use aesthetic judgement: generous padding, clear hierarchy, balanced whitespace. The only layout constraint is that content shouldn't sit flush against viewport edges or adjacent blocks without breathing room.
|
|
499
405
|
|
|
500
|
-
###
|
|
501
|
-
|
|
502
|
-
Do not build a custom hero. Use `PageHeader` with `eyebrow` and `actions` — it already handles title size, description max-width, and action alignment.
|
|
503
|
-
|
|
504
|
-
```tsx
|
|
505
|
-
<Page>
|
|
506
|
-
<PageHeader
|
|
507
|
-
eyebrow={<><Tag text="LIVE" variant="green" size="small" /><Tag text="SET +0.82%" variant="lime" size="small" /></>}
|
|
508
|
-
title="ลงทุนหุ้นอย่างชาญฉลาด ด้วยข้อมูลเรียลไทม์"
|
|
509
|
-
description="ติดตามราคา วิเคราะห์เทคนิคอล รับสัญญาณซื้อขาย บนแพลตฟอร์มเดียว"
|
|
510
|
-
actions={<><Button variant="primary" size="lg">เริ่มต้นใช้งานฟรี</Button><Button variant="outline" size="lg">ดูแผนพรีเมียม</Button></>}
|
|
511
|
-
/>
|
|
512
|
-
{/* rest of page */}
|
|
513
|
-
</Page>
|
|
514
|
-
```
|
|
406
|
+
### Optional: layout helper components
|
|
515
407
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
- **Do** always wrap a page in `<Page>`. Never return a naked `<div>` or `<main>` at the top level.
|
|
519
|
-
- **Do** use `<PageHeader>` for the page title — never hand-roll `<h1>` + description + buttons.
|
|
520
|
-
- **Do** use `<Section>` for each content block. Stack multiple `<Section>` children directly inside `<Page>` — the gap is automatic.
|
|
521
|
-
- **Do** use `<Toolbar>` for search/filter rows and `<CardGrid>` for card collections.
|
|
522
|
-
- **Don't** add manual spacing like `mt-8` / `mb-12` between sections — `<Page>` already provides section gap.
|
|
523
|
-
- **Don't** wrap `<Section>` in another flex container — it breaks the rhythm.
|
|
524
|
-
- **Don't** override heading sizes with utility classes — `h1`–`h4` inside these primitives are already sized.
|
|
525
|
-
- **Don't** use `max-w-*` on `<Page>` via className — use the `width` prop instead.
|
|
526
|
-
|
|
527
|
-
### Spacing scale (used internally by primitives — reference only)
|
|
528
|
-
|
|
529
|
-
| Purpose | Value |
|
|
530
|
-
|---|---|
|
|
531
|
-
| Between label and input | gap-1 / gap-2 (4–8px) |
|
|
532
|
-
| Between fields in a form | gap-4 (16px) — default `<Stack>` |
|
|
533
|
-
| Between heading and content | gap-6 (24px) — built into `<Section>` |
|
|
534
|
-
| Between top-level sections | gap-12 (48px) — built into `<Page>` |
|
|
535
|
-
| Page horizontal padding | px-6 md:px-8 — built into `<Page>` |
|
|
536
|
-
| Page vertical padding | py-10 — built into `<Page>` |
|
|
537
|
-
|
|
538
|
-
If you need a custom gap, use `<Stack gap={N}>` with a value from: 1, 2, 3, 4, 6, 8, 10, 12.
|
|
408
|
+
The library also ships a small set of layout primitives (`Page`, `PageHeader`, `Section`, `Toolbar`, `CardGrid`, `Stack`) that some users prefer for rapid scaffolding. They are entirely optional — skip them and design your own layout if that produces a better result. If you do use them, they apply sensible defaults (centered container, 48px section gap, responsive card grid). Full API is in the TypeScript types.
|
|
539
409
|
|
|
540
410
|
---
|
|
541
411
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sarunyu/system-one",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A production-ready React design system built for AI-powered web generation tools (Figma Make, Lovable, V0). Tailwind CSS v4 + CSS custom properties for full theming support.",
|
|
6
6
|
"keywords": [
|