@sarunyu/system-one 4.9.30 → 4.9.33

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @sarunyu/system-one — AI usage guide
2
2
 
3
- React component library. Tailwind CSS v4 + CSS custom properties. 24 components.
3
+ React component library. Tailwind CSS v4 + CSS custom properties. 30 components.
4
4
  Built for AI-powered UI generation (v0, Lovable, Figma Make, Cursor).
5
5
 
6
6
  **This file is the contract.** Read it top-to-bottom before generating any screen
@@ -12,7 +12,7 @@ that uses this library. The rules are non-negotiable.
12
12
 
13
13
  1. **Use library components for every element it provides.** Never recreate
14
14
  Button, Input, Tag, Dropdown, Card, Tab, Checkbox, Toggle, Radio, DateInput, TimeInput,
15
- Table, SearchInput, TextArea, Chip, Modal, BottomSheet, Alert, Toast, Notification, Badge, Avatar, AvatarStack as raw HTML.
15
+ Table, SearchInput, TextArea, Chip, Modal, BottomSheet, Alert, Toast, Notification, Badge, Avatar, AvatarStack, Breadcrumb, Tooltip, Popover as raw HTML.
16
16
  2. **Never override a component's built-in styles.** Every library component manages its own colors, shadows, padding, radius, and typography internally. Only use `className` on library components for **layout** (`w-*`, `max-w-*`, `flex`, `grid`, `gap-*`, `m-*`, `col-span-*`). Never pass `bg-*`, `shadow-*`, `text-*`, `p-*`, `rounded-*`, or `border-*` in `className` on a library component.
17
17
  3. **Use design-token classes for color and typography.** Never `text-blue-600`,
18
18
  `bg-gray-100`, `text-[#3b82f6]`. The token table below is exhaustive — if a
