@sarunyu/system-one 4.9.31 → 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. 27 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, Breadcrumb 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
@@ -144,6 +144,7 @@ import {
144
144
  DateInput, TimeInput,
145
145
  // Navigation
146
146
  Breadcrumb,
147
+ Pagination, PaginationBanner, PaginationCarousel,
147
148
  // Display
148
149
  Avatar, AvatarStack,
149
150
  Tag, StatusTag, Chip,
@@ -156,7 +157,7 @@ import {
156
157
  Notification,
157
158
  Badge,
158
159
  // Overlay
159
- Modal, BottomSheet,
160
+ Modal, BottomSheet, Tooltip, Popover,
160
161
  // Utility
161
162
  cn, useIsMobile,
162
163
  } from "@sarunyu/system-one";
@@ -890,6 +891,37 @@ The last item in `items` is always treated as the current page — never pass `h
890
891
 
891
892
  ---
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
+
893
925
  ### Notification
894
926
 
895
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.
@@ -1091,6 +1123,80 @@ Props: `open`, `onOpenChange`, `trigger`, `headerType`, `showHeader`,
1091
1123
 
1092
1124
  ---
1093
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
+
1094
1200
  ### Modal vs BottomSheet — responsive rule
1095
1201
 
1096
1202
  **On mobile (< 768px), content-heavy / action-heavy modals MUST render as
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarunyu/system-one",
3
- "version": "4.9.31",
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": [