@uisatin/ui 0.1.1 → 0.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/CHANGELOG.md +33 -0
- package/README.md +20 -3
- package/chunk-3DHJXU45.js +147 -0
- package/{chunk-6YXUBP27.js → chunk-5725MFGQ.js} +72 -67
- package/{chunk-BKZBWPUH.js → chunk-57QEOCDZ.js} +9 -11
- package/{chunk-RTJ76X5U.js → chunk-5KTBSMQU.js} +2 -4
- package/{chunk-B2K45IUR.js → chunk-5XTUFBZI.js} +5 -7
- package/{chunk-LW3TRU5W.js → chunk-674SRBZK.js} +28 -16
- package/{chunk-XZNHT6MO.js → chunk-6VKV36OK.js} +115 -61
- package/{chunk-GICKPMJU.js → chunk-73Z7NMQQ.js} +31 -31
- package/chunk-7Q76HLRQ.js +128 -0
- package/{chunk-JPNWHWAQ.js → chunk-AIMQNLPY.js} +38 -35
- package/chunk-BN7FDKCJ.js +164 -0
- package/{chunk-3DINAQLL.js → chunk-BR2B4OIT.js} +33 -29
- package/{chunk-2HKBZFIK.js → chunk-CGOH5IYX.js} +31 -31
- package/chunk-CVNRZ2YV.js +112 -0
- package/{chunk-QUF2IPOZ.js → chunk-DPYIBFQD.js} +12 -14
- package/chunk-EF5GT4OG.js +87 -0
- package/chunk-FAJ3OVL4.js +37 -0
- package/{chunk-L6NCCSIP.js → chunk-FB5HTCO2.js} +36 -29
- package/chunk-GI2SMFZL.js +55 -0
- package/{chunk-B6V4VSGH.js → chunk-GMETYACH.js} +14 -15
- package/chunk-HK6WINL6.js +95 -0
- package/{chunk-HL42K2NH.js → chunk-IKO3GQFE.js} +17 -17
- package/{chunk-DO3TBNSC.js → chunk-ISYKZCPJ.js} +15 -17
- package/{chunk-YG7JOOLJ.js → chunk-J7RMFN54.js} +5 -7
- package/{chunk-SHDFUXYV.js → chunk-JBKBRAC4.js} +16 -18
- package/{chunk-LZMKSFCF.js → chunk-JCXI7VQL.js} +10 -12
- package/{chunk-NN6PKJWS.js → chunk-JYOZUQNU.js} +7 -9
- package/{chunk-LLHTVIM3.js → chunk-LB37KTJH.js} +7 -9
- package/{chunk-NSRTTYQ4.js → chunk-LB7Z6BSK.js} +42 -35
- package/{chunk-BNZVTLHV.js → chunk-LFGUJHFF.js} +25 -21
- package/{chunk-7TXHCRAG.js → chunk-M2HEVFQ3.js} +8 -10
- package/{chunk-SH6NG6VN.js → chunk-NH3EHMIL.js} +6 -8
- package/chunk-NL574STL.js +88 -0
- package/chunk-NQL6SIIB.js +168 -0
- package/chunk-O46O6LFQ.js +25 -0
- package/{chunk-YPNKBE5X.js → chunk-OURZQM27.js} +5 -7
- package/{chunk-XL75JRUA.js → chunk-OVKPPXK5.js} +42 -22
- package/chunk-PD6YPFYN.js +42 -0
- package/{chunk-XILQ7GXE.js → chunk-PHNR6ZQ7.js} +11 -13
- package/{chunk-BNTPPZCK.js → chunk-PUWSL5XW.js} +37 -39
- package/{chunk-A5XEM3GF.js → chunk-RHQHDYTE.js} +34 -36
- package/chunk-S7QHBVPX.js +45 -0
- package/{chunk-TX3H3QMA.js → chunk-SAYNV7B3.js} +71 -70
- package/{chunk-6QMSWITQ.js → chunk-SDOTDMYG.js} +24 -26
- package/{chunk-UGRSWP6U.js → chunk-SPGUZMCC.js} +10 -12
- package/chunk-SSOFFQ5T.js +74 -0
- package/{chunk-AN2RNJLR.js → chunk-SZJIVBOD.js} +16 -16
- package/chunk-T6L32XXH.js +107 -0
- package/{chunk-QS4N4MNP.js → chunk-TT2N5752.js} +18 -20
- package/{chunk-72OCFAPT.js → chunk-UCCNXGLG.js} +22 -21
- package/{chunk-KNUWZNFV.js → chunk-UGIVCXGN.js} +4 -6
- package/{chunk-H4NU7NPO.js → chunk-UUCVRIVP.js} +62 -61
- package/{chunk-P4O6TGDR.js → chunk-UZ4DXU6W.js} +28 -26
- package/{chunk-UBNHSZSE.js → chunk-VUOAPWTF.js} +10 -12
- package/{chunk-VAGIAREV.js → chunk-W472DBMT.js} +29 -26
- package/{chunk-X3PQANZO.js → chunk-W4RDTP6W.js} +47 -46
- package/{chunk-CL2II6BX.js → chunk-WLQD5BN2.js} +11 -13
- package/{chunk-FDKIX4DC.js → chunk-X2GNMNZQ.js} +7 -9
- package/{chunk-PF3YBUKT.js → chunk-X66KTATQ.js} +16 -15
- package/{chunk-J3NSDRVH.js → chunk-XETMIETJ.js} +0 -2
- package/chunk-XH56JGYC.js +71 -0
- package/{chunk-O7F3CIDV.js → chunk-XUOSJMEJ.js} +10 -12
- package/chunk-YJK4MGSI.js +86 -0
- package/{chunk-YX5VNRJX.js → chunk-YYFAZQ25.js} +0 -2
- package/chunk-Z7S2KQZS.js +177 -0
- package/chunk-ZBZ3ZQRB.js +195 -0
- package/{chunk-Y5AYU7PK.js → chunk-ZHFIWDGF.js} +0 -2
- package/components/accordion.js +2 -4
- package/components/agent-loading.d.ts +2 -0
- package/components/agent-loading.js +2 -4
- package/components/agent-picker.js +4 -5
- package/components/agent-suggestion.js +5 -6
- package/components/announcement-bar.js +6 -7
- package/components/attachment.js +4 -5
- package/components/avatar.d.ts +16 -0
- package/components/avatar.js +4 -6
- package/components/badge.js +2 -4
- package/components/banner-mesh.js +1 -3
- package/components/banner.js +4 -6
- package/components/bar-chart.js +10 -11
- package/components/breadcrumb.js +5 -6
- package/components/button.js +2 -4
- package/components/card.js +3 -5
- package/components/channel-chart.js +10 -11
- package/components/chart.js +9 -10
- package/components/checkbox.js +2 -4
- package/components/chip.js +2 -4
- package/components/citations.d.ts +6 -4
- package/components/citations.js +4 -5
- package/components/code-block.js +3 -5
- package/components/combobox.d.ts +12 -3
- package/components/combobox.js +9 -10
- package/components/command-menu.d.ts +6 -2
- package/components/command-menu.js +5 -6
- package/components/context-menu.d.ts +12 -5
- package/components/context-menu.js +5 -6
- package/components/cookie-consent.js +3 -5
- package/components/date-picker.d.ts +26 -14
- package/components/date-picker.js +8 -9
- package/components/decision-card.js +6 -7
- package/components/dialog.d.ts +5 -2
- package/components/dialog.js +4 -5
- package/components/donut-chart.js +10 -11
- package/components/dot.js +2 -4
- package/components/dropdown.d.ts +6 -1
- package/components/dropdown.js +4 -5
- package/components/empty-state.js +2 -4
- package/components/file-upload.js +6 -7
- package/components/floating.js +1 -3
- package/components/form-field.js +2 -4
- package/components/hover-card.d.ts +5 -2
- package/components/hover-card.js +2 -4
- package/components/input-otp.d.ts +4 -2
- package/components/input-otp.js +7 -8
- package/components/input.js +3 -5
- package/components/kbd.js +2 -4
- package/components/labels.d.ts +79 -0
- package/components/labels.js +1 -0
- package/components/line-chart.js +11 -12
- package/components/message-actions.js +4 -5
- package/components/message.js +7 -8
- package/components/number-input.d.ts +4 -2
- package/components/number-input.js +7 -8
- package/components/pagination.js +4 -6
- package/components/popover.d.ts +11 -5
- package/components/popover.js +3 -4
- package/components/progress.js +2 -4
- package/components/prompt-bar.js +5 -6
- package/components/radio.js +2 -4
- package/components/search-bar.js +3 -5
- package/components/segmented-control.d.ts +4 -2
- package/components/segmented-control.js +3 -5
- package/components/select.d.ts +10 -2
- package/components/select.js +6 -7
- package/components/sheet.d.ts +4 -2
- package/components/sheet.js +5 -6
- package/components/sidebar.js +2 -4
- package/components/skeleton.js +2 -4
- package/components/slider.d.ts +6 -2
- package/components/slider.js +7 -8
- package/components/sliding-indicator.js +1 -3
- package/components/streaming-text.js +2 -4
- package/components/switch.js +2 -4
- package/components/table.d.ts +16 -5
- package/components/table.js +4 -5
- package/components/tabs.d.ts +4 -2
- package/components/tabs.js +3 -5
- package/components/textarea.js +3 -5
- package/components/thinking.js +3 -5
- package/components/toast.js +4 -5
- package/components/toggle.js +2 -4
- package/components/tooltip.d.ts +5 -2
- package/components/tooltip.js +3 -5
- package/index.d.ts +1 -0
- package/index.js +67 -231
- package/lib/utils.d.ts +8 -1
- package/lib/utils.js +1 -3
- package/package.json +22 -1
- package/styles.css +1 -1
- package/theme/create-theme.d.ts +6 -2
- package/theme/index.js +1 -0
- package/chunk-2HKBZFIK.js.map +0 -1
- package/chunk-3DINAQLL.js.map +0 -1
- package/chunk-3ERGAHKA.js +0 -179
- package/chunk-3ERGAHKA.js.map +0 -1
- package/chunk-6C7CGJX2.js +0 -86
- package/chunk-6C7CGJX2.js.map +0 -1
- package/chunk-6QMSWITQ.js.map +0 -1
- package/chunk-6YXUBP27.js.map +0 -1
- package/chunk-72OCFAPT.js.map +0 -1
- package/chunk-7TXHCRAG.js.map +0 -1
- package/chunk-A5XEM3GF.js.map +0 -1
- package/chunk-AN2RNJLR.js.map +0 -1
- package/chunk-B2K45IUR.js.map +0 -1
- package/chunk-B6V4VSGH.js.map +0 -1
- package/chunk-BKZBWPUH.js.map +0 -1
- package/chunk-BNTPPZCK.js.map +0 -1
- package/chunk-BNZVTLHV.js.map +0 -1
- package/chunk-CL2II6BX.js.map +0 -1
- package/chunk-D7RZNTFC.js +0 -95
- package/chunk-D7RZNTFC.js.map +0 -1
- package/chunk-DETGJAIC.js +0 -147
- package/chunk-DETGJAIC.js.map +0 -1
- package/chunk-DO3TBNSC.js.map +0 -1
- package/chunk-ESC5JCVQ.js +0 -90
- package/chunk-ESC5JCVQ.js.map +0 -1
- package/chunk-FDKIX4DC.js.map +0 -1
- package/chunk-GICKPMJU.js.map +0 -1
- package/chunk-GQA24FYG.js +0 -57
- package/chunk-GQA24FYG.js.map +0 -1
- package/chunk-H4NU7NPO.js.map +0 -1
- package/chunk-H63FYCMY.js +0 -11
- package/chunk-H63FYCMY.js.map +0 -1
- package/chunk-HL42K2NH.js.map +0 -1
- package/chunk-HNQUX43Z.js +0 -109
- package/chunk-HNQUX43Z.js.map +0 -1
- package/chunk-HRKPV66B.js +0 -32
- package/chunk-HRKPV66B.js.map +0 -1
- package/chunk-J3NSDRVH.js.map +0 -1
- package/chunk-JPNWHWAQ.js.map +0 -1
- package/chunk-KNUWZNFV.js.map +0 -1
- package/chunk-L6NCCSIP.js.map +0 -1
- package/chunk-LLHTVIM3.js.map +0 -1
- package/chunk-LW3TRU5W.js.map +0 -1
- package/chunk-LZMKSFCF.js.map +0 -1
- package/chunk-MR3JDI7E.js +0 -122
- package/chunk-MR3JDI7E.js.map +0 -1
- package/chunk-NN6PKJWS.js.map +0 -1
- package/chunk-NSRTTYQ4.js.map +0 -1
- package/chunk-O7F3CIDV.js.map +0 -1
- package/chunk-P4O6TGDR.js.map +0 -1
- package/chunk-PF3YBUKT.js.map +0 -1
- package/chunk-PVOLDO4G.js +0 -47
- package/chunk-PVOLDO4G.js.map +0 -1
- package/chunk-QS4N4MNP.js.map +0 -1
- package/chunk-QUF2IPOZ.js.map +0 -1
- package/chunk-RTJ76X5U.js.map +0 -1
- package/chunk-SH6NG6VN.js.map +0 -1
- package/chunk-SHDFUXYV.js.map +0 -1
- package/chunk-TKO44NDI.js +0 -84
- package/chunk-TKO44NDI.js.map +0 -1
- package/chunk-TVLGZGYN.js +0 -59
- package/chunk-TVLGZGYN.js.map +0 -1
- package/chunk-TX3H3QMA.js.map +0 -1
- package/chunk-UBNHSZSE.js.map +0 -1
- package/chunk-UC3ZJWOD.js +0 -73
- package/chunk-UC3ZJWOD.js.map +0 -1
- package/chunk-UGRSWP6U.js.map +0 -1
- package/chunk-VAGIAREV.js.map +0 -1
- package/chunk-WTMZT3IT.js +0 -105
- package/chunk-WTMZT3IT.js.map +0 -1
- package/chunk-WX6BP5ZP.js +0 -39
- package/chunk-WX6BP5ZP.js.map +0 -1
- package/chunk-X3PQANZO.js.map +0 -1
- package/chunk-XILQ7GXE.js.map +0 -1
- package/chunk-XL75JRUA.js.map +0 -1
- package/chunk-XZNHT6MO.js.map +0 -1
- package/chunk-Y5AYU7PK.js.map +0 -1
- package/chunk-YG7JOOLJ.js.map +0 -1
- package/chunk-YPJYW624.js +0 -195
- package/chunk-YPJYW624.js.map +0 -1
- package/chunk-YPNKBE5X.js.map +0 -1
- package/chunk-YX5VNRJX.js.map +0 -1
- package/components/accordion.js.map +0 -1
- package/components/agent-loading.js.map +0 -1
- package/components/agent-picker.js.map +0 -1
- package/components/agent-suggestion.js.map +0 -1
- package/components/announcement-bar.js.map +0 -1
- package/components/attachment.js.map +0 -1
- package/components/avatar.js.map +0 -1
- package/components/badge.js.map +0 -1
- package/components/banner-mesh.js.map +0 -1
- package/components/banner.js.map +0 -1
- package/components/bar-chart.js.map +0 -1
- package/components/breadcrumb.js.map +0 -1
- package/components/button.js.map +0 -1
- package/components/card.js.map +0 -1
- package/components/channel-chart.js.map +0 -1
- package/components/chart.js.map +0 -1
- package/components/checkbox.js.map +0 -1
- package/components/chip.js.map +0 -1
- package/components/citations.js.map +0 -1
- package/components/code-block.js.map +0 -1
- package/components/combobox.js.map +0 -1
- package/components/command-menu.js.map +0 -1
- package/components/context-menu.js.map +0 -1
- package/components/cookie-consent.js.map +0 -1
- package/components/date-picker.js.map +0 -1
- package/components/decision-card.js.map +0 -1
- package/components/dialog.js.map +0 -1
- package/components/donut-chart.js.map +0 -1
- package/components/dot.js.map +0 -1
- package/components/dropdown.js.map +0 -1
- package/components/empty-state.js.map +0 -1
- package/components/file-upload.js.map +0 -1
- package/components/floating.js.map +0 -1
- package/components/form-field.js.map +0 -1
- package/components/hover-card.js.map +0 -1
- package/components/input-otp.js.map +0 -1
- package/components/input.js.map +0 -1
- package/components/kbd.js.map +0 -1
- package/components/line-chart.js.map +0 -1
- package/components/message-actions.js.map +0 -1
- package/components/message.js.map +0 -1
- package/components/number-input.js.map +0 -1
- package/components/pagination.js.map +0 -1
- package/components/popover.js.map +0 -1
- package/components/progress.js.map +0 -1
- package/components/prompt-bar.js.map +0 -1
- package/components/radio.js.map +0 -1
- package/components/search-bar.js.map +0 -1
- package/components/segmented-control.js.map +0 -1
- package/components/select.js.map +0 -1
- package/components/sheet.js.map +0 -1
- package/components/sidebar.js.map +0 -1
- package/components/skeleton.js.map +0 -1
- package/components/slider.js.map +0 -1
- package/components/sliding-indicator.js.map +0 -1
- package/components/streaming-text.js.map +0 -1
- package/components/switch.js.map +0 -1
- package/components/table.js.map +0 -1
- package/components/tabs.js.map +0 -1
- package/components/textarea.js.map +0 -1
- package/components/thinking.js.map +0 -1
- package/components/toast.js.map +0 -1
- package/components/toggle.js.map +0 -1
- package/components/tooltip.js.map +0 -1
- package/index.js.map +0 -1
- package/lib/utils.js.map +0 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# @uisatin/ui
|
|
2
|
+
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 0d40736: Satin now sits next to an app's own Tailwind or shadcn/ui theme without touching it. The stylesheet's classes carry Satin's prefix (`sa:flex`), its theme variables are `--sa-*` (`--sa-text-sm`, `--sa-color-blue-600`, `--sa-radius`, `--sa-chart-1`…), and Tailwind's reset and Satin's base rules apply only to Satin's elements, so the app's `text-sm`, `--spacing`, `--radius`, list styles and headings stay the app's in either import order. Tailwind classes passed in `className` still replace the Satin classes they conflict with.
|
|
8
|
+
|
|
9
|
+
Breaking for custom CSS that read Satin's primitive variables: use `--sa-color-*` and `--sa-radius-*` instead of `--color-*` and `--radius-*` (semantic tokens like `--bg-card` and `--action-primary-bg` are unchanged). `themeCss()` writes the new names. The shadcn registry ships the same prefixed source. The empty source maps are gone from the package.
|
|
10
|
+
|
|
11
|
+
- 9a4b332: Every component now takes ordinary HTML attributes and a `ref` (`id`, `data-*`, `aria-*`, `style`, handlers): fields pass them to the control a label points at (Select's trigger, NumberInput's input), overlays to their panel (Dialog, Sheet, Popover, menus, Tooltip's bubble). Each component's docs comment says where they go. Tabs' extra props are now typed.
|
|
12
|
+
|
|
13
|
+
New `SatinLabels` (`@uisatin/ui/labels`): the words components say on their own (Close, Increase, Select all rows, Pick a date…) are English by default and can be translated or reworded for an app or part of it. A component's own prop still wins.
|
|
14
|
+
|
|
15
|
+
Table: a column's `key` must be a field of the row unless the column renders its own `cell`, so a typo is a type error; rows no longer need an index signature. Internal helpers still exported from the root (`CloseIcon`, `menuItemClass`, `FieldChrome`…) are marked `@internal`.
|
|
16
|
+
|
|
17
|
+
## 0.2.0
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- c1fdcb5: AvatarGroup: avatars side by side share one name tooltip. The first name still waits 400 ms; after that, moving to the next person slides the tooltip over to them and eases its width to the new name, instead of closing one tooltip and opening another. It closes 150 ms after the pointer leaves the row, so the gaps between faces don't close it. Focus shows it at once; Escape and blur hide it.
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- c1fdcb5: Accordion and expanding groups: the content no longer scales while it opens. Chrome drew the scaled text as a bitmap, so it looked heavier until the animation ended, and the Accordion's open item did it on every page load. The section still grows downwards from under its header.
|
|
26
|
+
- 2fdb885: The package now links its source (`repository`, `bugs`), states `engines.node >=20.19` (it's ESM only), ships its CHANGELOG, and is published with npm provenance from the public repository.
|
|
27
|
+
|
|
28
|
+
## 0.1.1
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- fd01b6e: Banner and Announcement bar: the mesh glows are now inlined as WebP data URIs (`banner-mesh`), so they show in any app. In 0.1.0 they pointed at `/figma/*.png` on uisatin.dev and were missing everywhere else.
|
|
33
|
+
- cb6f3e1: Type declarations now resolve under TypeScript `moduleResolution` `node16` and `nodenext`: relative imports in the `.d.ts` files carry their `.js` extension (folders point at `index.js`). `bundler` resolution is unchanged.
|
package/README.md
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
# @uisatin/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@uisatin/ui)
|
|
4
|
+
[](https://github.com/maciej-kownacki/ui-satin/actions/workflows/ci.yml)
|
|
5
|
+
[](https://github.com/maciej-kownacki/ui-satin/blob/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
Satin's React components: shadcn-based, built on Radix, themed with Satin tokens.
|
|
8
|
+
|
|
9
|
+
[Docs](https://uisatin.dev) · [Source](https://github.com/maciej-kownacki/ui-satin/tree/main/packages/ui) · [Changelog](https://github.com/maciej-kownacki/ui-satin/blob/main/packages/ui/CHANGELOG.md) · [Issues](https://github.com/maciej-kownacki/ui-satin/issues)
|
|
4
10
|
|
|
5
11
|
**Satin Free.** This package is the free, open-source edition of Satin, under the MIT license. Satin Pro, with more components, patterns and templates, will ship separately as its own licensed package; nothing here changes when it does.
|
|
6
12
|
|
|
7
|
-
You don't need Tailwind. Satin ships one precompiled stylesheet with the tokens and every class the components use.
|
|
13
|
+
You don't need Tailwind. Satin ships one precompiled stylesheet with the tokens and every class the components use. If your app has its own Tailwind (v3 or v4) or a shadcn/ui theme, the two don't touch: Satin's classes are prefixed (`sa:flex`), its variables are `--sa-*`, and its reset only applies to Satin's elements, so your `text-sm`, `--spacing` or `--radius` stay yours in either import order.
|
|
8
14
|
|
|
9
15
|
## Install
|
|
10
16
|
|
|
@@ -12,7 +18,9 @@ You don't need Tailwind. Satin ships one precompiled stylesheet with the tokens
|
|
|
12
18
|
npm i @uisatin/ui
|
|
13
19
|
```
|
|
14
20
|
|
|
15
|
-
React 19 or newer is
|
|
21
|
+
Requirements: React 19 or newer (peer dependency). The package is ESM only; Node 20.19 or newer can also `require()` it. Every entry point is marked `'use client'`, so it works in React Server Components apps (Next.js App Router).
|
|
22
|
+
|
|
23
|
+
Versions: Satin is 0.x. Until 1.0 a minor release (0.2 → 0.3) may change an API; patches don't. Every change is in the changelog.
|
|
16
24
|
|
|
17
25
|
## Use
|
|
18
26
|
|
|
@@ -35,6 +43,15 @@ export function Save() {
|
|
|
35
43
|
|
|
36
44
|
**Dark mode:** add the `dark` class to `<html>` or any parent element.
|
|
37
45
|
|
|
46
|
+
**Customizing:**
|
|
47
|
+
|
|
48
|
+
- Props first: `variant`, `size`, `tone`, `shape` cover what the design system allows.
|
|
49
|
+
- `className` takes your own classes and lands on the component's root. With Tailwind in your app, a utility there replaces the Satin class it conflicts with (`<Button className="px-6">` drops Satin's padding for yours). Without Tailwind, use your own CSS classes; a Tailwind class name alone does nothing, because Satin's stylesheet only contains its own prefixed classes.
|
|
50
|
+
- Theme: brand colour and corners with `themeCss({ brand, radius })` or the customizer at https://uisatin.dev/theming. Semantic tokens (`--bg-card`, `--text-muted`, `--action-primary-bg`…) can be set in your CSS too.
|
|
51
|
+
- Words: the labels components say on their own (Close, Increase, Select all rows…) are English by default. Wrap the app in `<SatinLabels labels={{ close: 'Zamknij' }}>` (from `@uisatin/ui/labels`) to translate or reword any of them.
|
|
52
|
+
- HTML attributes and `ref`: every component passes `id`, `data-*`, `aria-*`, handlers and `ref` to its main element (the control for fields, the panel for overlays); each component's docs comment says which.
|
|
53
|
+
- Satin's CSS sits in cascade layers (`theme`, `base`, `components`, `utilities`). Your unlayered rules win over it, so a global `p { margin: … }` also reaches a paragraph inside a Satin Card; scope those rules or put them in `@layer base`.
|
|
54
|
+
|
|
38
55
|
**Font:** the tokens ask for Geist and Geist Mono; load them (for example with `@fontsource-variable/geist`) or the system font is used.
|
|
39
56
|
|
|
40
57
|
## Copy the source instead (shadcn registry)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { useSlidingIndicator } from './chunk-XETMIETJ.js';
|
|
2
|
+
import { cn } from './chunk-O46O6LFQ.js';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Tabs as Tabs$1 } from 'radix-ui';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var list = cva("sa:relative sa:flex", {
|
|
9
|
+
variants: {
|
|
10
|
+
variant: {
|
|
11
|
+
// The rule is an inset shadow, so the 2px indicator can sit on top of it (as in Figma).
|
|
12
|
+
underline: "sa:items-end sa:gap-8 sa:[box-shadow:inset_0_-1px_0_var(--border-default)]",
|
|
13
|
+
pill: "sa:items-center sa:gap-1"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
var trigger = cva(
|
|
18
|
+
[
|
|
19
|
+
"sa:group/tab sa:relative sa:flex sa:shrink-0 sa:items-center sa:font-medium sa:whitespace-nowrap sa:text-text-muted sa:select-none",
|
|
20
|
+
"sa:transition-[color,background-color,box-shadow] sa:duration-(--sa-duration-fast) sa:ease-(--sa-ease-out)",
|
|
21
|
+
"sa:focus-visible:outline-none sa:disabled:pointer-events-none sa:disabled:opacity-50",
|
|
22
|
+
"sa:satin-hover:text-text-default sa:satin-focus:text-text-default sa:data-[state=active]:text-text-default",
|
|
23
|
+
"sa:[&_svg]:pointer-events-none sa:[&_svg]:size-4 sa:[&_svg]:shrink-0 sa:[&_svg]:[stroke-width:1.875]"
|
|
24
|
+
],
|
|
25
|
+
{
|
|
26
|
+
variants: {
|
|
27
|
+
variant: {
|
|
28
|
+
underline: "",
|
|
29
|
+
pill: [
|
|
30
|
+
"sa:rounded-pill",
|
|
31
|
+
"sa:data-[state=inactive]:satin-hover:bg-bg-muted",
|
|
32
|
+
"sa:satin-focus:[box-shadow:0_0_0_1px_var(--border-focus)]"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
size: {
|
|
36
|
+
md: "sa:text-base",
|
|
37
|
+
sm: "sa:text-sm"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
compoundVariants: [
|
|
41
|
+
{ variant: "sa:underline", size: "md", className: "sa:h-control-height-xl" },
|
|
42
|
+
{ variant: "sa:underline", size: "sm", className: "sa:h-control-height-lg" },
|
|
43
|
+
{ variant: "pill", size: "md", className: "sa:h-control-height-lg sa:px-3" },
|
|
44
|
+
{ variant: "pill", size: "sm", className: "sa:h-control-height sa:px-2.5" }
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
function normalize(item) {
|
|
49
|
+
return typeof item === "string" ? { value: item, label: item } : item;
|
|
50
|
+
}
|
|
51
|
+
function Tabs({
|
|
52
|
+
items,
|
|
53
|
+
value,
|
|
54
|
+
defaultValue,
|
|
55
|
+
onValueChange,
|
|
56
|
+
variant = "underline",
|
|
57
|
+
size = "md",
|
|
58
|
+
disabled = false,
|
|
59
|
+
children,
|
|
60
|
+
className,
|
|
61
|
+
"aria-label": ariaLabel,
|
|
62
|
+
...props
|
|
63
|
+
}) {
|
|
64
|
+
const tabs = items.map(normalize);
|
|
65
|
+
const listRef = React.useRef(null);
|
|
66
|
+
const [current, setCurrent] = React.useState(value ?? defaultValue ?? tabs[0]?.value);
|
|
67
|
+
const selected = value ?? current;
|
|
68
|
+
const indicator = useSlidingIndicator(listRef, '[role="tab"][data-state="active"]', `${selected}|${variant}|${size}|${tabs.length}`);
|
|
69
|
+
return /* @__PURE__ */ jsxs(
|
|
70
|
+
Tabs$1.Root,
|
|
71
|
+
{
|
|
72
|
+
...props,
|
|
73
|
+
"data-slot": "tabs",
|
|
74
|
+
value,
|
|
75
|
+
defaultValue: defaultValue ?? (value === void 0 ? tabs[0]?.value : void 0),
|
|
76
|
+
onValueChange: (v) => {
|
|
77
|
+
setCurrent(v);
|
|
78
|
+
onValueChange?.(v);
|
|
79
|
+
},
|
|
80
|
+
className: cn("sa:flex sa:flex-col", className),
|
|
81
|
+
children: [
|
|
82
|
+
/* @__PURE__ */ jsxs(Tabs$1.List, { ref: listRef, "aria-label": ariaLabel, className: list({ variant }), children: [
|
|
83
|
+
/* @__PURE__ */ jsx(
|
|
84
|
+
"span",
|
|
85
|
+
{
|
|
86
|
+
ref: indicator.ref,
|
|
87
|
+
"aria-hidden": true,
|
|
88
|
+
className: cn(
|
|
89
|
+
"sa:pointer-events-none sa:absolute sa:left-0 sa:opacity-0",
|
|
90
|
+
variant === "sa:underline" ? "sa:bottom-0 sa:z-10 sa:h-0.5 sa:rounded-full sa:bg-action-primary-bg" : "sa:top-1/2 sa:z-0 sa:-translate-y-1/2 sa:rounded-pill sa:bg-bg-selected",
|
|
91
|
+
variant === "pill" && (size === "md" ? "sa:h-control-height-lg" : "sa:h-control-height")
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
),
|
|
95
|
+
tabs.map((tab) => /* @__PURE__ */ jsxs(
|
|
96
|
+
Tabs$1.Trigger,
|
|
97
|
+
{
|
|
98
|
+
value: tab.value,
|
|
99
|
+
disabled: disabled || tab.disabled,
|
|
100
|
+
...children == null && { "aria-controls": void 0 },
|
|
101
|
+
className: cn(
|
|
102
|
+
trigger({ variant, size }),
|
|
103
|
+
variant === "pill" && "sa:z-10",
|
|
104
|
+
// Before the indicator is placed (server render), the selected tab paints its own.
|
|
105
|
+
!indicator.ready && variant === "pill" && "sa:data-[state=active]:bg-bg-selected"
|
|
106
|
+
),
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ jsxs(
|
|
109
|
+
"span",
|
|
110
|
+
{
|
|
111
|
+
className: cn(
|
|
112
|
+
"sa:flex sa:items-center sa:gap-1.5 sa:rounded-sm",
|
|
113
|
+
variant === "sa:underline" && "sa:group-focus-visible/tab:[box-shadow:inset_0_0_0_1.5px_var(--border-focus)] sa:group-data-[force=focus]/tab:[box-shadow:inset_0_0_0_1.5px_var(--border-focus)]"
|
|
114
|
+
),
|
|
115
|
+
children: [
|
|
116
|
+
tab.icon,
|
|
117
|
+
tab.label
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
),
|
|
121
|
+
variant === "underline" && /* @__PURE__ */ jsx(
|
|
122
|
+
"span",
|
|
123
|
+
{
|
|
124
|
+
"aria-hidden": true,
|
|
125
|
+
className: cn(
|
|
126
|
+
"sa:absolute sa:inset-x-0 sa:bottom-0 sa:h-0.5 sa:rounded-full sa:bg-transparent",
|
|
127
|
+
"sa:transition-colors sa:duration-(--sa-duration-fast) sa:ease-(--sa-ease-out)",
|
|
128
|
+
"sa:group-data-[state=inactive]/tab:group-hover/tab:bg-border-strong sa:group-data-[state=inactive]/tab:group-data-[force=hover]/tab:bg-border-strong",
|
|
129
|
+
!indicator.ready && "sa:group-data-[state=active]/tab:bg-action-primary-bg"
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
)
|
|
133
|
+
]
|
|
134
|
+
},
|
|
135
|
+
tab.value
|
|
136
|
+
))
|
|
137
|
+
] }),
|
|
138
|
+
children
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
function TabsContent({ className, ...props }) {
|
|
144
|
+
return /* @__PURE__ */ jsx(Tabs$1.Content, { "data-slot": "tabs-content", className: cn("sa:rounded-md sa:focus-visible:shadow-border-focus sa:focus-visible:outline-none", className), ...props });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export { Tabs, TabsContent };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { KbdHint, KbdArrowUp, KbdArrowDown, KbdReturn } from './chunk-
|
|
2
|
-
import { Button } from './chunk-
|
|
3
|
-
import {
|
|
1
|
+
import { KbdHint, KbdArrowUp, KbdArrowDown, KbdReturn } from './chunk-57QEOCDZ.js';
|
|
2
|
+
import { Button } from './chunk-T6L32XXH.js';
|
|
3
|
+
import { useSatinLabels } from './chunk-SSOFFQ5T.js';
|
|
4
|
+
import { cn } from './chunk-O46O6LFQ.js';
|
|
4
5
|
import * as React from 'react';
|
|
5
6
|
import { Popover, DropdownMenu } from 'radix-ui';
|
|
6
|
-
import { Attachment, Globe, Plus, ArrowUp, Search, Check, Microphone, Xmark, Page
|
|
7
|
+
import { Attachment, Globe, Plus, ArrowUp, Search, NavArrowDown, Check, Microphone, Xmark, Page } from 'iconoir-react';
|
|
7
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
9
|
|
|
9
10
|
var defaultActions = [
|
|
@@ -11,10 +12,10 @@ var defaultActions = [
|
|
|
11
12
|
{ id: "web", label: "Web search", description: "Research and find on the internet", icon: /* @__PURE__ */ jsx(Globe, {}) }
|
|
12
13
|
];
|
|
13
14
|
var menuCard = [
|
|
14
|
-
"overflow-clip rounded-xl border border-border-subtle bg-bg-popover",
|
|
15
|
-
"[box-shadow:0_1px_3px_0_var(--effect-shadow-sm),0_1px_2px_-1px_var(--effect-shadow-sm)]",
|
|
16
|
-
"origin-(--radix-popper-transform-origin) data-[state=open]:animate-[satin-enter_var(--duration-base)_var(--ease-out)]",
|
|
17
|
-
"focus-visible:outline-none"
|
|
15
|
+
"sa:overflow-clip sa:rounded-xl sa:border sa:border-border-subtle sa:bg-bg-popover",
|
|
16
|
+
"sa:[box-shadow:0_1px_3px_0_var(--effect-shadow-sm),0_1px_2px_-1px_var(--effect-shadow-sm)]",
|
|
17
|
+
"sa:origin-(--radix-popper-transform-origin) sa:data-[state=open]:animate-[satin-enter_var(--sa-duration-base)_var(--sa-ease-out)]",
|
|
18
|
+
"sa:focus-visible:outline-none"
|
|
18
19
|
];
|
|
19
20
|
function PromptBar({
|
|
20
21
|
shape = "pill",
|
|
@@ -36,6 +37,7 @@ function PromptBar({
|
|
|
36
37
|
className,
|
|
37
38
|
...props
|
|
38
39
|
}) {
|
|
40
|
+
const labels = useSatinLabels();
|
|
39
41
|
const [innerValue, setInnerValue] = React.useState(defaultValue);
|
|
40
42
|
const value = valueProp ?? innerValue;
|
|
41
43
|
const [files, setFiles] = React.useState(attachmentsProp ?? []);
|
|
@@ -94,11 +96,11 @@ function PromptBar({
|
|
|
94
96
|
submit();
|
|
95
97
|
},
|
|
96
98
|
className: cn(
|
|
97
|
-
"flex w-full flex-col gap-2 border border-border-default bg-bg-field p-2 [box-shadow:0_1px_2px_0_var(--effect-shadow-xs)]",
|
|
98
|
-
"transition-[border-color,border-radius] duration-(--duration-fast) ease-(--ease-out)",
|
|
99
|
-
"has-[textarea:focus]:border-border-strong data-filled:border-border-strong",
|
|
100
|
-
pill ? files.length > 0 || expanded ? "rounded-3xl" : "rounded-pill" : "rounded-xl",
|
|
101
|
-
disabled && "opacity-50",
|
|
99
|
+
"sa:flex sa:w-full sa:flex-col sa:gap-2 sa:border sa:border-border-default sa:bg-bg-field sa:p-2 sa:[box-shadow:0_1px_2px_0_var(--effect-shadow-xs)]",
|
|
100
|
+
"sa:transition-[border-color,border-radius] sa:duration-(--sa-duration-fast) sa:ease-(--sa-ease-out)",
|
|
101
|
+
"sa:has-[textarea:focus]:border-border-strong sa:data-filled:border-border-strong",
|
|
102
|
+
pill ? files.length > 0 || expanded ? "sa:rounded-3xl" : "sa:rounded-pill" : "sa:rounded-xl",
|
|
103
|
+
disabled && "sa:opacity-50",
|
|
102
104
|
className
|
|
103
105
|
),
|
|
104
106
|
...props,
|
|
@@ -117,7 +119,7 @@ function PromptBar({
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
),
|
|
120
|
-
files.length > 0 && /* @__PURE__ */ jsx("ul", { "aria-label":
|
|
122
|
+
files.length > 0 && /* @__PURE__ */ jsx("ul", { "aria-label": labels.attachments, className: "sa:flex sa:flex-wrap sa:gap-1 sa:pb-1", children: files.map((file, i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
121
123
|
AttachmentChip,
|
|
122
124
|
{
|
|
123
125
|
file,
|
|
@@ -126,7 +128,7 @@ function PromptBar({
|
|
|
126
128
|
onRemove: () => setAttachments(files.filter((_, j) => j !== i))
|
|
127
129
|
}
|
|
128
130
|
) }, `${file.name}-${i}`)) }),
|
|
129
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex flex-wrap items-end gap-x-2 gap-y-2", expanded && "items-center"), children: [
|
|
131
|
+
/* @__PURE__ */ jsxs("div", { className: cn("sa:flex sa:flex-wrap sa:items-end sa:gap-x-2 sa:gap-y-2", expanded && "sa:items-center"), children: [
|
|
130
132
|
/* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
131
133
|
Button,
|
|
132
134
|
{
|
|
@@ -135,8 +137,8 @@ function PromptBar({
|
|
|
135
137
|
shape: btnShape,
|
|
136
138
|
iconOnly: true,
|
|
137
139
|
disabled,
|
|
138
|
-
"aria-label":
|
|
139
|
-
className: "data-[state=open]:bg-border-input",
|
|
140
|
+
"aria-label": labels.addToConversation,
|
|
141
|
+
className: "sa:data-[state=open]:bg-border-input",
|
|
140
142
|
children: /* @__PURE__ */ jsx(Plus, {})
|
|
141
143
|
}
|
|
142
144
|
) }),
|
|
@@ -148,7 +150,7 @@ function PromptBar({
|
|
|
148
150
|
value,
|
|
149
151
|
disabled,
|
|
150
152
|
placeholder,
|
|
151
|
-
"aria-label":
|
|
153
|
+
"aria-label": labels.message,
|
|
152
154
|
onChange: (e) => setValue(e.target.value),
|
|
153
155
|
onKeyDown: (e) => {
|
|
154
156
|
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
|
|
@@ -157,13 +159,13 @@ function PromptBar({
|
|
|
157
159
|
}
|
|
158
160
|
},
|
|
159
161
|
className: cn(
|
|
160
|
-
"block h-7 min-w-0 flex-1 resize-none bg-transparent py-[3.5px] text-base leading-[21px] text-text-default",
|
|
161
|
-
expanded && "order-first basis-full px-1",
|
|
162
|
-
"outline-none placeholder:text-text-muted focus-visible:ring-0 disabled:cursor-not-allowed"
|
|
162
|
+
"sa:block sa:h-7 sa:min-w-0 sa:flex-1 sa:resize-none sa:bg-transparent sa:py-[3.5px] sa:text-base sa:leading-[21px] sa:text-text-default",
|
|
163
|
+
expanded && "sa:order-first sa:basis-full sa:px-1",
|
|
164
|
+
"sa:outline-none sa:placeholder:text-text-muted sa:focus-visible:ring-0 sa:disabled:cursor-not-allowed"
|
|
163
165
|
)
|
|
164
166
|
}
|
|
165
167
|
),
|
|
166
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex shrink-0 items-center gap-1", expanded && "contents"), children: [
|
|
168
|
+
/* @__PURE__ */ jsxs("div", { className: cn("sa:flex sa:shrink-0 sa:items-center sa:gap-1", expanded && "sa:contents"), children: [
|
|
167
169
|
/* @__PURE__ */ jsx(
|
|
168
170
|
ModelSelect,
|
|
169
171
|
{
|
|
@@ -179,7 +181,7 @@ function PromptBar({
|
|
|
179
181
|
}
|
|
180
182
|
}
|
|
181
183
|
),
|
|
182
|
-
expanded && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "flex-1" }),
|
|
184
|
+
expanded && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "sa:flex-1" }),
|
|
183
185
|
/* @__PURE__ */ jsx(
|
|
184
186
|
DictationButton,
|
|
185
187
|
{
|
|
@@ -192,7 +194,7 @@ function PromptBar({
|
|
|
192
194
|
}
|
|
193
195
|
}
|
|
194
196
|
),
|
|
195
|
-
/* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", size: "md", shape: btnShape, iconOnly: true, "aria-label":
|
|
197
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", variant: "primary", size: "md", shape: btnShape, iconOnly: true, "aria-label": labels.send, disabled: !canSend, children: /* @__PURE__ */ jsx(ArrowUp, {}) })
|
|
196
198
|
] })
|
|
197
199
|
] })
|
|
198
200
|
]
|
|
@@ -205,8 +207,8 @@ function PromptBar({
|
|
|
205
207
|
align: "start",
|
|
206
208
|
sideOffset: 8,
|
|
207
209
|
avoidCollisions: false,
|
|
208
|
-
"aria-label":
|
|
209
|
-
className: cn(menuCard, "z-50 flex w-(--radix-popper-anchor-width) flex-col"),
|
|
210
|
+
"aria-label": labels.addToConversation,
|
|
211
|
+
className: cn(menuCard, "sa:z-50 sa:flex sa:w-(--radix-popper-anchor-width) sa:flex-col"),
|
|
210
212
|
children: /* @__PURE__ */ jsx(AddMenu, { actions, onAction: runAction, onAddAgent })
|
|
211
213
|
}
|
|
212
214
|
) })
|
|
@@ -217,6 +219,7 @@ function AddMenu({
|
|
|
217
219
|
onAction,
|
|
218
220
|
onAddAgent
|
|
219
221
|
}) {
|
|
222
|
+
const labels = useSatinLabels();
|
|
220
223
|
const [query, setQuery] = React.useState("");
|
|
221
224
|
const [active, setActive] = React.useState(0);
|
|
222
225
|
const id = React.useId();
|
|
@@ -224,9 +227,9 @@ function AddMenu({
|
|
|
224
227
|
const shown = q ? actions.filter((a) => `${a.label} ${a.description ?? ""}`.toLowerCase().includes(q)) : actions;
|
|
225
228
|
const index = Math.min(active, Math.max(shown.length - 1, 0));
|
|
226
229
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
227
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 pr-1.5", children: [
|
|
228
|
-
/* @__PURE__ */ jsxs("label", { className: "flex flex-1 items-center gap-2 px-3 py-1.5", children: [
|
|
229
|
-
/* @__PURE__ */ jsx(Search, { "aria-hidden": true, className: "size-icon-size shrink-0 text-text-muted [stroke-width:1.875]" }),
|
|
230
|
+
/* @__PURE__ */ jsxs("div", { className: "sa:flex sa:items-center sa:gap-1 sa:pr-1.5", children: [
|
|
231
|
+
/* @__PURE__ */ jsxs("label", { className: "sa:flex sa:flex-1 sa:items-center sa:gap-2 sa:px-3 sa:py-1.5", children: [
|
|
232
|
+
/* @__PURE__ */ jsx(Search, { "aria-hidden": true, className: "sa:size-icon-size sa:shrink-0 sa:text-text-muted sa:[stroke-width:1.875]" }),
|
|
230
233
|
/* @__PURE__ */ jsx(
|
|
231
234
|
"input",
|
|
232
235
|
{
|
|
@@ -234,7 +237,7 @@ function AddMenu({
|
|
|
234
237
|
"aria-expanded": true,
|
|
235
238
|
"aria-controls": `${id}-list`,
|
|
236
239
|
"aria-activedescendant": shown.length ? `${id}-${index}` : void 0,
|
|
237
|
-
"aria-label":
|
|
240
|
+
"aria-label": labels.searchAgentsAndTools,
|
|
238
241
|
placeholder: "Search agents and tools",
|
|
239
242
|
value: query,
|
|
240
243
|
onChange: (e) => {
|
|
@@ -253,14 +256,14 @@ function AddMenu({
|
|
|
253
256
|
onAction(shown[index]);
|
|
254
257
|
}
|
|
255
258
|
},
|
|
256
|
-
className: "min-w-0 flex-1 bg-transparent text-sm text-text-default outline-none placeholder:text-text-muted focus-visible:ring-0"
|
|
259
|
+
className: "sa:min-w-0 sa:flex-1 sa:bg-transparent sa:text-sm sa:text-text-default sa:outline-none sa:placeholder:text-text-muted sa:focus-visible:ring-0"
|
|
257
260
|
}
|
|
258
261
|
)
|
|
259
262
|
] }),
|
|
260
|
-
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "xs", iconOnly: true, "aria-label":
|
|
263
|
+
/* @__PURE__ */ jsx(Button, { variant: "tertiary", size: "xs", iconOnly: true, "aria-label": labels.addAgent, onClick: onAddAgent, children: /* @__PURE__ */ jsx(Plus, {}) })
|
|
261
264
|
] }),
|
|
262
|
-
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "h-px bg-border-subtle" }),
|
|
263
|
-
/* @__PURE__ */ jsxs("div", { id: `${id}-list`, role: "listbox", "aria-label":
|
|
265
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": true, className: "sa:h-px sa:bg-border-subtle" }),
|
|
266
|
+
/* @__PURE__ */ jsxs("div", { id: `${id}-list`, role: "listbox", "aria-label": labels.agentsAndTools, className: "sa:flex sa:flex-col sa:p-1", children: [
|
|
264
267
|
shown.map((a, i) => /* @__PURE__ */ jsxs(
|
|
265
268
|
"div",
|
|
266
269
|
{
|
|
@@ -271,21 +274,21 @@ function AddMenu({
|
|
|
271
274
|
onMouseDown: (e) => e.preventDefault(),
|
|
272
275
|
onClick: () => onAction(a),
|
|
273
276
|
className: cn(
|
|
274
|
-
"flex min-h-8 items-center gap-2 rounded-lg px-2 py-1.5",
|
|
275
|
-
"[&>svg]:size-icon-size [&>svg]:shrink-0 [&>svg]:text-text-muted [&>svg]:[stroke-width:1.875]",
|
|
276
|
-
i === index && "bg-bg-hover"
|
|
277
|
+
"sa:flex sa:min-h-8 sa:items-center sa:gap-2 sa:rounded-lg sa:px-2 sa:py-1.5",
|
|
278
|
+
"sa:[&>svg]:size-icon-size sa:[&>svg]:shrink-0 sa:[&>svg]:text-text-muted sa:[&>svg]:[stroke-width:1.875]",
|
|
279
|
+
i === index && "sa:bg-bg-hover"
|
|
277
280
|
),
|
|
278
281
|
children: [
|
|
279
282
|
a.icon,
|
|
280
|
-
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-baseline gap-3", children: [
|
|
281
|
-
/* @__PURE__ */ jsx("span", { className: "shrink-0 text-sm leading-[13px] font-medium whitespace-nowrap text-text-default", children: a.label }),
|
|
282
|
-
a.description && /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm text-text-muted", children: a.description })
|
|
283
|
+
/* @__PURE__ */ jsxs("span", { className: "sa:flex sa:min-w-0 sa:flex-1 sa:items-baseline sa:gap-3", children: [
|
|
284
|
+
/* @__PURE__ */ jsx("span", { className: "sa:shrink-0 sa:text-sm sa:leading-[13px] sa:font-medium sa:whitespace-nowrap sa:text-text-default", children: a.label }),
|
|
285
|
+
a.description && /* @__PURE__ */ jsx("span", { className: "sa:min-w-0 sa:flex-1 sa:truncate sa:text-sm sa:text-text-muted", children: a.description })
|
|
283
286
|
] })
|
|
284
287
|
]
|
|
285
288
|
},
|
|
286
289
|
a.id
|
|
287
290
|
)),
|
|
288
|
-
shown.length === 0 && /* @__PURE__ */ jsx("p", { className: "px-2 py-1.5 text-sm text-text-muted", children: "No matches" })
|
|
291
|
+
shown.length === 0 && /* @__PURE__ */ jsx("p", { className: "sa:px-2 sa:py-1.5 sa:text-sm sa:text-text-muted", children: "No matches" })
|
|
289
292
|
] }),
|
|
290
293
|
/* @__PURE__ */ jsx(ShortcutHints, {})
|
|
291
294
|
] });
|
|
@@ -299,6 +302,7 @@ function ModelSelect({
|
|
|
299
302
|
disabled,
|
|
300
303
|
onChange
|
|
301
304
|
}) {
|
|
305
|
+
const labels = useSatinLabels();
|
|
302
306
|
if (!label) return null;
|
|
303
307
|
const trigger = /* @__PURE__ */ jsxs(
|
|
304
308
|
Button,
|
|
@@ -307,10 +311,13 @@ function ModelSelect({
|
|
|
307
311
|
size: "md",
|
|
308
312
|
shape,
|
|
309
313
|
disabled,
|
|
310
|
-
className: "data-[state=open]:bg-border-input",
|
|
314
|
+
className: "sa:data-[state=open]:bg-border-input",
|
|
311
315
|
children: [
|
|
312
|
-
icon && /* @__PURE__ */ jsx("span", { className: "flex size-4 shrink-0 items-center justify-center [&>*]:size-4", children: icon }),
|
|
313
|
-
/* @__PURE__ */
|
|
316
|
+
icon && /* @__PURE__ */ jsx("span", { className: "sa:flex sa:size-4 sa:shrink-0 sa:items-center sa:justify-center sa:[&>*]:size-4", children: icon }),
|
|
317
|
+
/* @__PURE__ */ jsxs("span", { className: "sa:sr-only", children: [
|
|
318
|
+
labels.model,
|
|
319
|
+
": "
|
|
320
|
+
] }),
|
|
314
321
|
label,
|
|
315
322
|
/* @__PURE__ */ jsx(NavArrowDown, { "aria-hidden": true, "data-chevron": true })
|
|
316
323
|
]
|
|
@@ -326,20 +333,20 @@ function ModelSelect({
|
|
|
326
333
|
align: "end",
|
|
327
334
|
sideOffset: 8,
|
|
328
335
|
avoidCollisions: false,
|
|
329
|
-
className: cn(menuCard, "z-50 w-[241px]"),
|
|
336
|
+
className: cn(menuCard, "sa:z-50 sa:w-[241px]"),
|
|
330
337
|
children: [
|
|
331
|
-
/* @__PURE__ */ jsx(DropdownMenu.RadioGroup, { value: model, onValueChange: onChange, className: "flex flex-col p-1", children: models.map((m) => /* @__PURE__ */ jsxs(
|
|
338
|
+
/* @__PURE__ */ jsx(DropdownMenu.RadioGroup, { value: model, onValueChange: onChange, className: "sa:flex sa:flex-col sa:p-1", children: models.map((m) => /* @__PURE__ */ jsxs(
|
|
332
339
|
DropdownMenu.RadioItem,
|
|
333
340
|
{
|
|
334
341
|
value: m.value,
|
|
335
342
|
className: cn(
|
|
336
|
-
"flex min-h-8 cursor-pointer items-center gap-2 rounded-lg px-2 py-1.5 outline-none select-none",
|
|
337
|
-
"data-highlighted:bg-bg-hover data-[state=checked]:bg-bg-selected"
|
|
343
|
+
"sa:flex sa:min-h-8 sa:cursor-pointer sa:items-center sa:gap-2 sa:rounded-lg sa:px-2 sa:py-1.5 sa:outline-none sa:select-none",
|
|
344
|
+
"sa:data-highlighted:bg-bg-hover sa:data-[state=checked]:bg-bg-selected"
|
|
338
345
|
),
|
|
339
346
|
children: [
|
|
340
|
-
/* @__PURE__ */ jsx("span", { className: "flex size-5 shrink-0 items-center justify-center [&>*]:size-5", children: m.icon }),
|
|
341
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-sm leading-[13px] font-medium text-text-default", children: m.label }),
|
|
342
|
-
/* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "size-icon-size text-status-green-fg [stroke-width:1.875]" }) })
|
|
347
|
+
/* @__PURE__ */ jsx("span", { className: "sa:flex sa:size-5 sa:shrink-0 sa:items-center sa:justify-center sa:[&>*]:size-5", children: m.icon }),
|
|
348
|
+
/* @__PURE__ */ jsx("span", { className: "sa:min-w-0 sa:flex-1 sa:truncate sa:text-sm sa:leading-[13px] sa:font-medium sa:text-text-default", children: m.label }),
|
|
349
|
+
/* @__PURE__ */ jsx(DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsx(Check, { "aria-hidden": true, className: "sa:size-icon-size sa:text-status-green-fg sa:[stroke-width:1.875]" }) })
|
|
343
350
|
]
|
|
344
351
|
},
|
|
345
352
|
m.value
|
|
@@ -351,7 +358,7 @@ function ModelSelect({
|
|
|
351
358
|
] });
|
|
352
359
|
}
|
|
353
360
|
function ShortcutHints() {
|
|
354
|
-
return /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: "flex items-center gap-3 border-t border-border-default bg-bg-popover px-3 py-1.5", children: [
|
|
361
|
+
return /* @__PURE__ */ jsxs("div", { "aria-hidden": true, className: "sa:flex sa:items-center sa:gap-3 sa:border-t sa:border-border-default sa:bg-bg-popover sa:px-3 sa:py-1.5", children: [
|
|
355
362
|
/* @__PURE__ */ jsx(KbdHint, { keys: [/* @__PURE__ */ jsx(KbdArrowUp, {}, "up"), /* @__PURE__ */ jsx(KbdArrowDown, {}, "down")], label: "Navigate" }),
|
|
356
363
|
/* @__PURE__ */ jsx(KbdHint, { keys: [/* @__PURE__ */ jsx(KbdReturn, {}, "return")], label: "Select" })
|
|
357
364
|
] });
|
|
@@ -406,15 +413,15 @@ function AttachmentChip({
|
|
|
406
413
|
{
|
|
407
414
|
"data-slot": "attachment",
|
|
408
415
|
className: cn(
|
|
409
|
-
"flex h-control-height items-center gap-1.5 border border-border-default bg-bg-popover pr-0.5 pl-2",
|
|
410
|
-
"[filter:drop-shadow(0_1px_1px_var(--effect-shadow-xs))]",
|
|
411
|
-
"transition-[background-color,border-color] duration-(--duration-fast) ease-(--ease-out)",
|
|
412
|
-
"hover:border-border-strong hover:bg-bg-canvas active:border-border-strong active:bg-bg-muted",
|
|
413
|
-
rounded ? "rounded-pill" : "rounded-md"
|
|
416
|
+
"sa:flex sa:h-control-height sa:items-center sa:gap-1.5 sa:border sa:border-border-default sa:bg-bg-popover sa:pr-0.5 sa:pl-2",
|
|
417
|
+
"sa:[filter:drop-shadow(0_1px_1px_var(--effect-shadow-xs))]",
|
|
418
|
+
"sa:transition-[background-color,border-color] sa:duration-(--sa-duration-fast) sa:ease-(--sa-ease-out)",
|
|
419
|
+
"sa:hover:border-border-strong sa:hover:bg-bg-canvas sa:active:border-border-strong sa:active:bg-bg-muted",
|
|
420
|
+
rounded ? "sa:rounded-pill" : "sa:rounded-md"
|
|
414
421
|
),
|
|
415
422
|
children: [
|
|
416
423
|
/* @__PURE__ */ jsx(FileIcon, { name: file.name }),
|
|
417
|
-
/* @__PURE__ */ jsx("span", { className: "max-w-[200px] truncate text-sm font-medium text-text-default", children: file.name }),
|
|
424
|
+
/* @__PURE__ */ jsx("span", { className: "sa:max-w-[200px] sa:truncate sa:text-sm sa:font-medium sa:text-text-default", children: file.name }),
|
|
418
425
|
/* @__PURE__ */ jsx(
|
|
419
426
|
Button,
|
|
420
427
|
{
|
|
@@ -425,7 +432,7 @@ function AttachmentChip({
|
|
|
425
432
|
disabled,
|
|
426
433
|
"aria-label": `Remove ${file.name}`,
|
|
427
434
|
onClick: onRemove,
|
|
428
|
-
children: /* @__PURE__ */ jsx(Xmark, { className: "
|
|
435
|
+
children: /* @__PURE__ */ jsx(Xmark, { className: "sa:![stroke-width:1.64]" })
|
|
429
436
|
}
|
|
430
437
|
)
|
|
431
438
|
]
|
|
@@ -453,22 +460,20 @@ var LABELS = {
|
|
|
453
460
|
]
|
|
454
461
|
};
|
|
455
462
|
var FILE_COLORS = {
|
|
456
|
-
pdf: ["var(--color-red-500)", "var(--color-red-300)"],
|
|
457
|
-
doc: ["var(--color-sky-600)", "var(--color-sky-300)"],
|
|
458
|
-
xls: ["var(--color-green-700)", "var(--color-green-300)"]
|
|
463
|
+
pdf: ["var(--sa-color-red-500)", "var(--sa-color-red-300)"],
|
|
464
|
+
doc: ["var(--sa-color-sky-600)", "var(--sa-color-sky-300)"],
|
|
465
|
+
xls: ["var(--sa-color-green-700)", "var(--sa-color-green-300)"]
|
|
459
466
|
};
|
|
460
467
|
function FileIcon({ name }) {
|
|
461
468
|
const ext = name.split(".").pop()?.toLowerCase() ?? "";
|
|
462
469
|
const kind = ext === "pdf" ? "pdf" : ext === "doc" || ext === "docx" ? "doc" : ext === "xls" || ext === "xlsx" || ext === "csv" ? "xls" : null;
|
|
463
|
-
if (!kind) return /* @__PURE__ */ jsx(Page, { "aria-hidden": true, className: "size-4 shrink-0 text-text-muted [stroke-width:1.875]" });
|
|
470
|
+
if (!kind) return /* @__PURE__ */ jsx(Page, { "aria-hidden": true, className: "sa:size-4 sa:shrink-0 sa:text-text-muted sa:[stroke-width:1.875]" });
|
|
464
471
|
const [page, fold] = FILE_COLORS[kind];
|
|
465
|
-
return /* @__PURE__ */ jsxs("svg", { "aria-hidden": true, viewBox: "0 0 16 16", fill: "none", className: "size-4 shrink-0", children: [
|
|
472
|
+
return /* @__PURE__ */ jsxs("svg", { "aria-hidden": true, viewBox: "0 0 16 16", fill: "none", className: "sa:size-4 sa:shrink-0", children: [
|
|
466
473
|
/* @__PURE__ */ jsx("path", { d: PAGE, fill: page }),
|
|
467
474
|
/* @__PURE__ */ jsx("path", { d: FOLD, fill: fold }),
|
|
468
|
-
LABELS[kind].map((d, i) => /* @__PURE__ */ jsx("path", { d, fill: "var(--color-white)" }, i))
|
|
475
|
+
LABELS[kind].map((d, i) => /* @__PURE__ */ jsx("path", { d, fill: "var(--sa-color-white)" }, i))
|
|
469
476
|
] });
|
|
470
477
|
}
|
|
471
478
|
|
|
472
479
|
export { PromptBar, defaultActions };
|
|
473
|
-
//# sourceMappingURL=chunk-6YXUBP27.js.map
|
|
474
|
-
//# sourceMappingURL=chunk-6YXUBP27.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from './chunk-
|
|
1
|
+
import { cn } from './chunk-O46O6LFQ.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -11,13 +11,13 @@ function Kbd({ size = "sm", tone = "default", className, children, ...props }) {
|
|
|
11
11
|
"data-slot": "kbd",
|
|
12
12
|
"data-square": square || void 0,
|
|
13
13
|
className: cn(
|
|
14
|
-
"inline-flex shrink-0 items-center justify-center rounded-sm border-[0.75px] font-sans text-2xs leading-none font-medium tracking-normal whitespace-nowrap",
|
|
15
|
-
size === "sm" ? "h-[18px] min-w-[18px]" : "h-5 min-w-5",
|
|
14
|
+
"sa:inline-flex sa:shrink-0 sa:items-center sa:justify-center sa:rounded-sm sa:border-[0.75px] sa:font-sans sa:text-2xs sa:leading-none sa:font-medium sa:tracking-normal sa:whitespace-nowrap",
|
|
15
|
+
size === "sm" ? "sa:h-[18px] sa:min-w-[18px]" : "sa:h-5 sa:min-w-5",
|
|
16
16
|
// A single key is exactly square with nothing on the sides, so the glyph sits in the middle.
|
|
17
|
-
square ? size === "sm" ? "w-[18px] px-0" : "w-5 px-0" : size === "sm" ? "px-1" : "px-1.5",
|
|
18
|
-
tone === "default" ? "border-border-default bg-component-kbd-bg text-text-muted" : "border-action-inverse-border bg-action-inverse-bg-hover text-bg-canvas/72 dark:border-action-inverse-bg-pressed dark:bg-text-default",
|
|
17
|
+
square ? size === "sm" ? "sa:w-[18px] sa:px-0" : "sa:w-5 sa:px-0" : size === "sm" ? "sa:px-1" : "sa:px-1.5",
|
|
18
|
+
tone === "default" ? "sa:border-border-default sa:bg-component-kbd-bg sa:text-text-muted" : "sa:border-action-inverse-border sa:bg-action-inverse-bg-hover sa:text-bg-canvas/72 sa:dark:border-action-inverse-bg-pressed sa:dark:bg-text-default",
|
|
19
19
|
// Glyph icons (arrows, return) take the key's colour at 10px.
|
|
20
|
-
"[&>svg]:size-2.5 [&>svg]:shrink-0",
|
|
20
|
+
"sa:[&>svg]:size-2.5 sa:[&>svg]:shrink-0",
|
|
21
21
|
className
|
|
22
22
|
),
|
|
23
23
|
...props,
|
|
@@ -38,7 +38,7 @@ function keysOf(shortcut) {
|
|
|
38
38
|
}
|
|
39
39
|
function KbdGroup({ keys, size, tone, className, ...props }) {
|
|
40
40
|
const list = typeof keys === "string" ? keysOf(keys) : keys;
|
|
41
|
-
return /* @__PURE__ */ jsx("span", { "data-slot": "kbd-group", className: cn("inline-flex shrink-0 items-center gap-0.5", className), ...props, children: list.map((k, i) => /* @__PURE__ */ jsx(Kbd, { size, tone, children: k }, i)) });
|
|
41
|
+
return /* @__PURE__ */ jsx("span", { "data-slot": "kbd-group", className: cn("sa:inline-flex sa:shrink-0 sa:items-center sa:gap-0.5", className), ...props, children: list.map((k, i) => /* @__PURE__ */ jsx(Kbd, { size, tone, children: k }, i)) });
|
|
42
42
|
}
|
|
43
43
|
var glyph = { viewBox: "0 0 10 10", fill: "none", stroke: "currentColor", strokeWidth: 0.75, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": true };
|
|
44
44
|
var KbdArrowUp = () => /* @__PURE__ */ jsx("svg", { ...glyph, children: /* @__PURE__ */ jsx("path", { d: "M5.00018 8.17963L5.00018 1.82037M8.00316 4.82335L5.00018 1.82037L1.9972 4.82335" }) });
|
|
@@ -48,12 +48,10 @@ var KbdReturn = () => /* @__PURE__ */ jsxs("svg", { ...glyph, children: [
|
|
|
48
48
|
/* @__PURE__ */ jsx("path", { d: "M2.8125 6.5625H5.3125C6.23296 6.5625 6.97917 5.81629 6.97917 4.89583V1.97917" })
|
|
49
49
|
] });
|
|
50
50
|
function KbdHint({ keys, label, className, ...props }) {
|
|
51
|
-
return /* @__PURE__ */ jsxs("span", { "data-slot": "kbd-hint", className: cn("flex items-center gap-1.5", className), ...props, children: [
|
|
51
|
+
return /* @__PURE__ */ jsxs("span", { "data-slot": "kbd-hint", className: cn("sa:flex sa:items-center sa:gap-1.5", className), ...props, children: [
|
|
52
52
|
/* @__PURE__ */ jsx(KbdGroup, { keys }),
|
|
53
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs leading-4 tracking-normal whitespace-nowrap text-text-muted", children: label })
|
|
53
|
+
/* @__PURE__ */ jsx("span", { className: "sa:text-xs sa:leading-4 sa:tracking-normal sa:whitespace-nowrap sa:text-text-muted", children: label })
|
|
54
54
|
] });
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export { Kbd, KbdArrowDown, KbdArrowUp, KbdGroup, KbdHint, KbdReturn, keysOf };
|
|
58
|
-
//# sourceMappingURL=chunk-BKZBWPUH.js.map
|
|
59
|
-
//# sourceMappingURL=chunk-BKZBWPUH.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { cn } from './chunk-
|
|
1
|
+
import { cn } from './chunk-O46O6LFQ.js';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { jsx } from 'react/jsx-runtime';
|
|
4
4
|
|
|
@@ -114,7 +114,7 @@ function StreamingText({
|
|
|
114
114
|
"data-slot": "streaming-text",
|
|
115
115
|
"data-reveal": reveal,
|
|
116
116
|
"aria-busy": streaming || void 0,
|
|
117
|
-
className: cn("satin-stream text-body whitespace-pre-wrap text-text-default", className),
|
|
117
|
+
className: cn("satin-stream sa:text-body sa:whitespace-pre-wrap sa:text-text-default", className),
|
|
118
118
|
...props,
|
|
119
119
|
children: units.map((u, i) => /* @__PURE__ */ jsx("span", { className: "satin-stream-unit", children: u }, i))
|
|
120
120
|
}
|
|
@@ -122,5 +122,3 @@ function StreamingText({
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
export { StreamingText };
|
|
125
|
-
//# sourceMappingURL=chunk-RTJ76X5U.js.map
|
|
126
|
-
//# sourceMappingURL=chunk-RTJ76X5U.js.map
|