@@ -142,6 +142,9 @@ import {
142
142
  Dropdown, DropdownMultiple, OptionList,
143
143
  Checkbox, Toggle, Radio,
144
144
  DateInput, TimeInput,
145
+ // Navigation
146
+ Breadcrumb,
147
+ Pagination, PaginationBanner, PaginationCarousel,
145
148
  // Display
146
149
  Avatar, AvatarStack,
147
150
  Tag, StatusTag, Chip,
@@ -154,7 +157,7 @@ import {
154
157
  Notification,
155
158
  Badge,
156
159
  // Overlay
157
- Modal, BottomSheet,
160
+ Modal, BottomSheet, Tooltip, Popover,
158
161
  // Utility
159
162
  cn, useIsMobile,
160
163
  } from "@sarunyu/system-one";
@@ -868,6 +871,57 @@ Props: `items` (array of `{ type?, src?, alt?, initials? }`), `size?` (`"small"`
868
871
 
869
872
  ---
870
873
 
874
+ ### Breadcrumb
875
+
876
+ Horizontal navigation trail rendered as a `<nav>` with `/` separators. The last item is always the current page (active state). Items with `href` render as anchor tags; items without render as plain text.
877
+
878
+ ```tsx
879
+ <Breadcrumb
880
+ items={[
881
+ { label: "Home", href: "/" },
882
+ { label: "Products", href: "/products" },
883
+ { label: "Detail" },
884
+ ]}
885
+ />
886
+ ```
887
+
888
+ Props: `items` (`BreadcrumbItem[]` — each has `label: string`, `href?: string`), `className?`.
889
+
890
+ The last item in `items` is always treated as the current page — never pass `href` on it.
891
+
892
+ ---
893
+
894
+ ### Pagination
895
+
896
+ Three variants for different scroll/paging patterns:
897
+
898
+ | Component | Use for |
899
+ |---|---|
900
+ | `<Pagination>` | Numbered pages — datasets, search results, news lists |
901
+ | `<PaginationBanner>` | Banner/hero slide dot indicator (active = wider pill) |
902
+ | `<PaginationCarousel>` | Free-scroll carousel progress bar |
903
+
904
+ ```tsx
905
+ // Numbered pagination
906
+ <Pagination totalPages={10} currentPage={currentPage} onPageChange={setCurrentPage} />
907
+
908
+ // Banner slide dots
909
+ <PaginationBanner count={5} activeIndex={bannerIndex} onIndexChange={setBannerIndex} />
910
+
911
+ // Carousel scrollbar — progress 0 (start) to 1 (end)
912
+ <PaginationCarousel progress={scrollProgress} />
913
+ <PaginationCarousel progress={0.5} trackWidth={60} />
914
+ ```
915
+
916
+ **Numbered pagination** — when `totalPages > 5`, pages 4…(n-1) collapse behind a `…` button that opens a scrollable dropdown to jump to any hidden page. Do not use `<Pagination>` inside a horizontal card carousel — use `<PaginationCarousel>` instead.
917
+
918
+ Props:
919
+ - `Pagination` — `totalPages`, `currentPage`, `onPageChange?(page: number)`, `className?`
920
+ - `PaginationBanner` — `count`, `activeIndex`, `onIndexChange?(index: number)`, `className?`
921
+ - `PaginationCarousel` — `progress` (0–1, clamped), `trackWidth?` (default 40), `className?`
922
+
923
+ ---
924
+
871
925
  ### Notification
872
926
 
873
927
  Bell-icon trigger + popover panel showing grouped notification rows. Handles badge count, auto-clear on open, and keyboard navigation. Uses `<Badge variant="notification">` internally.
@@ -1069,6 +1123,80 @@ Props: `open`, `onOpenChange`, `trigger`, `headerType`, `showHeader`,
1069
1123
 
1070
1124
  ---
1071
1125
 
1126
+ ### Tooltip
1127
+
1128
+ Dark-bubble contextual hint shown on hover over any trigger element.
1129
+ `children` is the trigger (must be a single focusable element); `content` is the bubble text.
1130
+
1131
+ ```tsx
1132
+ <Tooltip content="Delete this item">
1133
+ <Button variant="outline" size="icon-md" aria-label="Delete"><Trash size={16} /></Button>
1134
+ </Tooltip>
1135
+
1136
+ <Tooltip content="This field is required" side="right" align="start">
1137
+ <Input placeholder="Email" value={email} onChange={setEmail} />
1138
+ </Tooltip>
1139
+
1140
+ <Tooltip content="Appears immediately" side="top" delayDuration={0}>
1141
+ <Button variant="plain" size="md">Instant</Button>
1142
+ </Tooltip>
1143
+ ```
1144
+
1145
+ Props:
1146
+ - `children` — trigger element (`ReactNode`, required). Must be a single element that accepts `onPointerEnter` / `onFocus`.
1147
+ - `content` — bubble content (`ReactNode`, required).
1148
+ - `side` — `"top"` | `"bottom"` | `"left"` | `"right"`. Default `"top"`.
1149
+ - `align` — `"start"` | `"center"` | `"end"`. Default `"center"`.
1150
+ - `delayDuration` — ms before tooltip shows on hover. Default `300`.
1151
+ - `sideOffset` — gap in px between trigger and bubble. Default `6`.
1152
+ - `className?` — extra classes on the bubble (layout only — never override colors or padding).
1153
+
1154
+ ---
1155
+
1156
+ ### Popover
1157
+
1158
+ Floating panel that opens on **click** over any trigger element. Pass the trigger as `children` and the panel body as `content`. Scrollbar is hidden inside the bubble by default.
1159
+
1160
+ ```tsx
1161
+ <Popover content={<div>Panel content here</div>}>
1162
+ <Button variant="outline" size="md">Open</Button>
1163
+ </Popover>
1164
+
1165
+ // Side and alignment
1166
+ <Popover side="top" align="center" content={<p className="text-sm text-foreground">Centered above</p>}>
1167
+ <Button variant="outline" size="md">Top center</Button>
1168
+ </Popover>
1169
+
1170
+ // Controlled state
1171
+ <Popover open={open} onOpenChange={setOpen} content={<p>Controlled</p>}>
1172
+ <Button variant="outline" size="md">Open</Button>
1173
+ </Popover>
1174
+
1175
+ // Rich content
1176
+ <Popover
1177
+ content={
1178
+ <div className="flex flex-col gap-2 min-w-48">
1179
+ <p className="text-sm font-medium text-foreground">Account</p>
1180
+ <OptionList options={menuItems} selectedValue={null} onSelect={handleSelect} />
1181
+ </div>
1182
+ }
1183
+ >
1184
+ <Button variant="outline" size="md" leftIcon={<User size={16} />}>Account</Button>
1185
+ </Popover>
1186
+ ```
1187
+
1188
+ Props:
1189
+ - `children` — trigger element (`ReactNode`, required). Must be a single element.
1190
+ - `content` — panel body (`ReactNode`, required).
1191
+ - `side` — `"top"` | `"bottom"` | `"left"` | `"right"`. Default `"bottom"`.
1192
+ - `align` — `"start"` | `"center"` | `"end"`. Default `"start"`.
1193
+ - `sideOffset` — gap in px between trigger and panel. Default `4`.
1194
+ - `open` — controlled open state. Omit for uncontrolled usage.
1195
+ - `onOpenChange` — `(open: boolean) => void`.
1196
+ - `className?` — extra classes on the panel bubble (layout only — never override `bg-*` or `p-*`).
1197
+
1198
+ ---
1199
+
1072
1200
  ### Modal vs BottomSheet — responsive rule
1073
1201
 
1074
1202
  **On mobile (< 768px), content-heavy / action-heavy modals MUST render as
@@ -1521,4 +1649,4 @@ Rules for custom components:
1521
1649
  - Border → `border-border` (or `border-divider` for light separators).
1522
1650
  - Typography → use `<h1>`…`<h4>` and body text inherits from `--foreground`.
1523
1651
 
1524
- If the thing you're building is conceptually a button/input/tag/chip/tab/card/table — **do not build a custom one. Use the library's component.** The only reason to build custom is when the library truly doesn't cover the concept (e.g. a bespoke hero section, a custom chart, a breadcrumb).
1652
+ If the thing you're building is conceptually a button/input/tag/chip/tab/card/table/breadcrumb — **do not build a custom one. Use the library's component.** The only reason to build custom is when the library truly doesn't cover the concept (e.g. a bespoke hero section, a custom chart).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarunyu/system-one",
3
- "version": "4.9.30",
3
+ "version": "4.9.33",
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": [