@sarunyu/system-one 4.9.37 → 4.9.40

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. 30 components.
3
+ React component library. Tailwind CSS v4 + CSS custom properties. 35 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,14 +12,16 @@ 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, Pagination, PaginationBanner, PaginationCarousel, Tooltip, Popover as raw HTML.
15
+ Table, SearchInput, TextArea, Chip, Modal, BottomSheet, Alert, Toast, Notification, Badge, Avatar, AvatarStack, Breadcrumb, Pagination, PaginationBanner, PaginationCarousel, Tooltip, Popover,
16
+ Slider, UploadArea, UploadItem, List, ListItem as raw HTML.
16
17
  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
18
  3. **Use design-token classes for color and typography.** Never `text-blue-600`,
18
19
  `bg-gray-100`, `text-[#3b82f6]`. The token table below is exhaustive — if a
19
20
  color you need is not in it, use `text-foreground` / `bg-card`.
20
21
  4. **Use `@phosphor-icons/react` for all icons.** Never import from `lucide-react`
21
22
  or any other icon library. Install with `npm install @phosphor-icons/react`.
22
- Import named icons: `import { House, MagnifyingGlass, CaretDown } from "@phosphor-icons/react"`.
23
+ Import named icons: `import { HouseIcon, MagnifyingGlassIcon, CaretDownIcon } from "@phosphor-icons/react"`.
24
+ All icon names use the `Icon` suffix (e.g. `StarIcon`, `TrashIcon`, `ArrowUpIcon`). The un-suffixed names are deprecated.
23
25
  Every icon accepts `size`, `weight` (`"regular"` | `"fill"` — no other weights), and `className` props.
24
26
  5. **No arbitrary bracket values for spacing / sizing / typography.**
25
27
  Use scale utilities, not pixel overrides. The library's shipped stylesheet
