@heyramzi/ui 3.4.0 → 3.6.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/COMPONENTS.md +2 -0
- package/dist/ai/chat-window/icons.js +43 -0
- package/dist/ai/chat-window/index.js +5 -0
- package/dist/ai/chat-window/labels.js +16 -0
- package/dist/ai/chat-window/reveal.svelte.js +106 -0
- package/dist/ai/chat-window/types.js +4 -0
- package/dist/components/copy/clipboard.js +3 -3
- package/dist/components/flag/codes.js +13 -0
- package/dist/components/flag/index.js +2 -0
- package/dist/slides/export/pdf.js +7 -0
- package/dist/vite/flags.js +46 -0
- package/package.json +7 -2
- package/src/ai/chat-window/ChatGlyph.svelte +38 -0
- package/src/ai/chat-window/ChatGlyph.svelte.d.ts +9 -0
- package/src/ai/chat-window/ChatGptWindow.svelte +636 -0
- package/src/ai/chat-window/ChatGptWindow.svelte.d.ts +25 -0
- package/src/ai/chat-window/ClaudeWindow.svelte +668 -0
- package/src/ai/chat-window/ClaudeWindow.svelte.d.ts +25 -0
- package/src/ai/chat-window/chat-window.test.ts +80 -0
- package/src/ai/chat-window/icons/LICENSE +24 -0
- package/src/ai/chat-window/icons/chatgpt-chevron.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-copy.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-mic.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-more.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-plus.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-regenerate.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-share.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-sidebar.svg +1 -0
- package/src/ai/chat-window/icons/chatgpt-thumb.svg +2 -0
- package/src/ai/chat-window/icons/chatgpt-voice.svg +2 -0
- package/src/ai/chat-window/icons/claude-chevron.svg +1 -0
- package/src/ai/chat-window/icons/claude-copy.svg +1 -0
- package/src/ai/chat-window/icons/claude-plus.svg +1 -0
- package/src/ai/chat-window/icons/claude-retry.svg +1 -0
- package/src/ai/chat-window/icons/claude-send.svg +1 -0
- package/src/ai/chat-window/icons/claude-sidebar.svg +1 -0
- package/src/ai/chat-window/icons/claude-sliders.svg +1 -0
- package/src/ai/chat-window/icons/claude-spark.svg +1 -0
- package/src/ai/chat-window/icons/claude-thumb.svg +1 -0
- package/src/ai/chat-window/icons.ts +46 -0
- package/src/ai/chat-window/index.ts +26 -0
- package/src/ai/chat-window/labels.ts +39 -0
- package/src/ai/chat-window/reveal.svelte.ts +106 -0
- package/src/ai/chat-window/types.ts +42 -0
- package/src/components/copy/clipboard.test.ts +17 -1
- package/src/components/copy/clipboard.ts +3 -3
- package/src/components/flag/codes.test.ts +30 -0
- package/src/components/flag/codes.ts +25 -0
- package/src/components/flag/flag.svelte +51 -0
- package/src/components/flag/flag.svelte.d.ts +12 -0
- package/src/components/flag/flags/AD.svg +1 -0
- package/src/components/flag/flags/AE.svg +1 -0
- package/src/components/flag/flags/AF.svg +1 -0
- package/src/components/flag/flags/AG.svg +1 -0
- package/src/components/flag/flags/AI.svg +1 -0
- package/src/components/flag/flags/AL.svg +1 -0
- package/src/components/flag/flags/AM.svg +1 -0
- package/src/components/flag/flags/AO.svg +1 -0
- package/src/components/flag/flags/AQ.svg +1 -0
- package/src/components/flag/flags/AR.svg +1 -0
- package/src/components/flag/flags/AS.svg +1 -0
- package/src/components/flag/flags/AT.svg +1 -0
- package/src/components/flag/flags/AU.svg +1 -0
- package/src/components/flag/flags/AW.svg +1 -0
- package/src/components/flag/flags/AX.svg +1 -0
- package/src/components/flag/flags/AZ.svg +1 -0
- package/src/components/flag/flags/BA.svg +1 -0
- package/src/components/flag/flags/BB.svg +1 -0
- package/src/components/flag/flags/BD.svg +1 -0
- package/src/components/flag/flags/BE.svg +1 -0
- package/src/components/flag/flags/BF.svg +1 -0
- package/src/components/flag/flags/BG.svg +1 -0
- package/src/components/flag/flags/BH.svg +1 -0
- package/src/components/flag/flags/BI.svg +1 -0
- package/src/components/flag/flags/BJ.svg +1 -0
- package/src/components/flag/flags/BL.svg +1 -0
- package/src/components/flag/flags/BM.svg +1 -0
- package/src/components/flag/flags/BN.svg +1 -0
- package/src/components/flag/flags/BO.svg +1 -0
- package/src/components/flag/flags/BQ.svg +1 -0
- package/src/components/flag/flags/BR.svg +1 -0
- package/src/components/flag/flags/BS.svg +1 -0
- package/src/components/flag/flags/BT.svg +1 -0
- package/src/components/flag/flags/BV.svg +1 -0
- package/src/components/flag/flags/BW.svg +1 -0
- package/src/components/flag/flags/BY.svg +1 -0
- package/src/components/flag/flags/BZ.svg +1 -0
- package/src/components/flag/flags/CA.svg +1 -0
- package/src/components/flag/flags/CC.svg +1 -0
- package/src/components/flag/flags/CD.svg +1 -0
- package/src/components/flag/flags/CF.svg +1 -0
- package/src/components/flag/flags/CG.svg +1 -0
- package/src/components/flag/flags/CH.svg +1 -0
- package/src/components/flag/flags/CI.svg +1 -0
- package/src/components/flag/flags/CK.svg +1 -0
- package/src/components/flag/flags/CL.svg +1 -0
- package/src/components/flag/flags/CM.svg +1 -0
- package/src/components/flag/flags/CN.svg +1 -0
- package/src/components/flag/flags/CO.svg +1 -0
- package/src/components/flag/flags/CR.svg +1 -0
- package/src/components/flag/flags/CU.svg +1 -0
- package/src/components/flag/flags/CV.svg +1 -0
- package/src/components/flag/flags/CW.svg +1 -0
- package/src/components/flag/flags/CX.svg +1 -0
- package/src/components/flag/flags/CY.svg +1 -0
- package/src/components/flag/flags/CZ.svg +1 -0
- package/src/components/flag/flags/DE.svg +1 -0
- package/src/components/flag/flags/DJ.svg +1 -0
- package/src/components/flag/flags/DK.svg +1 -0
- package/src/components/flag/flags/DM.svg +1 -0
- package/src/components/flag/flags/DO.svg +1 -0
- package/src/components/flag/flags/DZ.svg +1 -0
- package/src/components/flag/flags/EC.svg +1 -0
- package/src/components/flag/flags/EE.svg +1 -0
- package/src/components/flag/flags/EG.svg +1 -0
- package/src/components/flag/flags/EH.svg +1 -0
- package/src/components/flag/flags/ER.svg +1 -0
- package/src/components/flag/flags/ES.svg +1 -0
- package/src/components/flag/flags/ET.svg +1 -0
- package/src/components/flag/flags/FI.svg +1 -0
- package/src/components/flag/flags/FJ.svg +1 -0
- package/src/components/flag/flags/FK.svg +1 -0
- package/src/components/flag/flags/FM.svg +1 -0
- package/src/components/flag/flags/FO.svg +1 -0
- package/src/components/flag/flags/FR.svg +1 -0
- package/src/components/flag/flags/GA.svg +1 -0
- package/src/components/flag/flags/GB.svg +1 -0
- package/src/components/flag/flags/GD.svg +1 -0
- package/src/components/flag/flags/GE.svg +1 -0
- package/src/components/flag/flags/GF.svg +1 -0
- package/src/components/flag/flags/GG.svg +1 -0
- package/src/components/flag/flags/GH.svg +1 -0
- package/src/components/flag/flags/GI.svg +1 -0
- package/src/components/flag/flags/GL.svg +1 -0
- package/src/components/flag/flags/GM.svg +1 -0
- package/src/components/flag/flags/GN.svg +1 -0
- package/src/components/flag/flags/GP.svg +1 -0
- package/src/components/flag/flags/GQ.svg +1 -0
- package/src/components/flag/flags/GR.svg +1 -0
- package/src/components/flag/flags/GS.svg +1 -0
- package/src/components/flag/flags/GT.svg +1 -0
- package/src/components/flag/flags/GU.svg +1 -0
- package/src/components/flag/flags/GW.svg +1 -0
- package/src/components/flag/flags/GY.svg +1 -0
- package/src/components/flag/flags/HK.svg +1 -0
- package/src/components/flag/flags/HM.svg +1 -0
- package/src/components/flag/flags/HN.svg +1 -0
- package/src/components/flag/flags/HR.svg +1 -0
- package/src/components/flag/flags/HT.svg +1 -0
- package/src/components/flag/flags/HU.svg +1 -0
- package/src/components/flag/flags/ID.svg +1 -0
- package/src/components/flag/flags/IE.svg +1 -0
- package/src/components/flag/flags/IL.svg +1 -0
- package/src/components/flag/flags/IM.svg +1 -0
- package/src/components/flag/flags/IN.svg +1 -0
- package/src/components/flag/flags/IO.svg +1 -0
- package/src/components/flag/flags/IQ.svg +1 -0
- package/src/components/flag/flags/IR.svg +1 -0
- package/src/components/flag/flags/IS.svg +1 -0
- package/src/components/flag/flags/IT.svg +1 -0
- package/src/components/flag/flags/JE.svg +1 -0
- package/src/components/flag/flags/JM.svg +1 -0
- package/src/components/flag/flags/JO.svg +1 -0
- package/src/components/flag/flags/JP.svg +1 -0
- package/src/components/flag/flags/KE.svg +1 -0
- package/src/components/flag/flags/KG.svg +1 -0
- package/src/components/flag/flags/KH.svg +1 -0
- package/src/components/flag/flags/KI.svg +1 -0
- package/src/components/flag/flags/KM.svg +1 -0
- package/src/components/flag/flags/KN.svg +1 -0
- package/src/components/flag/flags/KP.svg +1 -0
- package/src/components/flag/flags/KR.svg +1 -0
- package/src/components/flag/flags/KW.svg +1 -0
- package/src/components/flag/flags/KY.svg +1 -0
- package/src/components/flag/flags/KZ.svg +1 -0
- package/src/components/flag/flags/LA.svg +1 -0
- package/src/components/flag/flags/LB.svg +1 -0
- package/src/components/flag/flags/LC.svg +1 -0
- package/src/components/flag/flags/LI.svg +1 -0
- package/src/components/flag/flags/LICENSE +22 -0
- package/src/components/flag/flags/LK.svg +1 -0
- package/src/components/flag/flags/LR.svg +1 -0
- package/src/components/flag/flags/LS.svg +1 -0
- package/src/components/flag/flags/LT.svg +1 -0
- package/src/components/flag/flags/LU.svg +1 -0
- package/src/components/flag/flags/LV.svg +1 -0
- package/src/components/flag/flags/LY.svg +1 -0
- package/src/components/flag/flags/MA.svg +1 -0
- package/src/components/flag/flags/MC.svg +1 -0
- package/src/components/flag/flags/MD.svg +1 -0
- package/src/components/flag/flags/ME.svg +1 -0
- package/src/components/flag/flags/MF.svg +1 -0
- package/src/components/flag/flags/MG.svg +1 -0
- package/src/components/flag/flags/MH.svg +1 -0
- package/src/components/flag/flags/MK.svg +1 -0
- package/src/components/flag/flags/ML.svg +1 -0
- package/src/components/flag/flags/MM.svg +1 -0
- package/src/components/flag/flags/MN.svg +1 -0
- package/src/components/flag/flags/MO.svg +1 -0
- package/src/components/flag/flags/MP.svg +1 -0
- package/src/components/flag/flags/MQ.svg +1 -0
- package/src/components/flag/flags/MR.svg +1 -0
- package/src/components/flag/flags/MS.svg +1 -0
- package/src/components/flag/flags/MT.svg +1 -0
- package/src/components/flag/flags/MU.svg +1 -0
- package/src/components/flag/flags/MV.svg +1 -0
- package/src/components/flag/flags/MW.svg +1 -0
- package/src/components/flag/flags/MX.svg +1 -0
- package/src/components/flag/flags/MY.svg +1 -0
- package/src/components/flag/flags/MZ.svg +1 -0
- package/src/components/flag/flags/NA.svg +1 -0
- package/src/components/flag/flags/NC.svg +1 -0
- package/src/components/flag/flags/NE.svg +1 -0
- package/src/components/flag/flags/NF.svg +1 -0
- package/src/components/flag/flags/NG.svg +1 -0
- package/src/components/flag/flags/NI.svg +1 -0
- package/src/components/flag/flags/NL.svg +1 -0
- package/src/components/flag/flags/NO.svg +1 -0
- package/src/components/flag/flags/NP.svg +1 -0
- package/src/components/flag/flags/NR.svg +1 -0
- package/src/components/flag/flags/NU.svg +1 -0
- package/src/components/flag/flags/NZ.svg +1 -0
- package/src/components/flag/flags/OM.svg +1 -0
- package/src/components/flag/flags/PA.svg +1 -0
- package/src/components/flag/flags/PE.svg +1 -0
- package/src/components/flag/flags/PF.svg +1 -0
- package/src/components/flag/flags/PG.svg +1 -0
- package/src/components/flag/flags/PH.svg +1 -0
- package/src/components/flag/flags/PK.svg +1 -0
- package/src/components/flag/flags/PL.svg +1 -0
- package/src/components/flag/flags/PM.svg +1 -0
- package/src/components/flag/flags/PN.svg +1 -0
- package/src/components/flag/flags/PR.svg +1 -0
- package/src/components/flag/flags/PS.svg +1 -0
- package/src/components/flag/flags/PT.svg +1 -0
- package/src/components/flag/flags/PW.svg +1 -0
- package/src/components/flag/flags/PY.svg +1 -0
- package/src/components/flag/flags/QA.svg +1 -0
- package/src/components/flag/flags/RE.svg +1 -0
- package/src/components/flag/flags/RO.svg +1 -0
- package/src/components/flag/flags/RS.svg +1 -0
- package/src/components/flag/flags/RU.svg +1 -0
- package/src/components/flag/flags/RW.svg +1 -0
- package/src/components/flag/flags/SA.svg +1 -0
- package/src/components/flag/flags/SB.svg +1 -0
- package/src/components/flag/flags/SC.svg +1 -0
- package/src/components/flag/flags/SD.svg +1 -0
- package/src/components/flag/flags/SE.svg +1 -0
- package/src/components/flag/flags/SG.svg +1 -0
- package/src/components/flag/flags/SH.svg +1 -0
- package/src/components/flag/flags/SI.svg +1 -0
- package/src/components/flag/flags/SJ.svg +1 -0
- package/src/components/flag/flags/SK.svg +1 -0
- package/src/components/flag/flags/SL.svg +1 -0
- package/src/components/flag/flags/SM.svg +1 -0
- package/src/components/flag/flags/SN.svg +1 -0
- package/src/components/flag/flags/SO.svg +1 -0
- package/src/components/flag/flags/SR.svg +1 -0
- package/src/components/flag/flags/SS.svg +1 -0
- package/src/components/flag/flags/ST.svg +1 -0
- package/src/components/flag/flags/SV.svg +1 -0
- package/src/components/flag/flags/SX.svg +1 -0
- package/src/components/flag/flags/SY.svg +1 -0
- package/src/components/flag/flags/SZ.svg +1 -0
- package/src/components/flag/flags/TC.svg +1 -0
- package/src/components/flag/flags/TD.svg +1 -0
- package/src/components/flag/flags/TF.svg +1 -0
- package/src/components/flag/flags/TG.svg +1 -0
- package/src/components/flag/flags/TH.svg +1 -0
- package/src/components/flag/flags/TJ.svg +1 -0
- package/src/components/flag/flags/TK.svg +1 -0
- package/src/components/flag/flags/TL.svg +1 -0
- package/src/components/flag/flags/TM.svg +1 -0
- package/src/components/flag/flags/TN.svg +1 -0
- package/src/components/flag/flags/TO.svg +1 -0
- package/src/components/flag/flags/TR.svg +1 -0
- package/src/components/flag/flags/TT.svg +1 -0
- package/src/components/flag/flags/TV.svg +1 -0
- package/src/components/flag/flags/TW.svg +1 -0
- package/src/components/flag/flags/TZ.svg +1 -0
- package/src/components/flag/flags/UA.svg +1 -0
- package/src/components/flag/flags/UG.svg +1 -0
- package/src/components/flag/flags/UM.svg +1 -0
- package/src/components/flag/flags/US.svg +1 -0
- package/src/components/flag/flags/UY.svg +1 -0
- package/src/components/flag/flags/UZ.svg +1 -0
- package/src/components/flag/flags/VA.svg +1 -0
- package/src/components/flag/flags/VC.svg +1 -0
- package/src/components/flag/flags/VE.svg +1 -0
- package/src/components/flag/flags/VG.svg +1 -0
- package/src/components/flag/flags/VI.svg +1 -0
- package/src/components/flag/flags/VN.svg +1 -0
- package/src/components/flag/flags/VU.svg +1 -0
- package/src/components/flag/flags/WF.svg +1 -0
- package/src/components/flag/flags/WS.svg +1 -0
- package/src/components/flag/flags/XK.svg +1 -0
- package/src/components/flag/flags/YE.svg +1 -0
- package/src/components/flag/flags/YT.svg +1 -0
- package/src/components/flag/flags/ZA.svg +1 -0
- package/src/components/flag/flags/ZM.svg +1 -0
- package/src/components/flag/flags/ZW.svg +1 -0
- package/src/components/flag/index.ts +2 -0
- package/src/slides/export/pdf.ts +11 -0
- package/src/vite/flags.test.ts +38 -0
- package/src/vite/flags.ts +63 -0
package/COMPONENTS.md
CHANGED
|
@@ -63,6 +63,7 @@ Generic pieces built on the primitives, imported from `@heyramzi/ui/components/<
|
|
|
63
63
|
|
|
64
64
|
- `copy` — CopyButton, copyText, copyRichText, htmlToPlainText, Copied
|
|
65
65
|
- `data-table` — SortableHead, Pagination, InfiniteScroll, RowContextMenu, TableSkeleton, and the sort, page and filter helpers
|
|
66
|
+
- `flag` — Flag, FLAG_CODES, flagCode: a country flag from an ISO 3166-1 alpha-2 code (plus XK for Kosovo), 1em tall at 3:2, one lazy `<img>` of `/flags/<CODE>.svg` each. Add `flagAssets()` from `@heyramzi/ui/vite` to the app's Vite plugins to serve the 250 SVGs (country-flag-icons, MIT, licence beside them). Decorative unless `label` is set. An unknown code renders nothing; to keep a row's layout, wrap it in `<span class="inline-block aspect-[3/2] h-[1em]">`
|
|
66
67
|
- `hold-to-confirm` — HoldToConfirm, press and hold to confirm
|
|
67
68
|
- `language-flag` — LanguageFlag, LANGUAGE_FLAGS (code to `/flags/*.svg`, also a SegmentedFilter option's `image`)
|
|
68
69
|
- `list-page` — ListPageShell, MasterDetail, GroupedList, RailRow and the rest of the master-detail page kit, DetailPanel, ToolbarSearch, toolbarTriggerClass, NoticeBar, EmptyState, FilterPopover, setSectionHost
|
|
@@ -124,6 +125,7 @@ Named exports from `@heyramzi/ui/effects/<name>`, e.g.
|
|
|
124
125
|
Imported from `@heyramzi/ui/ai/<name>`, e.g. `import { AiButton } from "@heyramzi/ui/ai/ai-button"`.
|
|
125
126
|
|
|
126
127
|
- `ai-button` — AiButton
|
|
128
|
+
- `chat-window` — ChatGptWindow, ClaudeWindow: still or playing pictures of a ChatGPT or Claude conversation for a marketing page, with a connector call row. `messages` takes user text, assistant text or a snippet, and tool steps; every printed string is a prop
|
|
127
129
|
- `confirmation` — Confirmation, ConfirmationTitle, ConfirmationState (`when` names the kind it shows), ConfirmationActions, ConfirmationAction, type ConfirmationKind
|
|
128
130
|
- `generation-progress` — GenerationProgress
|
|
129
131
|
- `loading-state` — PixelLoader
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Each glyph is a file a CSS mask paints in the current colour. Sources and licences: icons/LICENSE.
|
|
2
|
+
import gptChevron from "../../../src/ai/chat-window/icons/chatgpt-chevron.svg";
|
|
3
|
+
import gptCopy from "../../../src/ai/chat-window/icons/chatgpt-copy.svg";
|
|
4
|
+
import gptMic from "../../../src/ai/chat-window/icons/chatgpt-mic.svg";
|
|
5
|
+
import gptMore from "../../../src/ai/chat-window/icons/chatgpt-more.svg";
|
|
6
|
+
import gptPlus from "../../../src/ai/chat-window/icons/chatgpt-plus.svg";
|
|
7
|
+
import gptRegenerate from "../../../src/ai/chat-window/icons/chatgpt-regenerate.svg";
|
|
8
|
+
import gptShare from "../../../src/ai/chat-window/icons/chatgpt-share.svg";
|
|
9
|
+
import gptSidebar from "../../../src/ai/chat-window/icons/chatgpt-sidebar.svg";
|
|
10
|
+
import gptThumb from "../../../src/ai/chat-window/icons/chatgpt-thumb.svg";
|
|
11
|
+
import gptVoice from "../../../src/ai/chat-window/icons/chatgpt-voice.svg";
|
|
12
|
+
import claudeChevron from "../../../src/ai/chat-window/icons/claude-chevron.svg";
|
|
13
|
+
import claudeCopy from "../../../src/ai/chat-window/icons/claude-copy.svg";
|
|
14
|
+
import claudePlus from "../../../src/ai/chat-window/icons/claude-plus.svg";
|
|
15
|
+
import claudeRetry from "../../../src/ai/chat-window/icons/claude-retry.svg";
|
|
16
|
+
import claudeSend from "../../../src/ai/chat-window/icons/claude-send.svg";
|
|
17
|
+
import claudeSidebar from "../../../src/ai/chat-window/icons/claude-sidebar.svg";
|
|
18
|
+
import claudeSliders from "../../../src/ai/chat-window/icons/claude-sliders.svg";
|
|
19
|
+
import claudeSpark from "../../../src/ai/chat-window/icons/claude-spark.svg";
|
|
20
|
+
import claudeThumb from "../../../src/ai/chat-window/icons/claude-thumb.svg";
|
|
21
|
+
export const CHATGPT_ICONS = {
|
|
22
|
+
chevron: gptChevron,
|
|
23
|
+
copy: gptCopy,
|
|
24
|
+
mic: gptMic,
|
|
25
|
+
more: gptMore,
|
|
26
|
+
plus: gptPlus,
|
|
27
|
+
regenerate: gptRegenerate,
|
|
28
|
+
share: gptShare,
|
|
29
|
+
sidebar: gptSidebar,
|
|
30
|
+
thumb: gptThumb,
|
|
31
|
+
voice: gptVoice
|
|
32
|
+
};
|
|
33
|
+
export const CLAUDE_ICONS = {
|
|
34
|
+
chevron: claudeChevron,
|
|
35
|
+
copy: claudeCopy,
|
|
36
|
+
plus: claudePlus,
|
|
37
|
+
retry: claudeRetry,
|
|
38
|
+
send: claudeSend,
|
|
39
|
+
sidebar: claudeSidebar,
|
|
40
|
+
sliders: claudeSliders,
|
|
41
|
+
spark: claudeSpark,
|
|
42
|
+
thumb: claudeThumb
|
|
43
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import ChatGptWindow from "../../../src/ai/chat-window/ChatGptWindow.svelte";
|
|
2
|
+
import ClaudeWindow from "../../../src/ai/chat-window/ClaudeWindow.svelte";
|
|
3
|
+
export { CHATGPT_LABELS, CLAUDE_LABELS } from "./labels.js";
|
|
4
|
+
export { REVEAL_BEATS, revealSchedule } from "./reveal.svelte.js";
|
|
5
|
+
export { ChatGptWindow, ClaudeWindow };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const CHATGPT_LABELS = {
|
|
2
|
+
running: "Calling {name}",
|
|
3
|
+
done: "Used {name}",
|
|
4
|
+
share: "Share",
|
|
5
|
+
disclaimer: "ChatGPT can make mistakes. Check important info.",
|
|
6
|
+
userSaid: "You said:",
|
|
7
|
+
assistantSaid: "ChatGPT said:"
|
|
8
|
+
};
|
|
9
|
+
export const CLAUDE_LABELS = {
|
|
10
|
+
running: "Using {name}",
|
|
11
|
+
done: "Used {name}",
|
|
12
|
+
share: "Share",
|
|
13
|
+
disclaimer: "Claude can make mistakes. Please double-check responses.",
|
|
14
|
+
userSaid: "You said:",
|
|
15
|
+
assistantSaid: "Claude said:"
|
|
16
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { untrack } from "svelte";
|
|
2
|
+
/** Milliseconds each beat holds, read as one conversation's pacing, not a transition. */
|
|
3
|
+
export const REVEAL_BEATS = {
|
|
4
|
+
lead: 400,
|
|
5
|
+
user: 900,
|
|
6
|
+
thinking: 900,
|
|
7
|
+
stream: 1500,
|
|
8
|
+
running: 1300,
|
|
9
|
+
after: 350
|
|
10
|
+
};
|
|
11
|
+
/** The timeline for a conversation: when each message enters and settles, and when it ends. */
|
|
12
|
+
export function revealSchedule(roles, beats = REVEAL_BEATS) {
|
|
13
|
+
const out = [];
|
|
14
|
+
let t = beats.lead;
|
|
15
|
+
roles.forEach((role, index) => {
|
|
16
|
+
if (role === "user") {
|
|
17
|
+
out.push({
|
|
18
|
+
at: t,
|
|
19
|
+
index,
|
|
20
|
+
phase: "done"
|
|
21
|
+
});
|
|
22
|
+
t += beats.user;
|
|
23
|
+
} else if (role === "assistant") {
|
|
24
|
+
out.push({
|
|
25
|
+
at: t,
|
|
26
|
+
index,
|
|
27
|
+
phase: "thinking"
|
|
28
|
+
});
|
|
29
|
+
t += beats.thinking;
|
|
30
|
+
out.push({
|
|
31
|
+
at: t,
|
|
32
|
+
index,
|
|
33
|
+
phase: "streaming"
|
|
34
|
+
});
|
|
35
|
+
t += beats.stream;
|
|
36
|
+
out.push({
|
|
37
|
+
at: t,
|
|
38
|
+
index,
|
|
39
|
+
phase: "done"
|
|
40
|
+
});
|
|
41
|
+
t += beats.after;
|
|
42
|
+
} else {
|
|
43
|
+
out.push({
|
|
44
|
+
at: t,
|
|
45
|
+
index,
|
|
46
|
+
phase: "running"
|
|
47
|
+
});
|
|
48
|
+
t += beats.running;
|
|
49
|
+
out.push({
|
|
50
|
+
at: t,
|
|
51
|
+
index,
|
|
52
|
+
phase: "done"
|
|
53
|
+
});
|
|
54
|
+
t += beats.after;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return {
|
|
58
|
+
beats: out,
|
|
59
|
+
end: t
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Plays a conversation once the window is on screen and `active`, again each time `active` turns on.
|
|
64
|
+
* Renders finished for SSR, no JavaScript and reduced motion.
|
|
65
|
+
*/
|
|
66
|
+
export function createReveal(options) {
|
|
67
|
+
let phases = $state([]);
|
|
68
|
+
let node = $state(null);
|
|
69
|
+
let seen = $state(false);
|
|
70
|
+
$effect(() => {
|
|
71
|
+
const { enabled } = options();
|
|
72
|
+
if (!node || !enabled || seen) return;
|
|
73
|
+
const io = new IntersectionObserver((entries) => {
|
|
74
|
+
if (entries.some((e) => e.isIntersecting)) {
|
|
75
|
+
seen = true;
|
|
76
|
+
io.disconnect();
|
|
77
|
+
}
|
|
78
|
+
}, { threshold: .35 });
|
|
79
|
+
io.observe(node);
|
|
80
|
+
return () => io.disconnect();
|
|
81
|
+
});
|
|
82
|
+
$effect(() => {
|
|
83
|
+
const { enabled, active } = options();
|
|
84
|
+
if (!enabled || !active || !seen) return;
|
|
85
|
+
if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) return;
|
|
86
|
+
const { roles, hold, ondone } = untrack(options);
|
|
87
|
+
const { beats, end } = revealSchedule(roles);
|
|
88
|
+
phases = roles.map(() => "hidden");
|
|
89
|
+
const timers = beats.map((b) => setTimeout(() => phases[b.index] = b.phase, b.at));
|
|
90
|
+
timers.push(setTimeout(() => ondone?.(), end + hold));
|
|
91
|
+
return () => {
|
|
92
|
+
timers.forEach(clearTimeout);
|
|
93
|
+
phases = [];
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
/** A message's phase; `done` when nothing is playing. */
|
|
98
|
+
phase: (index) => phases[index] ?? "done",
|
|
99
|
+
/** Attach to the window's root, so the reveal waits until it scrolls into view. */
|
|
100
|
+
attach: (el) => {
|
|
101
|
+
node = el;
|
|
102
|
+
return () => node = null;
|
|
103
|
+
},
|
|
104
|
+
streamMs: REVEAL_BEATS.stream
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -32,7 +32,7 @@ export function htmlToPlainText(html) {
|
|
|
32
32
|
if (typeof document === "undefined") {
|
|
33
33
|
return html.replace(/<br\s*\/?>/gi, "\n").replace(/<\/p>/gi, "\n\n").replace(/<\/li>/gi, "\n").replace(/<li>/gi, "• ").replace(/<[^>]+>/g, "").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").trim();
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
35
|
+
// A DOMParser document has no browsing context, so nothing in the markup loads or runs.
|
|
36
|
+
// An element from document.createElement belongs to the live page: an <img onerror> fires.
|
|
37
|
+
return new DOMParser().parseFromString(html, "text/html").body.textContent ?? "";
|
|
38
38
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Where the host serves the flag files. `flagAssets()` from `@heyramzi/ui/vite` serves them there. */
|
|
2
|
+
export const FLAG_BASE = "/flags";
|
|
3
|
+
/**
|
|
4
|
+
* The 249 ISO 3166-1 alpha-2 codes plus XK (Kosovo, user-assigned but in common use), each with
|
|
5
|
+
* a file in `./flags`, from country-flag-icons 1.6.20 (MIT).
|
|
6
|
+
*/
|
|
7
|
+
export const FLAG_CODES = ("AD AE AF AG AI AL AM AO AQ AR AS AT AU AW AX AZ BA BB BD BE BF BG BH BI BJ BL BM BN BO BQ BR " + "BS BT BV BW BY BZ CA CC CD CF CG CH CI CK CL CM CN CO CR CU CV CW CX CY CZ DE DJ DK DM DO DZ " + "EC EE EG EH ER ES ET FI FJ FK FM FO FR GA GB GD GE GF GG GH GI GL GM GN GP GQ GR GS GT GU GW " + "GY HK HM HN HR HT HU ID IE IL IM IN IO IQ IR IS IT JE JM JO JP KE KG KH KI KM KN KP KR KW KY " + "KZ LA LB LC LI LK LR LS LT LU LV LY MA MC MD ME MF MG MH MK ML MM MN MO MP MQ MR MS MT MU MV " + "MW MX MY MZ NA NC NE NF NG NI NL NO NP NR NU NZ OM PA PE PF PG PH PK PL PM PN PR PS PT PW PY " + "QA RE RO RS RU RW SA SB SC SD SE SG SH SI SJ SK SL SM SN SO SR SS ST SV SX SY SZ TC TD TF TG " + "TH TJ TK TL TM TN TO TR TT TV TW TZ UA UG UM US UY UZ VA VC VE VG VI VN VU WF WS XK YE YT ZA ZM ZW").split(" ");
|
|
8
|
+
const KNOWN = new Set(FLAG_CODES);
|
|
9
|
+
/** The code in capitals when a flag exists for it, else null. */
|
|
10
|
+
export function flagCode(code) {
|
|
11
|
+
const upper = code?.trim().toUpperCase() ?? "";
|
|
12
|
+
return KNOWN.has(upper) ? upper : null;
|
|
13
|
+
}
|
|
@@ -38,6 +38,13 @@ export async function printPage(page, options = {}) {
|
|
|
38
38
|
}
|
|
39
39
|
await page.evaluate(() => document.fonts.ready.then(() => undefined));
|
|
40
40
|
if (options.settle) await page.waitForTimeout(options.settle);
|
|
41
|
+
// WHY: a lazy or still-loading image read as broken while the PDF printed it (testimonial photos, 11 Nov 2026).
|
|
42
|
+
await page.evaluate(() => Promise.all([...document.images].map((img) => {
|
|
43
|
+
img.loading = "eager";
|
|
44
|
+
if (img.complete) return undefined;
|
|
45
|
+
const loaded = img.decode().catch(() => undefined);
|
|
46
|
+
return Promise.race([loaded, new Promise((resolve) => setTimeout(resolve, 15e3))]);
|
|
47
|
+
})).then(() => undefined));
|
|
41
48
|
const brokenImages = await page.evaluate(() => [...document.images].filter((img) => !img.complete || img.naturalWidth === 0).map((img) => img.src));
|
|
42
49
|
const { size } = options;
|
|
43
50
|
const pdf = await page.pdf({
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
// From src/vite in the repo, or dist/vite in the published package.
|
|
5
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const FLAGS_DIR = [join(here, "../components/flag/flags"), join(here, "../../src/components/flag/flags")].find((dir) => existsSync(dir));
|
|
7
|
+
/**
|
|
8
|
+
* Serves the `Flag` SVGs at `/flags/<CODE>.svg`: from the package in dev and preview, and as
|
|
9
|
+
* one static file each in the client build. Add it to `plugins` in `vite.config.ts`.
|
|
10
|
+
*/
|
|
11
|
+
export function flagAssets(options = {}) {
|
|
12
|
+
const base = (options.base ?? "/flags").replace(/\/$/, "");
|
|
13
|
+
if (!FLAGS_DIR) throw new Error("@heyramzi/ui: the flag SVGs are missing from the package");
|
|
14
|
+
const dir = FLAGS_DIR;
|
|
15
|
+
const files = readdirSync(dir).filter((name) => /^[A-Z]{2}\.svg$/.test(name));
|
|
16
|
+
const known = new Set(files);
|
|
17
|
+
let ssrBuild = false;
|
|
18
|
+
// Returns nothing: Vite calls a function returned from configureServer as a post hook.
|
|
19
|
+
const serve = (server) => {
|
|
20
|
+
server.middlewares.use((req, res, next) => {
|
|
21
|
+
const path = req.url?.split("?")[0] ?? "";
|
|
22
|
+
const name = path.startsWith(`${base}/`) ? path.slice(base.length + 1) : "";
|
|
23
|
+
if (!known.has(name)) return next();
|
|
24
|
+
res.setHeader("Content-Type", "image/svg+xml");
|
|
25
|
+
res.setHeader("Cache-Control", "public, max-age=86400");
|
|
26
|
+
res.end(readFileSync(join(dir, name)));
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
return {
|
|
30
|
+
name: "heyramzi-ui:flags",
|
|
31
|
+
configResolved(config) {
|
|
32
|
+
ssrBuild = Boolean(config.build.ssr);
|
|
33
|
+
},
|
|
34
|
+
configureServer: serve,
|
|
35
|
+
configurePreviewServer: serve,
|
|
36
|
+
generateBundle() {
|
|
37
|
+
const consumer = this.environment?.config?.consumer;
|
|
38
|
+
if (consumer ? consumer !== "client" : ssrBuild) return;
|
|
39
|
+
for (const name of files) this.emitFile({
|
|
40
|
+
type: "asset",
|
|
41
|
+
fileName: `${base.replace(/^\//, "")}/${name}`,
|
|
42
|
+
source: readFileSync(join(dir, name))
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heyramzi/ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0",
|
|
4
4
|
"description": "Svelte 5 UI for apps: primitives, effects and animations, plus work (tasks and docs), charts, slides, an editor, onboarding and a canvas as subpaths.",
|
|
5
5
|
"homepage": "https://ui.heyramzi.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -115,6 +115,11 @@
|
|
|
115
115
|
"node": "./dist/effects/magnetic/magnetic.js",
|
|
116
116
|
"default": "./src/effects/magnetic/magnetic.ts"
|
|
117
117
|
},
|
|
118
|
+
"./vite": {
|
|
119
|
+
"types": "./src/vite/flags.ts",
|
|
120
|
+
"node": "./dist/vite/flags.js",
|
|
121
|
+
"default": "./src/vite/flags.ts"
|
|
122
|
+
},
|
|
118
123
|
"./icons/sf-symbols": {
|
|
119
124
|
"svelte": "./src/icons/sf-symbols.ts",
|
|
120
125
|
"types": "./src/icons/sf-symbols.ts",
|
|
@@ -389,6 +394,6 @@
|
|
|
389
394
|
"sync": "pnpm sync:transitions && pnpm sync:shadcn",
|
|
390
395
|
"sync:check": "node scripts/sync-transitions.mjs --check && node scripts/sync-shadcn.mjs --check",
|
|
391
396
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
392
|
-
"build": "node ../../../
|
|
397
|
+
"build": "node ../../../upsys/kit/scripts/build-dist.mjs"
|
|
393
398
|
}
|
|
394
399
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
// =========================
|
|
3
|
+
// PROPS
|
|
4
|
+
// =========================
|
|
5
|
+
interface Props {
|
|
6
|
+
/** The SVG file's URL, painted through a mask in the current colour. */
|
|
7
|
+
src: string;
|
|
8
|
+
size?: number;
|
|
9
|
+
class?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { src, size = 20, class: className = "" }: Props = $props();
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<!-- =========================== -->
|
|
16
|
+
<!-- MARKUP -->
|
|
17
|
+
<!-- =========================== -->
|
|
18
|
+
<span
|
|
19
|
+
class="chat-glyph {className}"
|
|
20
|
+
style:--glyph={`url("${src}")`}
|
|
21
|
+
style:--size="{size}px"
|
|
22
|
+
aria-hidden="true"
|
|
23
|
+
></span>
|
|
24
|
+
|
|
25
|
+
<style>
|
|
26
|
+
@layer theme, base, components, utilities;
|
|
27
|
+
|
|
28
|
+
@layer components {
|
|
29
|
+
.chat-glyph {
|
|
30
|
+
display: block;
|
|
31
|
+
flex: none;
|
|
32
|
+
width: var(--size);
|
|
33
|
+
height: var(--size);
|
|
34
|
+
background: currentColor;
|
|
35
|
+
mask: var(--glyph) center / contain no-repeat;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
</style>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
/** The SVG file's URL, painted through a mask in the current colour. */
|
|
3
|
+
src: string;
|
|
4
|
+
size?: number;
|
|
5
|
+
class?: string;
|
|
6
|
+
}
|
|
7
|
+
declare const $$Component: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type $$Component = ReturnType<typeof $$Component>;
|
|
9
|
+
export default $$Component;
|