@sarunyu/system-one 4.9.37 → 4.9.39
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/AGENTS.md +4 -0
- package/DESIGN.md +2 -2
- package/dist/index.cjs +627 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +628 -7
- package/dist/index.js.map +1 -1
- package/dist/src/components/list.d.ts +25 -0
- package/dist/src/components/list.d.ts.map +1 -0
- package/dist/src/components/progress.d.ts +23 -0
- package/dist/src/components/progress.d.ts.map +1 -0
- package/dist/src/components/slider.d.ts +34 -0
- package/dist/src/components/slider.d.ts.map +1 -0
- package/dist/src/components/upload.d.ts +38 -0
- package/dist/src/components/upload.d.ts.map +1 -0
- package/dist/src/index.d.ts +16 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/llms.txt +108 -5
- package/package.json +1 -1
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.
|
|
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
|
|
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 {
|
|
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";
|
|
@@ -1159,7 +1166,7 @@ Dark-bubble contextual hint shown on hover over any trigger element.
|
|
|
1159
1166
|
|
|
1160
1167
|
```tsx
|
|
1161
1168
|
<Tooltip content="Delete this item">
|
|
1162
|
-
<Button variant="outline" size="icon-md" aria-label="Delete"><
|
|
1169
|
+
<Button variant="outline" size="icon-md" aria-label="Delete"><TrashIcon size={16} /></Button>
|
|
1163
1170
|
</Tooltip>
|
|
1164
1171
|
|
|
1165
1172
|
<Tooltip content="This field is required" side="right" align="start">
|
|
@@ -1210,7 +1217,7 @@ Floating panel that opens on **click** over any trigger element. Pass the trigge
|
|
|
1210
1217
|
</div>
|
|
1211
1218
|
}
|
|
1212
1219
|
>
|
|
1213
|
-
<Button variant="outline" size="md" leftIcon={<
|
|
1220
|
+
<Button variant="outline" size="md" leftIcon={<UserIcon size={16} />}>Account</Button>
|
|
1214
1221
|
</Popover>
|
|
1215
1222
|
```
|
|
1216
1223
|
|
|
@@ -1226,6 +1233,102 @@ Props:
|
|
|
1226
1233
|
|
|
1227
1234
|
---
|
|
1228
1235
|
|
|
1236
|
+
### Slider
|
|
1237
|
+
|
|
1238
|
+
Range input with a draggable thumb. Three track heights, single-thumb or two-thumb range. Never use `<input type="range">` directly.
|
|
1239
|
+
|
|
1240
|
+
```tsx
|
|
1241
|
+
// Single thumb (uncontrolled default = 50)
|
|
1242
|
+
const [value, setValue] = useState(50)
|
|
1243
|
+
<Slider value={value} onChange={setValue} />
|
|
1244
|
+
<Slider size="sm" value={value} onChange={setValue} />
|
|
1245
|
+
<Slider size="lg" showSteps value={value} onChange={setValue} />
|
|
1246
|
+
<Slider disabled value={value} onChange={setValue} />
|
|
1247
|
+
|
|
1248
|
+
// Two-thumb range
|
|
1249
|
+
const [range, setRange] = useState<[number, number]>([25, 75])
|
|
1250
|
+
<Slider type="range" rangeValue={range} onRangeChange={setRange} />
|
|
1251
|
+
<Slider type="range" size="lg" showSteps rangeValue={range} onRangeChange={setRange} />
|
|
1252
|
+
```
|
|
1253
|
+
|
|
1254
|
+
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`.
|
|
1255
|
+
|
|
1256
|
+
---
|
|
1257
|
+
|
|
1258
|
+
### LinearProgress / CircleProgress
|
|
1259
|
+
|
|
1260
|
+
Deterministic progress indicators. `value` is 0–100 (clamped automatically). Never use `<progress>` HTML element.
|
|
1261
|
+
|
|
1262
|
+
```tsx
|
|
1263
|
+
// Linear bar — typically full-width or constrained by parent
|
|
1264
|
+
<LinearProgress value={65} />
|
|
1265
|
+
<LinearProgress value={30} className="w-64" />
|
|
1266
|
+
|
|
1267
|
+
// Circle — three sizes
|
|
1268
|
+
<CircleProgress value={75} /> // lg (128 px) — default, shows % label
|
|
1269
|
+
<CircleProgress value={50} size="md" /> // md (48 px) — shows % label
|
|
1270
|
+
<CircleProgress value={30} size="sm" /> // sm (24 px) — arc only, no label
|
|
1271
|
+
```
|
|
1272
|
+
|
|
1273
|
+
Props `LinearProgress`: `value`, `className`.
|
|
1274
|
+
Props `CircleProgress`: `value`, `size` (`"sm"` | `"md"` | `"lg"` default), `className`.
|
|
1275
|
+
|
|
1276
|
+
`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.
|
|
1277
|
+
|
|
1278
|
+
---
|
|
1279
|
+
|
|
1280
|
+
### UploadArea / UploadItem
|
|
1281
|
+
|
|
1282
|
+
Upload dropzone and per-file status rows. Never hand-roll dashed upload areas or custom file progress rows.
|
|
1283
|
+
|
|
1284
|
+
```tsx
|
|
1285
|
+
// Dropzone — wire onClick to open a file input
|
|
1286
|
+
const inputRef = useRef<HTMLInputElement>(null)
|
|
1287
|
+
<UploadArea onClick={() => inputRef.current?.click()} />
|
|
1288
|
+
<UploadArea disabled />
|
|
1289
|
+
<UploadArea label="Browse files" onClick={() => inputRef.current?.click()} />
|
|
1290
|
+
|
|
1291
|
+
// Text variant — compact row, no card border
|
|
1292
|
+
<UploadItem variant="text" status="loading" fileName="report.pdf" progress={42} />
|
|
1293
|
+
<UploadItem variant="text" status="success" fileName="report.pdf" onDelete={handleDelete} />
|
|
1294
|
+
<UploadItem variant="text" status="error" fileName="report.pdf" errorText="File too large" onDelete={handleDelete} />
|
|
1295
|
+
|
|
1296
|
+
// Card variant — bordered card with file-size column and separate delete button
|
|
1297
|
+
<UploadItem variant="card" status="loading" fileName="photo.png" fileSize="1.66KB" progress={42} />
|
|
1298
|
+
<UploadItem variant="card" status="success" fileName="photo.png" fileSize="1.66KB" onDelete={handleDelete} />
|
|
1299
|
+
<UploadItem variant="card" status="error" fileName="photo.png" fileSize="1.66KB" errorText="Upload failed" onDelete={handleDelete} />
|
|
1300
|
+
```
|
|
1301
|
+
|
|
1302
|
+
Props `UploadArea`: `disabled`, `label` (default `"อัปโหลดไฟล์"`), plus all native `<div>` props (`onClick`, `className`, etc.).
|
|
1303
|
+
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`.
|
|
1304
|
+
|
|
1305
|
+
---
|
|
1306
|
+
|
|
1307
|
+
### List / ListItem
|
|
1308
|
+
|
|
1309
|
+
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.
|
|
1310
|
+
|
|
1311
|
+
```tsx
|
|
1312
|
+
<List>
|
|
1313
|
+
<ListItem label="Settings" />
|
|
1314
|
+
<ListItem label="Profile" leading={<UserIcon size={24} />} />
|
|
1315
|
+
<ListItem label="Documents" trailing={<CaretRightIcon size={24} />} onClick={() => navigate("/docs")} />
|
|
1316
|
+
<ListItem label="Billing" action="Manage" onAction={openBilling} />
|
|
1317
|
+
<ListItem label="Disabled row" highlighted />
|
|
1318
|
+
</List>
|
|
1319
|
+
```
|
|
1320
|
+
|
|
1321
|
+
**Slots:**
|
|
1322
|
+
- `leading` — left slot (icon, avatar, image). Rendered at 24×24 with `text-icon-default`.
|
|
1323
|
+
- `trailing` — right slot (icon, chevron, badge). Same sizing.
|
|
1324
|
+
- `action` — string label for an inline text-button on the right (e.g. "Edit", "View all"). Fires `onAction`.
|
|
1325
|
+
- `onClick` — makes the whole row tappable. Press state (gray background) is applied automatically.
|
|
1326
|
+
|
|
1327
|
+
Props `ListItem`: `label` (required), `leading?`, `trailing?`, `action?`, `onAction?(e)`, `highlighted?`, `onClick?`, `className`.
|
|
1328
|
+
Props `List`: `children`, `className`.
|
|
1329
|
+
|
|
1330
|
+
---
|
|
1331
|
+
|
|
1229
1332
|
### Modal vs BottomSheet — responsive rule
|
|
1230
1333
|
|
|
1231
1334
|
**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.
|
|
3
|
+
"version": "4.9.39",
|
|
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": [
|