@@ -153,6 +155,8 @@ import {
153
155
  Dropdown, DropdownMultiple, OptionList,
154
156
  Checkbox, Toggle, Radio,
155
157
  DateInput, TimeInput,
158
+ Slider,
159
+ UploadArea, UploadItem,
156
160
  // Navigation
157
161
  Breadcrumb,
158
162
  Pagination, PaginationBanner, PaginationCarousel,
@@ -162,6 +166,7 @@ import {
162
166
  Tab, TabGroup,
163
167
  Card,
164
168
  Table, TableRow, TableHeaderCell, TableCell,
169
+ LinearProgress, CircleProgress,
165
170
  // Feedback
166
171
  Alert,
167
172
  Toast, Toaster,
@@ -169,6 +174,8 @@ import {
169
174
  Badge,
170
175
  // Overlay
171
176
  Modal, BottomSheet, Tooltip, Popover,
177
+ // List
178
+ List, ListItem,
172
179
  // Utility
173
180
  cn, useIsMobile,
174
181
  } from "@sarunyu/system-one";
@@ -919,17 +926,24 @@ Three variants for different scroll/paging patterns:
919
926
  // Banner slide dots
920
927
  <PaginationBanner count={5} activeIndex={bannerIndex} onIndexChange={setBannerIndex} />
921
928
 
922
- // Carousel scrollbar — progress 0 (start) to 1 (end)
923
- <PaginationCarousel progress={scrollProgress} />
924
- <PaginationCarousel progress={0.5} trackWidth={60} />
929
+ // Carousel scrollbar — pill slides as user scrolls
930
+ <PaginationCarousel
931
+ count={total}
932
+ activeIndex={activeIndex}
933
+ viewRatio={clientWidth / scrollWidth} // pill width = viewRatio × 40px track
934
+ scrollProgress={scrollLeft / maxScroll} // pill position 0–1
935
+ onIndexChange={goToSlide}
936
+ />
925
937
  ```
926
938
 
927
939
  **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.
928
940
 
941
+ **Carousel pagination** — a fixed-width sliding pill (width proportional to `viewRatio`) that moves along a 40 px track. Pair with a scrollable container: derive `viewRatio = clientWidth / scrollWidth` and `scrollProgress = scrollLeft / maxScroll` from the container's scroll events. Navigation arrows are built-in.
942
+
929
943
  Props:
930
944
  - `Pagination` — `totalPages`, `currentPage`, `onPageChange?(page: number)`, `className?`
931
945
  - `PaginationBanner` — `count`, `activeIndex`, `onIndexChange?(index: number)`, `className?`
932
- - `PaginationCarousel` — `progress` (0–1, clamped), `trackWidth?` (default 40), `className?`
946
+ - `PaginationCarousel` — `count`, `activeIndex`, `viewRatio?` (pill width ratio, default `1/count`), `scrollProgress?` (0–1, overrides index-based pill position), `onIndexChange?(index: number)`, `className?`
933
947
 
934
948
  ---
935
949
 
@@ -1159,7 +1173,7 @@ Dark-bubble contextual hint shown on hover over any trigger element.
1159
1173
 
1160
1174
  ```tsx
1161
1175
  <Tooltip content="Delete this item">
1162
- <Button variant="outline" size="icon-md" aria-label="Delete"><Trash size={16} /></Button>
1176
+ <Button variant="outline" size="icon-md" aria-label="Delete"><TrashIcon size={16} /></Button>
1163
1177
  </Tooltip>
1164
1178
 
1165
1179
  <Tooltip content="This field is required" side="right" align="start">
@@ -1210,7 +1224,7 @@ Floating panel that opens on **click** over any trigger element. Pass the trigge
1210
1224
  </div>
1211
1225
  }
1212
1226
  >
1213
- <Button variant="outline" size="md" leftIcon={<User size={16} />}>Account</Button>
1227
+ <Button variant="outline" size="md" leftIcon={<UserIcon size={16} />}>Account</Button>
1214
1228
  </Popover>
1215
1229
  ```
1216
1230
 
@@ -1226,6 +1240,102 @@ Props:
1226
1240
 
1227
1241
  ---
1228
1242
 
1243
+ ### Slider
1244
+
1245
+ Range input with a draggable thumb. Three track heights, single-thumb or two-thumb range. Never use `<input type="range">` directly.
1246
+
1247
+ ```tsx
1248
+ // Single thumb (uncontrolled default = 50)
1249
+ const [value, setValue] = useState(50)
1250
+ <Slider value={value} onChange={setValue} />
1251
+ <Slider size="sm" value={value} onChange={setValue} />
1252
+ <Slider size="lg" showSteps value={value} onChange={setValue} />
1253
+ <Slider disabled value={value} onChange={setValue} />
1254
+
1255
+ // Two-thumb range
1256
+ const [range, setRange] = useState<[number, number]>([25, 75])
1257
+ <Slider type="range" rangeValue={range} onRangeChange={setRange} />
1258
+ <Slider type="range" size="lg" showSteps rangeValue={range} onRangeChange={setRange} />
1259
+ ```
1260
+
1261
+ Props: `size` (`"sm"` 4px | `"md"` 8px default | `"lg"` 12px), `type` (`"single"` default | `"range"`), `disabled`, `showSteps` (labels at 0 / 25 / 50 / 75 / 100), `min` (default 0), `max` (default 100), `step` (default 1), `value` (controlled single), `rangeValue` (controlled range `[start, end]`), `defaultValue` (50), `defaultRangeValue` ([25, 75]), `onChange(value)`, `onRangeChange([start, end])`, `className`.
1262
+
1263
+ ---
1264
+
1265
+ ### LinearProgress / CircleProgress
1266
+
1267
+ Deterministic progress indicators. `value` is 0–100 (clamped automatically). Never use `<progress>` HTML element.
1268
+
1269
+ ```tsx
1270
+ // Linear bar — typically full-width or constrained by parent
1271
+ <LinearProgress value={65} />
1272
+ <LinearProgress value={30} className="w-64" />
1273
+
1274
+ // Circle — three sizes
1275
+ <CircleProgress value={75} /> // lg (128 px) — default, shows % label
1276
+ <CircleProgress value={50} size="md" /> // md (48 px) — shows % label
1277
+ <CircleProgress value={30} size="sm" /> // sm (24 px) — arc only, no label
1278
+ ```
1279
+
1280
+ Props `LinearProgress`: `value`, `className`.
1281
+ Props `CircleProgress`: `value`, `size` (`"sm"` | `"md"` | `"lg"` default), `className`.
1282
+
1283
+ `lg` and `md` sizes display a centred percentage label; `sm` is arc-only. The arc uses a brand cyan-to-navy gradient. At `value={0}`, `lg`/`md` show a placeholder-coloured `0%` label.
1284
+
1285
+ ---
1286
+
1287
+ ### UploadArea / UploadItem
1288
+
1289
+ Upload dropzone and per-file status rows. Never hand-roll dashed upload areas or custom file progress rows.
1290
+
1291
+ ```tsx
1292
+ // Dropzone — wire onClick to open a file input
1293
+ const inputRef = useRef<HTMLInputElement>(null)
1294
+ <UploadArea onClick={() => inputRef.current?.click()} />
1295
+ <UploadArea disabled />
1296
+ <UploadArea label="Browse files" onClick={() => inputRef.current?.click()} />
1297
+
1298
+ // Text variant — compact row, no card border
1299
+ <UploadItem variant="text" status="loading" fileName="report.pdf" progress={42} />
1300
+ <UploadItem variant="text" status="success" fileName="report.pdf" onDelete={handleDelete} />
1301
+ <UploadItem variant="text" status="error" fileName="report.pdf" errorText="File too large" onDelete={handleDelete} />
1302
+
1303
+ // Card variant — bordered card with file-size column and separate delete button
1304
+ <UploadItem variant="card" status="loading" fileName="photo.png" fileSize="1.66KB" progress={42} />
1305
+ <UploadItem variant="card" status="success" fileName="photo.png" fileSize="1.66KB" onDelete={handleDelete} />
1306
+ <UploadItem variant="card" status="error" fileName="photo.png" fileSize="1.66KB" errorText="Upload failed" onDelete={handleDelete} />
1307
+ ```
1308
+
1309
+ Props `UploadArea`: `disabled`, `label` (default `"อัปโหลดไฟล์"`), plus all native `<div>` props (`onClick`, `className`, etc.).
1310
+ Props `UploadItem`: `variant` (`"text"` default | `"card"`), `status` (`"loading"` | `"success"` | `"error"`, default `"loading"`), `fileName`, `fileSize` (card variant — e.g. `"1.66KB"`), `errorText`, `progress` (0–100, shown while `status="loading"`), `onDelete`, `className`.
1311
+
1312
+ ---
1313
+
1314
+ ### List / ListItem
1315
+
1316
+ Vertical list of rows. Each row has a label, optional leading/trailing slot, and optional action link or click handler. Never hand-roll `<ul>` / `<li>` rows for this pattern.
1317
+
1318
+ ```tsx
1319
+ <List>
1320
+ <ListItem label="Settings" />
1321
+ <ListItem label="Profile" leading={<UserIcon size={24} />} />
1322
+ <ListItem label="Documents" trailing={<CaretRightIcon size={24} />} onClick={() => navigate("/docs")} />
1323
+ <ListItem label="Billing" action="Manage" onAction={openBilling} />
1324
+ <ListItem label="Disabled row" highlighted />
1325
+ </List>
1326
+ ```
1327
+
1328
+ **Slots:**
1329
+ - `leading` — left slot (icon, avatar, image). Rendered at 24×24 with `text-icon-default`.
1330
+ - `trailing` — right slot (icon, chevron, badge). Same sizing.
1331
+ - `action` — string label for an inline text-button on the right (e.g. "Edit", "View all"). Fires `onAction`.
1332
+ - `onClick` — makes the whole row tappable. Press state (gray background) is applied automatically.
1333
+
1334
+ Props `ListItem`: `label` (required), `leading?`, `trailing?`, `action?`, `onAction?(e)`, `highlighted?`, `onClick?`, `className`.
1335
+ Props `List`: `children`, `className`.
1336
+
1337
+ ---
1338
+
1229
1339
  ### Modal vs BottomSheet — responsive rule
1230
1340
 
1231
1341
  **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.37",
3
+ "version": "4.9.40",
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": [