@wallarm-org/claude-design 0.0.0-stage → 4.8.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.
Files changed (963) hide show
  1. package/README.md +114 -2
  2. package/bin/claude-design.js +347 -0
  3. package/dist/SETUP.md +130 -0
  4. package/dist/UPDATE.md +84 -0
  5. package/dist/assets/Icons/activity.svg +1 -0
  6. package/dist/assets/Icons/alt.svg +1 -0
  7. package/dist/assets/Icons/android-neutral.svg +1 -0
  8. package/dist/assets/Icons/android.svg +1 -0
  9. package/dist/assets/Icons/api.svg +1 -0
  10. package/dist/assets/Icons/apple-music-neutral.svg +1 -0
  11. package/dist/assets/Icons/apple-music.svg +1 -0
  12. package/dist/assets/Icons/apple-neutral.svg +1 -0
  13. package/dist/assets/Icons/apple-podcasts-neutral.svg +1 -0
  14. package/dist/assets/Icons/apple-podcasts.svg +1 -0
  15. package/dist/assets/Icons/apple.svg +1 -0
  16. package/dist/assets/Icons/archive.svg +1 -0
  17. package/dist/assets/Icons/arrow-big-up-dash.svg +1 -0
  18. package/dist/assets/Icons/arrow-big-up.svg +1 -0
  19. package/dist/assets/Icons/arrow-down-left.svg +1 -0
  20. package/dist/assets/Icons/arrow-down-right.svg +1 -0
  21. package/dist/assets/Icons/arrow-down.svg +1 -0
  22. package/dist/assets/Icons/arrow-left.svg +1 -0
  23. package/dist/assets/Icons/arrow-right-alt.svg +1 -0
  24. package/dist/assets/Icons/arrow-right.svg +1 -0
  25. package/dist/assets/Icons/arrow-up-down.svg +1 -0
  26. package/dist/assets/Icons/arrow-up-left.svg +1 -0
  27. package/dist/assets/Icons/arrow-up-right.svg +1 -0
  28. package/dist/assets/Icons/arrow-up.svg +1 -0
  29. package/dist/assets/Icons/artstation-neutral.svg +1 -0
  30. package/dist/assets/Icons/artstation.svg +1 -0
  31. package/dist/assets/Icons/asterisk.svg +1 -0
  32. package/dist/assets/Icons/audio-waveform.svg +1 -0
  33. package/dist/assets/Icons/aws-neutral.svg +1 -0
  34. package/dist/assets/Icons/aws.svg +1 -0
  35. package/dist/assets/Icons/badge-check.svg +1 -0
  36. package/dist/assets/Icons/baidu-neutral.svg +1 -0
  37. package/dist/assets/Icons/baidu.svg +1 -0
  38. package/dist/assets/Icons/bandage.svg +1 -0
  39. package/dist/assets/Icons/behance-neutral.svg +1 -0
  40. package/dist/assets/Icons/behance.svg +1 -0
  41. package/dist/assets/Icons/bell-cog.svg +1 -0
  42. package/dist/assets/Icons/bell.svg +1 -0
  43. package/dist/assets/Icons/binary.svg +1 -0
  44. package/dist/assets/Icons/book-open.svg +1 -0
  45. package/dist/assets/Icons/book.svg +1 -0
  46. package/dist/assets/Icons/boosty-neutral.svg +1 -0
  47. package/dist/assets/Icons/boosty.svg +1 -0
  48. package/dist/assets/Icons/bot.svg +1 -0
  49. package/dist/assets/Icons/brain.svg +1 -0
  50. package/dist/assets/Icons/braze-neutral.svg +1 -0
  51. package/dist/assets/Icons/braze.svg +1 -0
  52. package/dist/assets/Icons/brevo-neutral.svg +1 -0
  53. package/dist/assets/Icons/brevo.svg +1 -0
  54. package/dist/assets/Icons/bug-off.svg +1 -0
  55. package/dist/assets/Icons/bug-play.svg +1 -0
  56. package/dist/assets/Icons/bug.svg +1 -0
  57. package/dist/assets/Icons/building.svg +1 -0
  58. package/dist/assets/Icons/building2.svg +1 -0
  59. package/dist/assets/Icons/calendar-check.svg +1 -0
  60. package/dist/assets/Icons/calendar-check2.svg +1 -0
  61. package/dist/assets/Icons/calendar-clock.svg +1 -0
  62. package/dist/assets/Icons/calendar-cog.svg +1 -0
  63. package/dist/assets/Icons/calendar-days.svg +1 -0
  64. package/dist/assets/Icons/calendar-fold.svg +1 -0
  65. package/dist/assets/Icons/calendar-heart.svg +1 -0
  66. package/dist/assets/Icons/calendar-minus.svg +1 -0
  67. package/dist/assets/Icons/calendar-minus2.svg +1 -0
  68. package/dist/assets/Icons/calendar-off.svg +1 -0
  69. package/dist/assets/Icons/calendar-plus.svg +1 -0
  70. package/dist/assets/Icons/calendar-plus2.svg +1 -0
  71. package/dist/assets/Icons/calendar-range.svg +1 -0
  72. package/dist/assets/Icons/calendar-search.svg +1 -0
  73. package/dist/assets/Icons/calendar-x.svg +1 -0
  74. package/dist/assets/Icons/calendar-x2.svg +1 -0
  75. package/dist/assets/Icons/calendar.svg +1 -0
  76. package/dist/assets/Icons/chart-area.svg +1 -0
  77. package/dist/assets/Icons/chart-bar.svg +1 -0
  78. package/dist/assets/Icons/chart-column.svg +1 -0
  79. package/dist/assets/Icons/chart-no-axes-column.svg +1 -0
  80. package/dist/assets/Icons/check-check.svg +1 -0
  81. package/dist/assets/Icons/check.svg +1 -0
  82. package/dist/assets/Icons/checkbox-indeterminate.svg +1 -0
  83. package/dist/assets/Icons/chevron-down.svg +1 -0
  84. package/dist/assets/Icons/chevron-first.svg +1 -0
  85. package/dist/assets/Icons/chevron-last.svg +1 -0
  86. package/dist/assets/Icons/chevron-left.svg +1 -0
  87. package/dist/assets/Icons/chevron-right.svg +1 -0
  88. package/dist/assets/Icons/chevron-up-down.svg +1 -0
  89. package/dist/assets/Icons/chevron-up.svg +1 -0
  90. package/dist/assets/Icons/chevrons-down-up.svg +1 -0
  91. package/dist/assets/Icons/chevrons-down.svg +1 -0
  92. package/dist/assets/Icons/chevrons-left-right.svg +1 -0
  93. package/dist/assets/Icons/chevrons-left.svg +1 -0
  94. package/dist/assets/Icons/chevrons-right-left.svg +1 -0
  95. package/dist/assets/Icons/chevrons-right.svg +1 -0
  96. package/dist/assets/Icons/chevrons-up-down.svg +1 -0
  97. package/dist/assets/Icons/chevrons-up.svg +1 -0
  98. package/dist/assets/Icons/circle-arrow-down.svg +1 -0
  99. package/dist/assets/Icons/circle-arrow-left.svg +1 -0
  100. package/dist/assets/Icons/circle-arrow-out-down-left.svg +1 -0
  101. package/dist/assets/Icons/circle-arrow-out-down-right.svg +1 -0
  102. package/dist/assets/Icons/circle-arrow-out-up-left.svg +1 -0
  103. package/dist/assets/Icons/circle-arrow-out-up-right.svg +1 -0
  104. package/dist/assets/Icons/circle-arrow-right.svg +1 -0
  105. package/dist/assets/Icons/circle-arrow-up.svg +1 -0
  106. package/dist/assets/Icons/circle-check-big.svg +1 -0
  107. package/dist/assets/Icons/circle-check.svg +1 -0
  108. package/dist/assets/Icons/circle-chevron-down.svg +1 -0
  109. package/dist/assets/Icons/circle-chevron-left.svg +1 -0
  110. package/dist/assets/Icons/circle-chevron-right.svg +1 -0
  111. package/dist/assets/Icons/circle-chevron-up.svg +1 -0
  112. package/dist/assets/Icons/circle-dashed.svg +1 -0
  113. package/dist/assets/Icons/circle-dot-dashed.svg +1 -0
  114. package/dist/assets/Icons/circle-ellipsis.svg +1 -0
  115. package/dist/assets/Icons/circle-gauge.svg +1 -0
  116. package/dist/assets/Icons/circle-help.svg +1 -0
  117. package/dist/assets/Icons/circle-minus.svg +1 -0
  118. package/dist/assets/Icons/circle-plus.svg +1 -0
  119. package/dist/assets/Icons/circle-slash.svg +1 -0
  120. package/dist/assets/Icons/circle-slash2.svg +1 -0
  121. package/dist/assets/Icons/circle-stop.svg +1 -0
  122. package/dist/assets/Icons/circle.svg +1 -0
  123. package/dist/assets/Icons/clipboard-check.svg +1 -0
  124. package/dist/assets/Icons/clipboard-x.svg +1 -0
  125. package/dist/assets/Icons/clipboard.svg +1 -0
  126. package/dist/assets/Icons/clock-fading.svg +1 -0
  127. package/dist/assets/Icons/clock.svg +1 -0
  128. package/dist/assets/Icons/cloud-off.svg +1 -0
  129. package/dist/assets/Icons/cloud-sync.svg +1 -0
  130. package/dist/assets/Icons/cloud.svg +1 -0
  131. package/dist/assets/Icons/code.svg +1 -0
  132. package/dist/assets/Icons/collapse.svg +1 -0
  133. package/dist/assets/Icons/columns3-cog.svg +1 -0
  134. package/dist/assets/Icons/command.svg +1 -0
  135. package/dist/assets/Icons/compass.svg +1 -0
  136. package/dist/assets/Icons/copy-slash.svg +1 -0
  137. package/dist/assets/Icons/copy.svg +1 -0
  138. package/dist/assets/Icons/corner-down-left.svg +1 -0
  139. package/dist/assets/Icons/corner-down-right.svg +1 -0
  140. package/dist/assets/Icons/corner-left-down.svg +1 -0
  141. package/dist/assets/Icons/corner-left-up.svg +1 -0
  142. package/dist/assets/Icons/corner-right-down.svg +1 -0
  143. package/dist/assets/Icons/corner-right-up.svg +1 -0
  144. package/dist/assets/Icons/corner-up-left.svg +1 -0
  145. package/dist/assets/Icons/corner-up-right.svg +1 -0
  146. package/dist/assets/Icons/cpu.svg +1 -0
  147. package/dist/assets/Icons/credit-card.svg +1 -0
  148. package/dist/assets/Icons/crosshair.svg +1 -0
  149. package/dist/assets/Icons/ctrl.svg +1 -0
  150. package/dist/assets/Icons/database.svg +1 -0
  151. package/dist/assets/Icons/devianart-neutral.svg +1 -0
  152. package/dist/assets/Icons/devianart.svg +1 -0
  153. package/dist/assets/Icons/discord-neutral.svg +1 -0
  154. package/dist/assets/Icons/discord.svg +1 -0
  155. package/dist/assets/Icons/dollar-sign.svg +1 -0
  156. package/dist/assets/Icons/dot.svg +1 -0
  157. package/dist/assets/Icons/download.svg +1 -0
  158. package/dist/assets/Icons/dprofile-neutral.svg +1 -0
  159. package/dist/assets/Icons/dprofile.svg +1 -0
  160. package/dist/assets/Icons/dribbble-neutral.svg +1 -0
  161. package/dist/assets/Icons/dribbble.svg +1 -0
  162. package/dist/assets/Icons/droplet.svg +1 -0
  163. package/dist/assets/Icons/duplicate.svg +1 -0
  164. package/dist/assets/Icons/dzen-neutral.svg +1 -0
  165. package/dist/assets/Icons/dzen.svg +1 -0
  166. package/dist/assets/Icons/earth-lock.svg +1 -0
  167. package/dist/assets/Icons/earth.svg +1 -0
  168. package/dist/assets/Icons/ellipsis.svg +1 -0
  169. package/dist/assets/Icons/expand.svg +1 -0
  170. package/dist/assets/Icons/external-link.svg +1 -0
  171. package/dist/assets/Icons/eye-off.svg +1 -0
  172. package/dist/assets/Icons/eye.svg +1 -0
  173. package/dist/assets/Icons/facebook-neutral.svg +1 -0
  174. package/dist/assets/Icons/facebook.svg +1 -0
  175. package/dist/assets/Icons/fast-forward.svg +1 -0
  176. package/dist/assets/Icons/figma-neutral.svg +1 -0
  177. package/dist/assets/Icons/figma.svg +1 -0
  178. package/dist/assets/Icons/file-down.svg +1 -0
  179. package/dist/assets/Icons/file-plus.svg +1 -0
  180. package/dist/assets/Icons/file-text.svg +1 -0
  181. package/dist/assets/Icons/file.svg +1 -0
  182. package/dist/assets/Icons/film.svg +1 -0
  183. package/dist/assets/Icons/filter-x.svg +1 -0
  184. package/dist/assets/Icons/filter.svg +1 -0
  185. package/dist/assets/Icons/fingerprint-pattern.svg +1 -0
  186. package/dist/assets/Icons/flag.svg +1 -0
  187. package/dist/assets/Icons/flask-conical.svg +1 -0
  188. package/dist/assets/Icons/folder.svg +1 -0
  189. package/dist/assets/Icons/funnel-plus.svg +1 -0
  190. package/dist/assets/Icons/ghost.svg +1 -0
  191. package/dist/assets/Icons/git-branch.svg +1 -0
  192. package/dist/assets/Icons/git-commit-horizontal.svg +1 -0
  193. package/dist/assets/Icons/git-commit-vertical.svg +1 -0
  194. package/dist/assets/Icons/git-compare-arrows-alt.svg +1 -0
  195. package/dist/assets/Icons/git-compare-arrows.svg +1 -0
  196. package/dist/assets/Icons/git-compare.svg +1 -0
  197. package/dist/assets/Icons/git-fork.svg +1 -0
  198. package/dist/assets/Icons/git-graph.svg +1 -0
  199. package/dist/assets/Icons/git-merge.svg +1 -0
  200. package/dist/assets/Icons/git-pull-request-arrow.svg +1 -0
  201. package/dist/assets/Icons/git-pull-request-closed.svg +1 -0
  202. package/dist/assets/Icons/git-pull-request-create-arrow.svg +1 -0
  203. package/dist/assets/Icons/git-pull-request-create.svg +1 -0
  204. package/dist/assets/Icons/git-pull-request-draft.svg +1 -0
  205. package/dist/assets/Icons/git-pull-request.svg +1 -0
  206. package/dist/assets/Icons/github-neutral.svg +1 -0
  207. package/dist/assets/Icons/github.svg +1 -0
  208. package/dist/assets/Icons/globe-lock.svg +1 -0
  209. package/dist/assets/Icons/globe.svg +1 -0
  210. package/dist/assets/Icons/gmail-neutral.svg +1 -0
  211. package/dist/assets/Icons/gmail.svg +1 -0
  212. package/dist/assets/Icons/google-meet-neutral.svg +1 -0
  213. package/dist/assets/Icons/google-meet.svg +1 -0
  214. package/dist/assets/Icons/google-neutral.svg +1 -0
  215. package/dist/assets/Icons/google-play-neutral.svg +1 -0
  216. package/dist/assets/Icons/google-play.svg +1 -0
  217. package/dist/assets/Icons/google-podcast-neutral.svg +1 -0
  218. package/dist/assets/Icons/google-podcast.svg +1 -0
  219. package/dist/assets/Icons/google.svg +1 -0
  220. package/dist/assets/Icons/grip-horizontal.svg +1 -0
  221. package/dist/assets/Icons/grip-vertical.svg +1 -0
  222. package/dist/assets/Icons/hammer.svg +1 -0
  223. package/dist/assets/Icons/heart-pulse.svg +1 -0
  224. package/dist/assets/Icons/history.svg +1 -0
  225. package/dist/assets/Icons/home.svg +1 -0
  226. package/dist/assets/Icons/imo-neutral.svg +1 -0
  227. package/dist/assets/Icons/imo.svg +1 -0
  228. package/dist/assets/Icons/infinity.svg +1 -0
  229. package/dist/assets/Icons/info.svg +1 -0
  230. package/dist/assets/Icons/infobip-neutral.svg +1 -0
  231. package/dist/assets/Icons/infobip.svg +1 -0
  232. package/dist/assets/Icons/instagram-neutral.svg +1 -0
  233. package/dist/assets/Icons/instagram.svg +1 -0
  234. package/dist/assets/Icons/key-round.svg +1 -0
  235. package/dist/assets/Icons/key-square.svg +1 -0
  236. package/dist/assets/Icons/keyboard.svg +1 -0
  237. package/dist/assets/Icons/kickstarter-neutral.svg +1 -0
  238. package/dist/assets/Icons/kickstarter.svg +1 -0
  239. package/dist/assets/Icons/laptop.svg +1 -0
  240. package/dist/assets/Icons/layers.svg +1 -0
  241. package/dist/assets/Icons/layers2.svg +1 -0
  242. package/dist/assets/Icons/layers3.svg +1 -0
  243. package/dist/assets/Icons/layout-dashboard.svg +1 -0
  244. package/dist/assets/Icons/layout-grid.svg +1 -0
  245. package/dist/assets/Icons/layout-list.svg +1 -0
  246. package/dist/assets/Icons/layout-panel-left.svg +1 -0
  247. package/dist/assets/Icons/layout-panel-top.svg +1 -0
  248. package/dist/assets/Icons/layout-template.svg +1 -0
  249. package/dist/assets/Icons/library-big.svg +1 -0
  250. package/dist/assets/Icons/life-buoy.svg +1 -0
  251. package/dist/assets/Icons/lightbulb-off.svg +1 -0
  252. package/dist/assets/Icons/lightbulb.svg +1 -0
  253. package/dist/assets/Icons/line-neutral.svg +1 -0
  254. package/dist/assets/Icons/line.svg +1 -0
  255. package/dist/assets/Icons/link.svg +1 -0
  256. package/dist/assets/Icons/link2-off.svg +1 -0
  257. package/dist/assets/Icons/link2.svg +1 -0
  258. package/dist/assets/Icons/linkedin-neutral.svg +1 -0
  259. package/dist/assets/Icons/linkedin.svg +1 -0
  260. package/dist/assets/Icons/list-checks.svg +1 -0
  261. package/dist/assets/Icons/list-collapse.svg +1 -0
  262. package/dist/assets/Icons/list-filter.svg +1 -0
  263. package/dist/assets/Icons/list-minus.svg +1 -0
  264. package/dist/assets/Icons/list-ordered.svg +1 -0
  265. package/dist/assets/Icons/list-plus.svg +1 -0
  266. package/dist/assets/Icons/list-restart.svg +1 -0
  267. package/dist/assets/Icons/list-start.svg +1 -0
  268. package/dist/assets/Icons/list-todo.svg +1 -0
  269. package/dist/assets/Icons/list-tree.svg +1 -0
  270. package/dist/assets/Icons/list-video.svg +1 -0
  271. package/dist/assets/Icons/list-x.svg +1 -0
  272. package/dist/assets/Icons/list.svg +1 -0
  273. package/dist/assets/Icons/loader-circle.svg +1 -0
  274. package/dist/assets/Icons/loader.svg +1 -0
  275. package/dist/assets/Icons/lock-open.svg +1 -0
  276. package/dist/assets/Icons/lock.svg +1 -0
  277. package/dist/assets/Icons/log-in.svg +1 -0
  278. package/dist/assets/Icons/log-out.svg +1 -0
  279. package/dist/assets/Icons/mail-check.svg +1 -0
  280. package/dist/assets/Icons/mail-minus.svg +1 -0
  281. package/dist/assets/Icons/mail-open.svg +1 -0
  282. package/dist/assets/Icons/mail-plus.svg +1 -0
  283. package/dist/assets/Icons/mail-question.svg +1 -0
  284. package/dist/assets/Icons/mail-search.svg +1 -0
  285. package/dist/assets/Icons/mail-warning.svg +1 -0
  286. package/dist/assets/Icons/mail-x.svg +1 -0
  287. package/dist/assets/Icons/mail.svg +1 -0
  288. package/dist/assets/Icons/mailbox.svg +1 -0
  289. package/dist/assets/Icons/mailersend-neutral.svg +1 -0
  290. package/dist/assets/Icons/mailersend.svg +1 -0
  291. package/dist/assets/Icons/mailgun-neutral.svg +1 -0
  292. package/dist/assets/Icons/mailgun.svg +1 -0
  293. package/dist/assets/Icons/mailjet-neutral.svg +1 -0
  294. package/dist/assets/Icons/mailjet.svg +1 -0
  295. package/dist/assets/Icons/mails.svg +1 -0
  296. package/dist/assets/Icons/mailtrap-neutral.svg +1 -0
  297. package/dist/assets/Icons/mailtrap.svg +1 -0
  298. package/dist/assets/Icons/mandrill-neutral.svg +1 -0
  299. package/dist/assets/Icons/mandrill.svg +1 -0
  300. package/dist/assets/Icons/map-pin.svg +1 -0
  301. package/dist/assets/Icons/maqsam-neutral.svg +1 -0
  302. package/dist/assets/Icons/maqsam.svg +1 -0
  303. package/dist/assets/Icons/mattermost-neutral.svg +1 -0
  304. package/dist/assets/Icons/mattermost.svg +1 -0
  305. package/dist/assets/Icons/maximize.svg +1 -0
  306. package/dist/assets/Icons/maximize2.svg +1 -0
  307. package/dist/assets/Icons/medium-neutral.svg +1 -0
  308. package/dist/assets/Icons/medium.svg +1 -0
  309. package/dist/assets/Icons/megaphone-off.svg +1 -0
  310. package/dist/assets/Icons/megaphone.svg +1 -0
  311. package/dist/assets/Icons/menu.svg +1 -0
  312. package/dist/assets/Icons/merge.svg +1 -0
  313. package/dist/assets/Icons/message-square-code.svg +1 -0
  314. package/dist/assets/Icons/message-square-dashed.svg +1 -0
  315. package/dist/assets/Icons/message-square-diff.svg +1 -0
  316. package/dist/assets/Icons/message-square-dot.svg +1 -0
  317. package/dist/assets/Icons/message-square-heart.svg +1 -0
  318. package/dist/assets/Icons/message-square-off.svg +1 -0
  319. package/dist/assets/Icons/message-square-plus.svg +1 -0
  320. package/dist/assets/Icons/message-square-quote.svg +1 -0
  321. package/dist/assets/Icons/message-square-reply.svg +1 -0
  322. package/dist/assets/Icons/message-square-share.svg +1 -0
  323. package/dist/assets/Icons/message-square-text.svg +1 -0
  324. package/dist/assets/Icons/message-square-warning.svg +1 -0
  325. package/dist/assets/Icons/message-square-x.svg +1 -0
  326. package/dist/assets/Icons/message-square.svg +1 -0
  327. package/dist/assets/Icons/messages-square.svg +1 -0
  328. package/dist/assets/Icons/messenger-neutral.svg +1 -0
  329. package/dist/assets/Icons/messenger.svg +1 -0
  330. package/dist/assets/Icons/microsoft-neutral.svg +1 -0
  331. package/dist/assets/Icons/microsoft-teams-neutral.svg +1 -0
  332. package/dist/assets/Icons/microsoft-teams.svg +1 -0
  333. package/dist/assets/Icons/microsoft.svg +1 -0
  334. package/dist/assets/Icons/minimize.svg +1 -0
  335. package/dist/assets/Icons/minimize2.svg +1 -0
  336. package/dist/assets/Icons/minus.svg +1 -0
  337. package/dist/assets/Icons/moon.svg +1 -0
  338. package/dist/assets/Icons/mouse-pointer-ban.svg +1 -0
  339. package/dist/assets/Icons/mouse-pointer-click.svg +1 -0
  340. package/dist/assets/Icons/mouse-pointer.svg +1 -0
  341. package/dist/assets/Icons/mouse-pointer2.svg +1 -0
  342. package/dist/assets/Icons/mouse.svg +1 -0
  343. package/dist/assets/Icons/move-diagonal.svg +1 -0
  344. package/dist/assets/Icons/move-diagonal2.svg +1 -0
  345. package/dist/assets/Icons/move-down-left.svg +1 -0
  346. package/dist/assets/Icons/move-down-right.svg +1 -0
  347. package/dist/assets/Icons/move-down.svg +1 -0
  348. package/dist/assets/Icons/move-horizontal.svg +1 -0
  349. package/dist/assets/Icons/move-left.svg +1 -0
  350. package/dist/assets/Icons/move-right.svg +1 -0
  351. package/dist/assets/Icons/move-up-left.svg +1 -0
  352. package/dist/assets/Icons/move-up-right.svg +1 -0
  353. package/dist/assets/Icons/move-up.svg +1 -0
  354. package/dist/assets/Icons/move-vertical.svg +1 -0
  355. package/dist/assets/Icons/move3-d.svg +1 -0
  356. package/dist/assets/Icons/netcore-neutral.svg +1 -0
  357. package/dist/assets/Icons/netcore.svg +1 -0
  358. package/dist/assets/Icons/notebook-pen.svg +1 -0
  359. package/dist/assets/Icons/notebook-tabs.svg +1 -0
  360. package/dist/assets/Icons/notebook-text.svg +1 -0
  361. package/dist/assets/Icons/notebook.svg +1 -0
  362. package/dist/assets/Icons/notepad-text-dashed.svg +1 -0
  363. package/dist/assets/Icons/notepad-text.svg +1 -0
  364. package/dist/assets/Icons/notion-neutral.svg +1 -0
  365. package/dist/assets/Icons/notion.svg +1 -0
  366. package/dist/assets/Icons/octagon-alert.svg +1 -0
  367. package/dist/assets/Icons/octagon-pause.svg +1 -0
  368. package/dist/assets/Icons/octagon-x.svg +1 -0
  369. package/dist/assets/Icons/octagon.svg +1 -0
  370. package/dist/assets/Icons/ok-neutral.svg +1 -0
  371. package/dist/assets/Icons/ok-only-sign-neutral.svg +1 -0
  372. package/dist/assets/Icons/ok-only-sign.svg +1 -0
  373. package/dist/assets/Icons/ok.svg +1 -0
  374. package/dist/assets/Icons/onlyfans-neutral.svg +1 -0
  375. package/dist/assets/Icons/onlyfans.svg +1 -0
  376. package/dist/assets/Icons/option.svg +1 -0
  377. package/dist/assets/Icons/outlook365-neutral.svg +1 -0
  378. package/dist/assets/Icons/outlook365.svg +1 -0
  379. package/dist/assets/Icons/paintbrush.svg +1 -0
  380. package/dist/assets/Icons/panel-bottom-open.svg +1 -0
  381. package/dist/assets/Icons/panel-bottom.svg +1 -0
  382. package/dist/assets/Icons/panel-left-close.svg +1 -0
  383. package/dist/assets/Icons/panel-left-dashed.svg +1 -0
  384. package/dist/assets/Icons/panel-left-open.svg +1 -0
  385. package/dist/assets/Icons/panel-left.svg +1 -0
  386. package/dist/assets/Icons/panel-right-animated.svg +1 -0
  387. package/dist/assets/Icons/panel-right-close.svg +1 -0
  388. package/dist/assets/Icons/panel-right-dashed.svg +1 -0
  389. package/dist/assets/Icons/panel-right-open.svg +1 -0
  390. package/dist/assets/Icons/panel-right.svg +1 -0
  391. package/dist/assets/Icons/panel-top-bottom-dashed.svg +1 -0
  392. package/dist/assets/Icons/panel-top-close.svg +1 -0
  393. package/dist/assets/Icons/panel-top-open.svg +1 -0
  394. package/dist/assets/Icons/panel-top.svg +1 -0
  395. package/dist/assets/Icons/panels-left-bottom.svg +1 -0
  396. package/dist/assets/Icons/panels-right-bottom.svg +1 -0
  397. package/dist/assets/Icons/panels-top-left.svg +1 -0
  398. package/dist/assets/Icons/paperclip.svg +1 -0
  399. package/dist/assets/Icons/patreon-neutral.svg +1 -0
  400. package/dist/assets/Icons/patreon.svg +1 -0
  401. package/dist/assets/Icons/paypal-neutral.svg +1 -0
  402. package/dist/assets/Icons/paypal.svg +1 -0
  403. package/dist/assets/Icons/pen-line.svg +1 -0
  404. package/dist/assets/Icons/pen-off.svg +1 -0
  405. package/dist/assets/Icons/pen-tool.svg +1 -0
  406. package/dist/assets/Icons/pen.svg +1 -0
  407. package/dist/assets/Icons/pencil-line.svg +1 -0
  408. package/dist/assets/Icons/pencil-off.svg +1 -0
  409. package/dist/assets/Icons/pencil-ruler.svg +1 -0
  410. package/dist/assets/Icons/pencil.svg +1 -0
  411. package/dist/assets/Icons/pentagon.svg +1 -0
  412. package/dist/assets/Icons/percentage.svg +1 -0
  413. package/dist/assets/Icons/phone.svg +1 -0
  414. package/dist/assets/Icons/pin-off.svg +1 -0
  415. package/dist/assets/Icons/pin.svg +1 -0
  416. package/dist/assets/Icons/pinterest-neutral.svg +1 -0
  417. package/dist/assets/Icons/pinterest.svg +1 -0
  418. package/dist/assets/Icons/play.svg +1 -0
  419. package/dist/assets/Icons/plug.svg +1 -0
  420. package/dist/assets/Icons/plunk-neutral.svg +1 -0
  421. package/dist/assets/Icons/plunk.svg +1 -0
  422. package/dist/assets/Icons/plus.svg +1 -0
  423. package/dist/assets/Icons/postmark-neutral.svg +1 -0
  424. package/dist/assets/Icons/postmark.svg +1 -0
  425. package/dist/assets/Icons/product-hunt-neutral.svg +1 -0
  426. package/dist/assets/Icons/product-hunt.svg +1 -0
  427. package/dist/assets/Icons/quora-neutral.svg +1 -0
  428. package/dist/assets/Icons/quora.svg +1 -0
  429. package/dist/assets/Icons/quote.svg +1 -0
  430. package/dist/assets/Icons/radar.svg +1 -0
  431. package/dist/assets/Icons/reddit-neutral.svg +1 -0
  432. package/dist/assets/Icons/reddit.svg +1 -0
  433. package/dist/assets/Icons/redo-dot.svg +1 -0
  434. package/dist/assets/Icons/redo.svg +1 -0
  435. package/dist/assets/Icons/redo2.svg +1 -0
  436. package/dist/assets/Icons/refresh-ccw.svg +1 -0
  437. package/dist/assets/Icons/refresh-cw-off.svg +1 -0
  438. package/dist/assets/Icons/resend-neutral.svg +1 -0
  439. package/dist/assets/Icons/resend.svg +1 -0
  440. package/dist/assets/Icons/rss.svg +1 -0
  441. package/dist/assets/Icons/rules.svg +1 -0
  442. package/dist/assets/Icons/scan-line.svg +1 -0
  443. package/dist/assets/Icons/scroll-text.svg +1 -0
  444. package/dist/assets/Icons/search-hint.svg +1 -0
  445. package/dist/assets/Icons/search-x.svg +1 -0
  446. package/dist/assets/Icons/search.svg +1 -0
  447. package/dist/assets/Icons/sendgrid-neutral.svg +1 -0
  448. package/dist/assets/Icons/sendgrid.svg +1 -0
  449. package/dist/assets/Icons/server.svg +1 -0
  450. package/dist/assets/Icons/ses-neutral.svg +1 -0
  451. package/dist/assets/Icons/ses.svg +1 -0
  452. package/dist/assets/Icons/settings.svg +1 -0
  453. package/dist/assets/Icons/settings2.svg +1 -0
  454. package/dist/assets/Icons/shapes.svg +1 -0
  455. package/dist/assets/Icons/share.svg +1 -0
  456. package/dist/assets/Icons/sheet.svg +1 -0
  457. package/dist/assets/Icons/shield-alert.svg +1 -0
  458. package/dist/assets/Icons/shield-ban.svg +1 -0
  459. package/dist/assets/Icons/shield-check.svg +1 -0
  460. package/dist/assets/Icons/shield-ellipsis.svg +1 -0
  461. package/dist/assets/Icons/shield-half.svg +1 -0
  462. package/dist/assets/Icons/shield-minus.svg +1 -0
  463. package/dist/assets/Icons/shield-off.svg +1 -0
  464. package/dist/assets/Icons/shield-plus.svg +1 -0
  465. package/dist/assets/Icons/shield-question.svg +1 -0
  466. package/dist/assets/Icons/shield-user.svg +1 -0
  467. package/dist/assets/Icons/shield-x.svg +1 -0
  468. package/dist/assets/Icons/shield.svg +1 -0
  469. package/dist/assets/Icons/shift.svg +1 -0
  470. package/dist/assets/Icons/signal-neutral.svg +1 -0
  471. package/dist/assets/Icons/signal.svg +1 -0
  472. package/dist/assets/Icons/signpost.svg +1 -0
  473. package/dist/assets/Icons/sina-weibo-neutral.svg +1 -0
  474. package/dist/assets/Icons/sina-weibo.svg +1 -0
  475. package/dist/assets/Icons/skull.svg +1 -0
  476. package/dist/assets/Icons/skype-neutral.svg +1 -0
  477. package/dist/assets/Icons/skype.svg +1 -0
  478. package/dist/assets/Icons/slack-neutral.svg +1 -0
  479. package/dist/assets/Icons/slack.svg +1 -0
  480. package/dist/assets/Icons/sliders-horizontal.svg +1 -0
  481. package/dist/assets/Icons/sliders-vertical.svg +1 -0
  482. package/dist/assets/Icons/smtp-neutral.svg +1 -0
  483. package/dist/assets/Icons/smtp.svg +1 -0
  484. package/dist/assets/Icons/snapchat-neutral.svg +1 -0
  485. package/dist/assets/Icons/snapchat.svg +1 -0
  486. package/dist/assets/Icons/soundcloud-neutral.svg +1 -0
  487. package/dist/assets/Icons/soundcloud.svg +1 -0
  488. package/dist/assets/Icons/space.svg +1 -0
  489. package/dist/assets/Icons/sparkpost-neutral.svg +1 -0
  490. package/dist/assets/Icons/sparkpost.svg +1 -0
  491. package/dist/assets/Icons/speed.svg +1 -0
  492. package/dist/assets/Icons/split.svg +1 -0
  493. package/dist/assets/Icons/spotify-neutral.svg +1 -0
  494. package/dist/assets/Icons/spotify.svg +1 -0
  495. package/dist/assets/Icons/square-arrow-out-up-right.svg +1 -0
  496. package/dist/assets/Icons/square-minus.svg +1 -0
  497. package/dist/assets/Icons/square-pen.svg +1 -0
  498. package/dist/assets/Icons/square-plus.svg +1 -0
  499. package/dist/assets/Icons/square-user-round.svg +1 -0
  500. package/dist/assets/Icons/stack-overflow-neutral.svg +1 -0
  501. package/dist/assets/Icons/stack-overflow.svg +1 -0
  502. package/dist/assets/Icons/star.svg +1 -0
  503. package/dist/assets/Icons/sun.svg +1 -0
  504. package/dist/assets/Icons/syringe.svg +1 -0
  505. package/dist/assets/Icons/tag.svg +1 -0
  506. package/dist/assets/Icons/target.svg +1 -0
  507. package/dist/assets/Icons/teams-neutral.svg +1 -0
  508. package/dist/assets/Icons/teams.svg +1 -0
  509. package/dist/assets/Icons/telegram-neutral.svg +1 -0
  510. package/dist/assets/Icons/telegram-only-sign-neutral.svg +1 -0
  511. package/dist/assets/Icons/telegram-only-sign.svg +1 -0
  512. package/dist/assets/Icons/telegram.svg +1 -0
  513. package/dist/assets/Icons/terminal.svg +1 -0
  514. package/dist/assets/Icons/test-policies.svg +1 -0
  515. package/dist/assets/Icons/threads-neutral.svg +1 -0
  516. package/dist/assets/Icons/threads.svg +1 -0
  517. package/dist/assets/Icons/thumbs-down.svg +1 -0
  518. package/dist/assets/Icons/thumbs-up.svg +1 -0
  519. package/dist/assets/Icons/tiktok-neutral.svg +1 -0
  520. package/dist/assets/Icons/tiktok.svg +1 -0
  521. package/dist/assets/Icons/tinder-neutral.svg +1 -0
  522. package/dist/assets/Icons/tinder.svg +1 -0
  523. package/dist/assets/Icons/trash.svg +1 -0
  524. package/dist/assets/Icons/trash2.svg +1 -0
  525. package/dist/assets/Icons/triangle-alert.svg +1 -0
  526. package/dist/assets/Icons/tumblr-neutral.svg +1 -0
  527. package/dist/assets/Icons/tumblr.svg +1 -0
  528. package/dist/assets/Icons/twitch-neutral.svg +1 -0
  529. package/dist/assets/Icons/twitch.svg +1 -0
  530. package/dist/assets/Icons/undo-dot.svg +1 -0
  531. package/dist/assets/Icons/undo.svg +1 -0
  532. package/dist/assets/Icons/undo2.svg +1 -0
  533. package/dist/assets/Icons/unplug.svg +1 -0
  534. package/dist/assets/Icons/user-check.svg +1 -0
  535. package/dist/assets/Icons/user-minus.svg +1 -0
  536. package/dist/assets/Icons/user-plus.svg +1 -0
  537. package/dist/assets/Icons/user-round-x.svg +1 -0
  538. package/dist/assets/Icons/user-round.svg +1 -0
  539. package/dist/assets/Icons/user.svg +1 -0
  540. package/dist/assets/Icons/username.svg +1 -0
  541. package/dist/assets/Icons/users-round.svg +1 -0
  542. package/dist/assets/Icons/users.svg +1 -0
  543. package/dist/assets/Icons/viber-neutral.svg +1 -0
  544. package/dist/assets/Icons/viber.svg +1 -0
  545. package/dist/assets/Icons/video.svg +1 -0
  546. package/dist/assets/Icons/vimeo-neutral.svg +1 -0
  547. package/dist/assets/Icons/vimeo.svg +1 -0
  548. package/dist/assets/Icons/vk-music-neutral.svg +1 -0
  549. package/dist/assets/Icons/vk-music.svg +1 -0
  550. package/dist/assets/Icons/vk-neutral.svg +1 -0
  551. package/dist/assets/Icons/vk-only-sign-neutral.svg +1 -0
  552. package/dist/assets/Icons/vk-only-sign.svg +1 -0
  553. package/dist/assets/Icons/vk.svg +1 -0
  554. package/dist/assets/Icons/webhook-neutral.svg +1 -0
  555. package/dist/assets/Icons/webhook.svg +1 -0
  556. package/dist/assets/Icons/wechat-neutral.svg +1 -0
  557. package/dist/assets/Icons/wechat.svg +1 -0
  558. package/dist/assets/Icons/whatsapp-badge-neutral.svg +1 -0
  559. package/dist/assets/Icons/whatsapp-badge.svg +1 -0
  560. package/dist/assets/Icons/whatsapp-neutral.svg +1 -0
  561. package/dist/assets/Icons/whatsapp.svg +1 -0
  562. package/dist/assets/Icons/workflow.svg +1 -0
  563. package/dist/assets/Icons/wrap-text.svg +1 -0
  564. package/dist/assets/Icons/wrench.svg +1 -0
  565. package/dist/assets/Icons/x-ex-twitter-neutral.svg +1 -0
  566. package/dist/assets/Icons/x-ex-twitter.svg +1 -0
  567. package/dist/assets/Icons/x.svg +1 -0
  568. package/dist/assets/Icons/xing-neutral.svg +1 -0
  569. package/dist/assets/Icons/xing.svg +1 -0
  570. package/dist/assets/Icons/yandex-music-neutral.svg +1 -0
  571. package/dist/assets/Icons/yandex-music.svg +1 -0
  572. package/dist/assets/Icons/yelp-neutral.svg +1 -0
  573. package/dist/assets/Icons/yelp.svg +1 -0
  574. package/dist/assets/Icons/youtube-music-neutral.svg +1 -0
  575. package/dist/assets/Icons/youtube-music.svg +1 -0
  576. package/dist/assets/Icons/youtube-neutral.svg +1 -0
  577. package/dist/assets/Icons/youtube-shorts-neutral.svg +1 -0
  578. package/dist/assets/Icons/youtube-shorts.svg +1 -0
  579. package/dist/assets/Icons/youtube.svg +1 -0
  580. package/dist/assets/Icons/zap.svg +1 -0
  581. package/dist/assets/Icons/zoom-in.svg +1 -0
  582. package/dist/assets/Icons/zoom-neutral.svg +1 -0
  583. package/dist/assets/Icons/zoom-out.svg +1 -0
  584. package/dist/assets/Icons/zoom.svg +1 -0
  585. package/dist/assets/Icons/zulip-neutral.svg +1 -0
  586. package/dist/assets/Icons/zulip.svg +1 -0
  587. package/dist/assets/Logos/wallarm.svg +1 -0
  588. package/dist/assets.json +4666 -0
  589. package/dist/project/README.md +265 -0
  590. package/dist/project/components/Accordion/README.md +354 -0
  591. package/dist/project/components/Accordion/preview.html +2 -0
  592. package/dist/project/components/Accordion/stories.js +12 -0
  593. package/dist/project/components/AgentAvatar/README.md +127 -0
  594. package/dist/project/components/AgentAvatar/preview.html +2 -0
  595. package/dist/project/components/AgentAvatar/stories.js +12 -0
  596. package/dist/project/components/AgentAvatar/stories.md +1805 -0
  597. package/dist/project/components/AgentGlyph/README.md +1182 -0
  598. package/dist/project/components/AgentGlyph/preview.html +2 -0
  599. package/dist/project/components/AgentGlyph/stories.js +12 -0
  600. package/dist/project/components/AgentLookBuilder/README.md +269 -0
  601. package/dist/project/components/AgentLookBuilder/preview.html +2 -0
  602. package/dist/project/components/AgentLookBuilder/stories.js +12 -0
  603. package/dist/project/components/Alert/README.md +492 -0
  604. package/dist/project/components/Alert/preview.html +2 -0
  605. package/dist/project/components/Alert/stories.js +12 -0
  606. package/dist/project/components/AnimatedBackground/README.md +124 -0
  607. package/dist/project/components/AnimatedBackground/preview.html +2 -0
  608. package/dist/project/components/AnimatedBackground/stories.js +12 -0
  609. package/dist/project/components/AppShell/README.md +75 -0
  610. package/dist/project/components/AppShell/preview.html +2 -0
  611. package/dist/project/components/AppShell/stories.js +28 -0
  612. package/dist/project/components/AppShell/stories.md +2878 -0
  613. package/dist/project/components/ApprovalCard/README.md +353 -0
  614. package/dist/project/components/ApprovalCard/preview.html +2 -0
  615. package/dist/project/components/ApprovalCard/stories.js +12 -0
  616. package/dist/project/components/AreaChart/README.md +673 -0
  617. package/dist/project/components/AreaChart/preview.html +2 -0
  618. package/dist/project/components/AreaChart/stories.js +12 -0
  619. package/dist/project/components/AssistantMessage/README.md +724 -0
  620. package/dist/project/components/AssistantMessage/preview.html +2 -0
  621. package/dist/project/components/AssistantMessage/stories.js +55 -0
  622. package/dist/project/components/Attribute/README.md +1174 -0
  623. package/dist/project/components/Attribute/preview.html +2 -0
  624. package/dist/project/components/Attribute/stories.js +12 -0
  625. package/dist/project/components/Avatar/README.md +416 -0
  626. package/dist/project/components/Avatar/preview.html +2 -0
  627. package/dist/project/components/Avatar/stories.js +12 -0
  628. package/dist/project/components/Badge/README.md +853 -0
  629. package/dist/project/components/Badge/preview.html +2 -0
  630. package/dist/project/components/Badge/stories.js +12 -0
  631. package/dist/project/components/Banner/README.md +341 -0
  632. package/dist/project/components/Banner/preview.html +2 -0
  633. package/dist/project/components/Banner/stories.js +12 -0
  634. package/dist/project/components/BarList/README.md +757 -0
  635. package/dist/project/components/BarList/preview.html +2 -0
  636. package/dist/project/components/BarList/stories.js +12 -0
  637. package/dist/project/components/Breadcrumbs/README.md +274 -0
  638. package/dist/project/components/Breadcrumbs/preview.html +2 -0
  639. package/dist/project/components/Breadcrumbs/stories.js +12 -0
  640. package/dist/project/components/BulkBar/README.md +19 -0
  641. package/dist/project/components/Button/README.md +467 -0
  642. package/dist/project/components/Button/preview.html +2 -0
  643. package/dist/project/components/Button/stories.js +12 -0
  644. package/dist/project/components/Calendar/README.md +654 -0
  645. package/dist/project/components/Calendar/preview.html +2 -0
  646. package/dist/project/components/Calendar/stories.js +12 -0
  647. package/dist/project/components/Card/README.md +367 -0
  648. package/dist/project/components/Card/preview.html +2 -0
  649. package/dist/project/components/Card/stories.js +12 -0
  650. package/dist/project/components/ChainOfThought/README.md +412 -0
  651. package/dist/project/components/ChainOfThought/preview.html +2 -0
  652. package/dist/project/components/ChainOfThought/stories.js +12 -0
  653. package/dist/project/components/Chart/README.md +224 -0
  654. package/dist/project/components/Chart/preview.html +2 -0
  655. package/dist/project/components/Chart/stories.js +12 -0
  656. package/dist/project/components/Chat/README.md +1244 -0
  657. package/dist/project/components/Chat/preview.html +2 -0
  658. package/dist/project/components/Chat/stories.js +12 -0
  659. package/dist/project/components/ChatInput/README.md +378 -0
  660. package/dist/project/components/ChatInput/preview.html +2 -0
  661. package/dist/project/components/ChatInput/stories.js +12 -0
  662. package/dist/project/components/ChatPermissions/README.md +218 -0
  663. package/dist/project/components/ChatPermissions/preview.html +2 -0
  664. package/dist/project/components/ChatPermissions/stories.js +12 -0
  665. package/dist/project/components/Checkbox/README.md +367 -0
  666. package/dist/project/components/Checkbox/preview.html +2 -0
  667. package/dist/project/components/Checkbox/stories.js +12 -0
  668. package/dist/project/components/Code/README.md +243 -0
  669. package/dist/project/components/Code/preview.html +2 -0
  670. package/dist/project/components/Code/stories.js +12 -0
  671. package/dist/project/components/CodeEditor/README.md +280 -0
  672. package/dist/project/components/CodeEditor/preview.html +2 -0
  673. package/dist/project/components/CodeEditor/stories.js +162 -0
  674. package/dist/project/components/CodeEditor/stories.md +1533 -0
  675. package/dist/project/components/CodeSnippet/README.md +1352 -0
  676. package/dist/project/components/CodeSnippet/preview.html +2 -0
  677. package/dist/project/components/CodeSnippet/stories.js +156 -0
  678. package/dist/project/components/ColumnChart/README.md +521 -0
  679. package/dist/project/components/ColumnChart/preview.html +2 -0
  680. package/dist/project/components/ColumnChart/stories.js +12 -0
  681. package/dist/project/components/Conversation/README.md +314 -0
  682. package/dist/project/components/Conversation/preview.html +2 -0
  683. package/dist/project/components/Conversation/stories.js +12 -0
  684. package/dist/project/components/Copyable/README.md +406 -0
  685. package/dist/project/components/Copyable/preview.html +2 -0
  686. package/dist/project/components/Copyable/stories.js +12 -0
  687. package/dist/project/components/Country/README.md +226 -0
  688. package/dist/project/components/Country/preview.html +2 -0
  689. package/dist/project/components/Country/stories.js +12 -0
  690. package/dist/project/components/Cover/preview.html +43 -0
  691. package/dist/project/components/DateInput/README.md +458 -0
  692. package/dist/project/components/DateInput/preview.html +2 -0
  693. package/dist/project/components/DateInput/stories.js +12 -0
  694. package/dist/project/components/DateRangeInput/README.md +412 -0
  695. package/dist/project/components/DateRangeInput/preview.html +2 -0
  696. package/dist/project/components/DateRangeInput/stories.js +12 -0
  697. package/dist/project/components/Dialog/README.md +1140 -0
  698. package/dist/project/components/Dialog/preview.html +2 -0
  699. package/dist/project/components/Dialog/stories.js +12 -0
  700. package/dist/project/components/Drawer/README.md +1163 -0
  701. package/dist/project/components/Drawer/preview.html +2 -0
  702. package/dist/project/components/Drawer/stories.js +12 -0
  703. package/dist/project/components/DropdownMenu/README.md +678 -0
  704. package/dist/project/components/DropdownMenu/preview.html +2 -0
  705. package/dist/project/components/DropdownMenu/stories.js +12 -0
  706. package/dist/project/components/EmptyState/README.md +276 -0
  707. package/dist/project/components/EmptyState/preview.html +2 -0
  708. package/dist/project/components/EmptyState/stories.js +12 -0
  709. package/dist/project/components/FeedbackPulse/README.md +125 -0
  710. package/dist/project/components/FeedbackPulse/preview.html +2 -0
  711. package/dist/project/components/FeedbackPulse/stories.js +12 -0
  712. package/dist/project/components/Field/README.md +676 -0
  713. package/dist/project/components/Field/preview.html +2 -0
  714. package/dist/project/components/Field/stories.js +12 -0
  715. package/dist/project/components/FileUpload/README.md +544 -0
  716. package/dist/project/components/FileUpload/preview.html +2 -0
  717. package/dist/project/components/FileUpload/stories.js +12 -0
  718. package/dist/project/components/FilterCascade/README.md +348 -0
  719. package/dist/project/components/FilterCascade/preview.html +2 -0
  720. package/dist/project/components/FilterCascade/stories.js +12 -0
  721. package/dist/project/components/FilterDropdown/README.md +542 -0
  722. package/dist/project/components/FilterDropdown/preview.html +2 -0
  723. package/dist/project/components/FilterDropdown/stories.js +12 -0
  724. package/dist/project/components/FilterInput/README.md +416 -0
  725. package/dist/project/components/FilterInput/preview.html +2 -0
  726. package/dist/project/components/FilterInput/stories.js +12 -0
  727. package/dist/project/components/FilterInput/stories.md +6682 -0
  728. package/dist/project/components/Flex/README.md +225 -0
  729. package/dist/project/components/Flex/preview.html +2 -0
  730. package/dist/project/components/Flex/stories.js +12 -0
  731. package/dist/project/components/FormatDateTime/README.md +315 -0
  732. package/dist/project/components/FormatDateTime/preview.html +2 -0
  733. package/dist/project/components/FormatDateTime/stories.js +12 -0
  734. package/dist/project/components/FormatNumber/README.md +317 -0
  735. package/dist/project/components/FormatNumber/preview.html +2 -0
  736. package/dist/project/components/FormatNumber/stories.js +12 -0
  737. package/dist/project/components/Heading/README.md +240 -0
  738. package/dist/project/components/Heading/preview.html +2 -0
  739. package/dist/project/components/Heading/stories.js +12 -0
  740. package/dist/project/components/HorizontalBarStack/README.md +281 -0
  741. package/dist/project/components/HorizontalBarStack/preview.html +2 -0
  742. package/dist/project/components/HorizontalBarStack/stories.js +12 -0
  743. package/dist/project/components/HttpMethod/README.md +137 -0
  744. package/dist/project/components/HttpMethod/preview.html +2 -0
  745. package/dist/project/components/HttpMethod/stories.js +12 -0
  746. package/dist/project/components/ImageCropper/README.md +332 -0
  747. package/dist/project/components/ImageCropper/preview.html +2 -0
  748. package/dist/project/components/ImageCropper/stories.js +33 -0
  749. package/dist/project/components/Indicator/README.md +110 -0
  750. package/dist/project/components/Indicator/preview.html +2 -0
  751. package/dist/project/components/Indicator/stories.js +12 -0
  752. package/dist/project/components/InlineEdit/README.md +977 -0
  753. package/dist/project/components/InlineEdit/preview.html +2 -0
  754. package/dist/project/components/InlineEdit/stories.js +12 -0
  755. package/dist/project/components/Input/README.md +187 -0
  756. package/dist/project/components/Input/preview.html +2 -0
  757. package/dist/project/components/Input/stories.js +12 -0
  758. package/dist/project/components/InputGroup/README.md +423 -0
  759. package/dist/project/components/InputGroup/preview.html +2 -0
  760. package/dist/project/components/InputGroup/stories.js +12 -0
  761. package/dist/project/components/InputOTP/README.md +201 -0
  762. package/dist/project/components/InputOTP/preview.html +2 -0
  763. package/dist/project/components/InputOTP/stories.js +12 -0
  764. package/dist/project/components/Ip/README.md +226 -0
  765. package/dist/project/components/Ip/preview.html +2 -0
  766. package/dist/project/components/Ip/stories.js +12 -0
  767. package/dist/project/components/Kbd/README.md +126 -0
  768. package/dist/project/components/Kbd/preview.html +2 -0
  769. package/dist/project/components/Kbd/stories.js +12 -0
  770. package/dist/project/components/LineChart/README.md +1479 -0
  771. package/dist/project/components/LineChart/preview.html +2 -0
  772. package/dist/project/components/LineChart/stories.js +12 -0
  773. package/dist/project/components/Link/README.md +160 -0
  774. package/dist/project/components/Link/preview.html +2 -0
  775. package/dist/project/components/Link/stories.js +12 -0
  776. package/dist/project/components/List/README.md +181 -0
  777. package/dist/project/components/List/preview.html +2 -0
  778. package/dist/project/components/List/stories.js +12 -0
  779. package/dist/project/components/Loader/README.md +145 -0
  780. package/dist/project/components/Loader/preview.html +2 -0
  781. package/dist/project/components/Loader/stories.js +12 -0
  782. package/dist/project/components/Logo/README.md +183 -0
  783. package/dist/project/components/Logo/preview.html +2 -0
  784. package/dist/project/components/Logo/stories.js +12 -0
  785. package/dist/project/components/MessageActions/README.md +255 -0
  786. package/dist/project/components/MessageActions/preview.html +2 -0
  787. package/dist/project/components/MessageActions/stories.js +12 -0
  788. package/dist/project/components/Metric/README.md +324 -0
  789. package/dist/project/components/Metric/preview.html +2 -0
  790. package/dist/project/components/Metric/stories.js +12 -0
  791. package/dist/project/components/NavRail/README.md +25 -0
  792. package/dist/project/components/NotificationCenter/README.md +91 -0
  793. package/dist/project/components/NotificationCenter/preview.html +2 -0
  794. package/dist/project/components/NotificationCenter/stories.js +12 -0
  795. package/dist/project/components/NotificationCenter/stories.md +2170 -0
  796. package/dist/project/components/NumberInput/README.md +177 -0
  797. package/dist/project/components/NumberInput/preview.html +2 -0
  798. package/dist/project/components/NumberInput/stories.js +12 -0
  799. package/dist/project/components/NumericBadge/README.md +252 -0
  800. package/dist/project/components/NumericBadge/preview.html +2 -0
  801. package/dist/project/components/NumericBadge/stories.js +12 -0
  802. package/dist/project/components/OverflowList/README.md +324 -0
  803. package/dist/project/components/OverflowList/preview.html +2 -0
  804. package/dist/project/components/OverflowList/stories.js +12 -0
  805. package/dist/project/components/OverflowTooltip/README.md +421 -0
  806. package/dist/project/components/OverflowTooltip/preview.html +2 -0
  807. package/dist/project/components/OverflowTooltip/stories.js +12 -0
  808. package/dist/project/components/Overlay/README.md +95 -0
  809. package/dist/project/components/Overlay/preview.html +2 -0
  810. package/dist/project/components/Overlay/stories.js +12 -0
  811. package/dist/project/components/Overview/README.md +445 -0
  812. package/dist/project/components/Overview/preview.html +2 -0
  813. package/dist/project/components/Overview/stories.js +12 -0
  814. package/dist/project/components/Page/README.md +215 -0
  815. package/dist/project/components/Page/preview.html +2 -0
  816. package/dist/project/components/Page/stories.js +12 -0
  817. package/dist/project/components/Pagination/README.md +302 -0
  818. package/dist/project/components/Pagination/preview.html +2 -0
  819. package/dist/project/components/Pagination/stories.js +12 -0
  820. package/dist/project/components/ParameterPath/README.md +284 -0
  821. package/dist/project/components/ParameterPath/preview.html +2 -0
  822. package/dist/project/components/ParameterPath/stories.js +12 -0
  823. package/dist/project/components/PasswordComplexity/README.md +171 -0
  824. package/dist/project/components/PasswordComplexity/preview.html +2 -0
  825. package/dist/project/components/PasswordComplexity/stories.js +12 -0
  826. package/dist/project/components/PasswordInput/README.md +254 -0
  827. package/dist/project/components/PasswordInput/preview.html +2 -0
  828. package/dist/project/components/PasswordInput/stories.js +12 -0
  829. package/dist/project/components/PieChart/README.md +895 -0
  830. package/dist/project/components/PieChart/preview.html +2 -0
  831. package/dist/project/components/PieChart/stories.js +12 -0
  832. package/dist/project/components/Popover/README.md +282 -0
  833. package/dist/project/components/Popover/preview.html +2 -0
  834. package/dist/project/components/Popover/stories.js +12 -0
  835. package/dist/project/components/Progress/README.md +174 -0
  836. package/dist/project/components/Progress/preview.html +2 -0
  837. package/dist/project/components/Progress/stories.js +12 -0
  838. package/dist/project/components/Radio/README.md +264 -0
  839. package/dist/project/components/Radio/preview.html +2 -0
  840. package/dist/project/components/Radio/stories.js +12 -0
  841. package/dist/project/components/RemoteShell/README.md +1758 -0
  842. package/dist/project/components/RemoteShell/preview.html +2 -0
  843. package/dist/project/components/RemoteShell/stories.js +28 -0
  844. package/dist/project/components/Resizable/README.md +290 -0
  845. package/dist/project/components/Resizable/preview.html +2 -0
  846. package/dist/project/components/Resizable/stories.js +12 -0
  847. package/dist/project/components/ResponseCode/README.md +205 -0
  848. package/dist/project/components/ResponseCode/preview.html +2 -0
  849. package/dist/project/components/ResponseCode/stories.js +12 -0
  850. package/dist/project/components/ScrollArea/README.md +234 -0
  851. package/dist/project/components/ScrollArea/preview.html +2 -0
  852. package/dist/project/components/ScrollArea/stories.js +12 -0
  853. package/dist/project/components/SearchInput/README.md +158 -0
  854. package/dist/project/components/SearchInput/preview.html +2 -0
  855. package/dist/project/components/SearchInput/stories.js +12 -0
  856. package/dist/project/components/SearchModal/README.md +836 -0
  857. package/dist/project/components/SearchModal/preview.html +2 -0
  858. package/dist/project/components/SearchModal/stories.js +12 -0
  859. package/dist/project/components/SegmentedControl/README.md +382 -0
  860. package/dist/project/components/SegmentedControl/preview.html +2 -0
  861. package/dist/project/components/SegmentedControl/stories.js +12 -0
  862. package/dist/project/components/SegmentedTabs/README.md +390 -0
  863. package/dist/project/components/SegmentedTabs/preview.html +2 -0
  864. package/dist/project/components/SegmentedTabs/stories.js +12 -0
  865. package/dist/project/components/Select/README.md +1311 -0
  866. package/dist/project/components/Select/preview.html +2 -0
  867. package/dist/project/components/Select/stories.js +12 -0
  868. package/dist/project/components/Selection/README.md +648 -0
  869. package/dist/project/components/Selection/preview.html +2 -0
  870. package/dist/project/components/Selection/stories.js +12 -0
  871. package/dist/project/components/Separator/README.md +77 -0
  872. package/dist/project/components/Separator/preview.html +2 -0
  873. package/dist/project/components/Separator/stories.js +12 -0
  874. package/dist/project/components/Skeleton/README.md +358 -0
  875. package/dist/project/components/Skeleton/preview.html +2 -0
  876. package/dist/project/components/Skeleton/stories.js +12 -0
  877. package/dist/project/components/Slider/README.md +433 -0
  878. package/dist/project/components/Slider/preview.html +2 -0
  879. package/dist/project/components/Slider/stories.js +12 -0
  880. package/dist/project/components/SplashScreen/README.md +192 -0
  881. package/dist/project/components/SplashScreen/preview.html +2 -0
  882. package/dist/project/components/SplashScreen/stories.js +12 -0
  883. package/dist/project/components/SplitButton/README.md +402 -0
  884. package/dist/project/components/SplitButton/preview.html +2 -0
  885. package/dist/project/components/SplitButton/stories.js +12 -0
  886. package/dist/project/components/Stack/README.md +269 -0
  887. package/dist/project/components/Stack/preview.html +2 -0
  888. package/dist/project/components/Stack/stories.js +12 -0
  889. package/dist/project/components/Stepper/README.md +682 -0
  890. package/dist/project/components/Stepper/preview.html +2 -0
  891. package/dist/project/components/Stepper/stories.js +12 -0
  892. package/dist/project/components/Switch/README.md +236 -0
  893. package/dist/project/components/Switch/preview.html +2 -0
  894. package/dist/project/components/Switch/stories.js +12 -0
  895. package/dist/project/components/Table/README.md +471 -0
  896. package/dist/project/components/Table/preview.html +2 -0
  897. package/dist/project/components/Table/stories.js +12 -0
  898. package/dist/project/components/Table/stories.md +3697 -0
  899. package/dist/project/components/Tabs/README.md +443 -0
  900. package/dist/project/components/Tabs/preview.html +2 -0
  901. package/dist/project/components/Tabs/stories.js +12 -0
  902. package/dist/project/components/Tag/README.md +324 -0
  903. package/dist/project/components/Tag/preview.html +2 -0
  904. package/dist/project/components/Tag/stories.js +12 -0
  905. package/dist/project/components/Text/README.md +200 -0
  906. package/dist/project/components/Text/preview.html +2 -0
  907. package/dist/project/components/Text/stories.js +12 -0
  908. package/dist/project/components/Textarea/README.md +273 -0
  909. package/dist/project/components/Textarea/preview.html +2 -0
  910. package/dist/project/components/Textarea/stories.js +12 -0
  911. package/dist/project/components/TimeInput/README.md +359 -0
  912. package/dist/project/components/TimeInput/preview.html +2 -0
  913. package/dist/project/components/TimeInput/stories.js +12 -0
  914. package/dist/project/components/Timeline/README.md +204 -0
  915. package/dist/project/components/Timeline/preview.html +2 -0
  916. package/dist/project/components/Timeline/stories.js +12 -0
  917. package/dist/project/components/Toast/README.md +718 -0
  918. package/dist/project/components/Toast/preview.html +2 -0
  919. package/dist/project/components/Toast/stories.js +12 -0
  920. package/dist/project/components/ToggleButton/README.md +292 -0
  921. package/dist/project/components/ToggleButton/preview.html +2 -0
  922. package/dist/project/components/ToggleButton/stories.js +12 -0
  923. package/dist/project/components/Tooltip/README.md +199 -0
  924. package/dist/project/components/Tooltip/preview.html +2 -0
  925. package/dist/project/components/Tooltip/stories.js +12 -0
  926. package/dist/project/components/TopHeader/README.md +21 -0
  927. package/dist/project/components/Tour/README.md +532 -0
  928. package/dist/project/components/Tour/preview.html +2 -0
  929. package/dist/project/components/Tour/stories.js +12 -0
  930. package/dist/project/components/Tree/README.md +450 -0
  931. package/dist/project/components/Tree/preview.html +2 -0
  932. package/dist/project/components/Tree/stories.js +12 -0
  933. package/dist/project/components/TreeView/README.md +531 -0
  934. package/dist/project/components/TreeView/preview.html +2 -0
  935. package/dist/project/components/TreeView/stories.js +12 -0
  936. package/dist/project/components/UTILITIES.md +647 -0
  937. package/dist/project/components/UserMessage/README.md +166 -0
  938. package/dist/project/components/UserMessage/preview.html +2 -0
  939. package/dist/project/components/UserMessage/stories.js +12 -0
  940. package/dist/project/components/UtilityPage/README.md +147 -0
  941. package/dist/project/components/UtilityPage/preview.html +2 -0
  942. package/dist/project/components/UtilityPage/stories.js +12 -0
  943. package/dist/project/components/WallyAssistant/README.md +1380 -0
  944. package/dist/project/components/WallyAssistant/preview.html +2 -0
  945. package/dist/project/components/WallyAssistant/stories.js +12 -0
  946. package/dist/project/components/WallyIcon/README.md +130 -0
  947. package/dist/project/components/WallyIcon/preview.html +2 -0
  948. package/dist/project/components/WallyIcon/stories.js +12 -0
  949. package/dist/project/components/WallySkeleton/README.md +96 -0
  950. package/dist/project/components/WallySkeleton/preview.html +2 -0
  951. package/dist/project/components/WallySkeleton/stories.js +12 -0
  952. package/dist/project/components/bundle.css +18734 -0
  953. package/dist/project/components/bundle.js +167 -0
  954. package/dist/project/components/index.d.ts +27226 -0
  955. package/dist/project/design-system.json +35 -0
  956. package/dist/project/fonts/Geist-Variable.woff2 +0 -0
  957. package/dist/project/fonts/GeistMono-Variable.woff2 +0 -0
  958. package/dist/project/fonts/GeistPixel-Square.woff2 +0 -0
  959. package/dist/project/sampler.dc.html +238 -0
  960. package/dist/project/tokens.css +1395 -0
  961. package/dist/project/tokens.json +5235 -0
  962. package/dist/wallarm-sampler.dc.html +239 -0
  963. package/package.json +67 -3
@@ -0,0 +1,1533 @@
1
+ # CodeEditor story sources
2
+
3
+ ### CodeEditor/CodeEditor.stories.tsx
4
+
5
+ ```tsx
6
+ import { type ReactNode, useState } from 'react';
7
+ import type { Meta, StoryFn } from 'storybook-react-rsbuild';
8
+ import { Info, Skull, TriangleAlert } from '../../icons';
9
+ import { Button } from '../Button';
10
+ import {
11
+ CodeSnippetActions,
12
+ CodeSnippetAdapterProvider,
13
+ CodeSnippetCode,
14
+ CodeSnippetContent,
15
+ CodeSnippetCopyButton,
16
+ CodeSnippetFullscreenButton,
17
+ CodeSnippetHeader,
18
+ CodeSnippetLineNumbers,
19
+ CodeSnippetRoot,
20
+ CodeSnippetShowMoreButton,
21
+ type CodeSnippetSize,
22
+ CodeSnippetTab,
23
+ CodeSnippetTabs,
24
+ CodeSnippetTitle,
25
+ CodeSnippetWrapButton,
26
+ type FoldRegion,
27
+ getHttpFolds,
28
+ type LineConfig,
29
+ loadPrismAdapter,
30
+ loadShikiAdapter,
31
+ } from '../CodeSnippet';
32
+ import {
33
+ Drawer,
34
+ DrawerBody,
35
+ DrawerContent,
36
+ DrawerHeader,
37
+ DrawerTitle,
38
+ DrawerTrigger,
39
+ } from '../Drawer';
40
+ import { VStack } from '../Stack';
41
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../Tooltip';
42
+ import { CodeEditorContent } from './CodeEditorContent';
43
+ import { CodeEditorRoot } from './CodeEditorRoot';
44
+ import { EditingWorkflowDemo } from './story-content/_storyEditingWorkflow';
45
+ import { LongDocumentDemo } from './story-content/_storyLongDocument';
46
+ import { TabsKeepHistoryDemo } from './story-content/_storyTabsKeepHistory';
47
+ import type { CodeEditorDiagnostic, CodeEditorLanguage } from './types';
48
+
49
+ const DESCRIPTION = [
50
+ 'An editable code surface that is visually the same component as `CodeSnippet` and reuses its header, tabs, actions and show-more — reach for `CodeSnippet` whenever the code is only read, since a page that never renders `CodeEditorContent` never loads the editor engine.',
51
+ 'Colours come from the same `CodeSnippetAdapterProvider` (plain text without one), so a read-only editor matches the snippet except for a native thin scrollbar, a caret and selection drawn by the editor, and an HTTP JSON body that stays coloured when `Content-Type` has parameters or the body has blank lines.',
52
+ 'The adapter re-tokenizes the whole document after each pause in typing, which stays within a frame up to about 2 000 lines with Prism; longer documents still edit smoothly, their colours just settle a moment later.',
53
+ 'Like the snippet, the editor sits inside a `display: contents` wrapper that keeps it mounted across fullscreen, so space editors with their own `className` (for example `mt-16`) or a `gap` on the parent — not `space-*`, `divide-*` or child selectors on the parent.',
54
+ '`lines`, `folds`, `completions` and `schema` are compared by identity, so memoise them or hoist them to module constants — a new value on every render reconfigures the editor.',
55
+ 'Autocomplete suggests language keywords and words already in the document for every language; HTTP methods and headers and JSON Schema values have their own contextual suggestions. Pass `completions` to add application-specific results.',
56
+ 'Syntax errors are best-effort: JSON reports the `JSON.parse` message, JavaScript and TypeScript use Babel, Lua uses luaparse (first error only), YAML and Python use their Lezer parsers, which still flag a few valid Python forms such as `lambda a, /, b` and parenthesised `with` items.',
57
+ '`lines` and `folds` stay on their line numbers while typing; to keep a decoration on a piece of text, recompute it from `value` (for example `useMemo(() => linesFor(value), [value])`, or a `folds` function such as `getHttpFolds`).',
58
+ 'The editor injects `<style>` tags, so under a strict Content Security Policy pass `cspNonce`.',
59
+ 'Tab indents, so keyboard users leave with Escape, then Tab, or press Ctrl+M (Alt+Shift+M on macOS) to switch Tab between indenting and moving focus — point `aria-describedby` at text holding `CODE_EDITOR_KEYBOARD_HINT` to tell screen-reader users.',
60
+ ].join(' ');
61
+
62
+ const meta = {
63
+ title: 'Data Display/CodeEditor',
64
+ component: CodeEditorRoot,
65
+ parameters: {
66
+ layout: 'padded',
67
+ docs: { description: { component: DESCRIPTION } },
68
+ design: {
69
+ type: 'figma',
70
+ url: 'https://www.figma.com/design/VKb5gW46uSGw0rqrhZsbXT/WADS-Components?node-id=3087-29516&m=dev',
71
+ },
72
+ },
73
+ tags: ['autodocs'],
74
+ } satisfies Meta<typeof CodeEditorRoot>;
75
+
76
+ export default meta;
77
+
78
+ // --- Sample documents ---
79
+
80
+ const jsonCode = `{
81
+ "name": "@wallarm-org/sdk",
82
+ "version": "1.0.0",
83
+ "dependencies": {
84
+ "react": "^19.0.0",
85
+ "typescript": "^5.0.0"
86
+ }
87
+ }`;
88
+
89
+ const sampleCode = `const greeting = "Hello, World!";
90
+ console.log(greeting);
91
+
92
+ function add(a, b) {
93
+ return a + b;
94
+ }
95
+
96
+ export default add;`;
97
+
98
+ const colorsCode = `Line 1: Default (no color)
99
+ Line 2: Danger color
100
+ Line 3: Warning color
101
+ Line 4: Info color
102
+ Line 5: Success color
103
+ Line 6: Brand color
104
+ Line 7: AI color
105
+ Line 8: Neutral color`;
106
+
107
+ const diffCode = `const greeting = "Hello";
108
+ console.log("old message");
109
+ console.log("new message");
110
+ console.log("another new line");
111
+
112
+ export default greeting;`;
113
+
114
+ const annotatedHeadersCode = `Host: inventory.example.com
115
+ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
116
+ AppleWebKit/537.36
117
+ Accept: application/json, text/plain, */*
118
+ Accept-Language: en-US,en;q=0.9
119
+ Connection: keep-alive
120
+ Cache-Control: no-cache`;
121
+
122
+ const rangesCode = `GET /api/v2/users HTTP/1.1
123
+ Host: inventory.example.com
124
+ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
125
+ Accept: application/json, text/plain, */*
126
+ Accept-Language: en-US,en;q=0.9
127
+ Connection: keep-alive
128
+ X-Forwarded-For: 192.168.1.100
129
+ Cache-Control: no-cache`;
130
+
131
+ const httpRequestCode = `POST /api/v2/rules HTTP/1.1
132
+ Host: api.wallarm.com
133
+ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
134
+ Content-Type: application/json
135
+ Accept: application/json
136
+
137
+ {
138
+ "action": "block",
139
+ "point": ["header", "X-Forwarded-For"],
140
+ "enabled": true
141
+ }`;
142
+
143
+ const httpResponseCode = `HTTP/1.1 200 OK
144
+ Content-Type: application/json; charset=utf-8
145
+ X-Request-Id: abc-123-def-456
146
+ Cache-Control: no-store
147
+
148
+ {
149
+ "users": [
150
+ { "id": 1, "name": "Alice" },
151
+ { "id": 2, "name": "Bob" }
152
+ ],
153
+ "total": 42
154
+ }`;
155
+
156
+ const foldableRequestCode = `GET /api/v2/users HTTP/1.1
157
+ Host: api.example.com
158
+ Accept: application/json
159
+ Authorization: Bearer eyJhbGciOiJIUzI1NiJ9
160
+ X-Request-ID: abc-123
161
+ Content-Type: application/json
162
+ Cache-Control: no-cache
163
+
164
+ {
165
+ "filter": {
166
+ "status": "active",
167
+ "role": "admin"
168
+ },
169
+ "pagination": {
170
+ "page": 1,
171
+ "limit": 50
172
+ }
173
+ }`;
174
+
175
+ const foldableResponseCode = `HTTP/1.1 200 OK
176
+ Content-Type: application/json; charset=utf-8
177
+ X-Request-ID: abc-123
178
+ X-RateLimit-Remaining: 98
179
+ Cache-Control: private, max-age=0
180
+
181
+ {
182
+ "data": [
183
+ { "id": 1, "name": "Alice", "role": "admin" },
184
+ { "id": 2, "name": "Bob", "role": "admin" }
185
+ ],
186
+ "meta": {
187
+ "total": 2,
188
+ "page": 1,
189
+ "limit": 50
190
+ }
191
+ }`;
192
+
193
+ const showMoreCode = `Host: inventory.example.com
194
+ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
195
+ Referer: https://app.example.com/dashboard
196
+ Accept: application/json, text/plain, */*
197
+ Accept-Language: en-US,en;q=0.9
198
+ Connection: keep-alive
199
+ Cache-Control: no-cache
200
+ Referer: https://app.example.com/dashboard
201
+ Accept: application/json, text/plain, */*
202
+ Accept-Language: en-US,en;q=0.9
203
+ Connection: keep-alive
204
+ Cache-Control: no-cache`;
205
+
206
+ const showMoreThresholdCode = `Host: inventory.example.com
207
+ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
208
+ Referer: https://app.example.com/dashboard
209
+ Accept: application/json, text/plain, */*
210
+ Accept-Language: en-US,en;q=0.9
211
+ Connection: keep-alive
212
+ Cache-Control: no-cache
213
+ Authorization: Bearer token123
214
+ X-Request-ID: abc-def-ghi`;
215
+
216
+ const longCode = `const veryLongVariableName = "This is a very long string that will demonstrate line wrapping behavior when the content exceeds the container width";
217
+ console.log(veryLongVariableName);`;
218
+
219
+ const bashCode = `npm install @wallarm-org/sdk
220
+ npm run build
221
+ npm run test`;
222
+
223
+ const tabDocuments = {
224
+ request: httpRequestCode,
225
+ response: `HTTP/1.1 201 Created
226
+ Content-Type: application/json
227
+ Location: /api/v2/rules/42
228
+
229
+ {
230
+ "id": 42,
231
+ "action": "block"
232
+ }`,
233
+ } satisfies Record<string, string>;
234
+
235
+ type TabId = keyof typeof tabDocuments;
236
+
237
+ const isTabId = (value: string): value is TabId => value === 'request' || value === 'response';
238
+
239
+ // --- Shared line configs and fold functions ---
240
+
241
+ const tooltipPrefix = (icon: ReactNode, text: string): ReactNode => (
242
+ <Tooltip>
243
+ <TooltipTrigger>{icon}</TooltipTrigger>
244
+ <TooltipContent>{text}</TooltipContent>
245
+ </Tooltip>
246
+ );
247
+
248
+ const colorLines: Record<number, LineConfig> = {
249
+ 2: { color: 'danger' },
250
+ 3: { color: 'warning' },
251
+ 4: { color: 'info' },
252
+ 5: { color: 'success' },
253
+ 6: { color: 'brand' },
254
+ 7: { color: 'ai' },
255
+ 8: { color: 'neutral' },
256
+ };
257
+
258
+ const diffLines: Record<number, LineConfig> = {
259
+ 2: { color: 'danger', prefix: '-' },
260
+ 3: { color: 'success', prefix: '+' },
261
+ 4: { color: 'success', prefix: '+' },
262
+ };
263
+
264
+ const iconLines: Record<number, LineConfig> = {
265
+ 3: { color: 'danger', prefix: tooltipPrefix(<Skull />, 'Malicious user agent') },
266
+ 5: { color: 'warning', prefix: tooltipPrefix(<TriangleAlert />, 'Unusual language list') },
267
+ 7: { color: 'info', prefix: tooltipPrefix(<Info />, 'Caching disabled') },
268
+ };
269
+
270
+ const rangeLines: Record<number, LineConfig> = {
271
+ 4: { color: 'danger', ranges: [{ start: 8, end: 24 }] },
272
+ 7: { color: 'info', ranges: [{ start: 17, end: 30 }] },
273
+ };
274
+
275
+ const wrapDiffLines: Record<number, LineConfig> = {
276
+ 1: { color: 'danger', prefix: '-' },
277
+ 2: { color: 'success', prefix: '+' },
278
+ };
279
+
280
+ const parityColorLines: Record<number, LineConfig> = {
281
+ ...colorLines,
282
+ 1: { prefix: tooltipPrefix(<Info />, 'Untouched line') },
283
+ 2: { color: 'danger', prefix: '-' },
284
+ 5: { color: 'success', prefix: '+' },
285
+ };
286
+
287
+ /** Module-level so the function identity is stable across renders. */
288
+ const foldRequestHeadersCollapsed = (
289
+ value: string,
290
+ { startingLineNumber }: { startingLineNumber: number },
291
+ ): FoldRegion[] => getHttpFolds(value, { startingLineNumber, headers: { defaultCollapsed: true } });
292
+
293
+ const foldHttp = (
294
+ value: string,
295
+ { startingLineNumber }: { startingLineNumber: number },
296
+ ): FoldRegion[] => getHttpFolds(value, { startingLineNumber });
297
+
298
+ const parityCollapsedFolds = getHttpFolds(foldableRequestCode, {
299
+ headers: { defaultCollapsed: true },
300
+ });
301
+
302
+ // --- Core stories ---
303
+
304
+ /**
305
+ * A controlled editor: `value` plus `onChange`, like any input. With no adapter in scope the
306
+ * text is plain, exactly as `CodeSnippet` renders it without a provider.
307
+ */
308
+ export const Default: StoryFn<typeof meta> = () => {
309
+ const [value, setValue] = useState(jsonCode);
310
+
311
+ return (
312
+ <div style={{ width: '600px' }}>
313
+ <CodeEditorRoot
314
+ value={value}
315
+ onChange={setValue}
316
+ language='json'
317
+ data-testid='code-editor-default'
318
+ >
319
+ <CodeEditorContent lineNumbers aria-label='Package manifest' />
320
+ </CodeEditorRoot>
321
+ </div>
322
+ );
323
+ };
324
+
325
+ /**
326
+ * The `CodeSnippet` header works unchanged: a title and the copy, wrap and fullscreen buttons.
327
+ * Copy puts the edited value on the clipboard, and fullscreen keeps the undo history.
328
+ */
329
+ export const WithHeader: StoryFn<typeof meta> = () => {
330
+ const [value, setValue] = useState(jsonCode);
331
+
332
+ return (
333
+ <div style={{ width: '600px' }}>
334
+ <CodeEditorRoot
335
+ value={value}
336
+ onChange={setValue}
337
+ language='json'
338
+ data-testid='code-editor-with-header'
339
+ >
340
+ <CodeSnippetHeader>
341
+ <CodeSnippetTitle>rule.json</CodeSnippetTitle>
342
+ <CodeSnippetActions>
343
+ <CodeSnippetCopyButton />
344
+ <CodeSnippetWrapButton />
345
+ <CodeSnippetFullscreenButton />
346
+ </CodeSnippetActions>
347
+ </CodeSnippetHeader>
348
+ <CodeEditorContent lineNumbers aria-label='Rule JSON' />
349
+ </CodeEditorRoot>
350
+ </div>
351
+ );
352
+ };
353
+
354
+ /**
355
+ * Without a header, `CodeSnippetActions` as a direct child floats over the top-right of the
356
+ * editor, as it does over a snippet.
357
+ */
358
+ export const FloatingActions: StoryFn<typeof meta> = () => {
359
+ const [value, setValue] = useState(sampleCode);
360
+
361
+ return (
362
+ <div style={{ width: '320px' }}>
363
+ <CodeEditorRoot
364
+ value={value}
365
+ onChange={setValue}
366
+ language='text'
367
+ data-testid='code-editor-floating-actions'
368
+ >
369
+ <CodeSnippetActions>
370
+ <CodeSnippetWrapButton />
371
+ <CodeSnippetCopyButton />
372
+ </CodeSnippetActions>
373
+ <CodeEditorContent lineNumbers aria-label='Sample code' />
374
+ </CodeEditorRoot>
375
+ </div>
376
+ );
377
+ };
378
+
379
+ /**
380
+ * `lineNumbers` on `CodeEditorContent` is the equivalent of `CodeSnippetLineNumbers`, and
381
+ * `startingLineNumber` renumbers the gutter for a fragment taken from a longer file.
382
+ */
383
+ export const LineNumbersAndStartingLine: StoryFn<typeof meta> = () => (
384
+ <VStack gap={16}>
385
+ <VStack align='start' gap={4}>
386
+ <span className='sb-annotation'>lineNumbers</span>
387
+ <div style={{ width: '600px' }}>
388
+ <CodeEditorRoot
389
+ defaultValue={sampleCode}
390
+ language='text'
391
+ data-testid='code-editor-line-numbers'
392
+ >
393
+ <CodeEditorContent lineNumbers aria-label='Sample code' />
394
+ </CodeEditorRoot>
395
+ </div>
396
+ </VStack>
397
+ <VStack align='start' gap={4}>
398
+ <span className='sb-annotation'>startingLineNumber = 97</span>
399
+ <div style={{ width: '600px' }}>
400
+ <CodeEditorRoot
401
+ defaultValue={sampleCode}
402
+ language='text'
403
+ startingLineNumber={97}
404
+ data-testid='code-editor-starting-line'
405
+ >
406
+ <CodeEditorContent lineNumbers aria-label='Sample code from line 97' />
407
+ </CodeEditorRoot>
408
+ </div>
409
+ </VStack>
410
+ </VStack>
411
+ );
412
+
413
+ /**
414
+ * `lines` uses the same `LineConfig` as CodeSnippet: seven semantic colours, text prefixes for a
415
+ * hand-made diff, and ReactNode prefixes such as a tooltipped icon. Lines are static and tied
416
+ * to line numbers, so they stay on their number while you type.
417
+ */
418
+ export const LineColorsAndPrefixes: StoryFn<typeof meta> = () => (
419
+ <VStack gap={16}>
420
+ <VStack align='start' gap={4}>
421
+ <span className='sb-annotation'>colours</span>
422
+ <div style={{ width: '600px' }}>
423
+ <CodeEditorRoot
424
+ defaultValue={colorsCode}
425
+ language='text'
426
+ lines={colorLines}
427
+ data-testid='code-editor-line-colors'
428
+ >
429
+ <CodeEditorContent lineNumbers aria-label='Line colours' />
430
+ </CodeEditorRoot>
431
+ </div>
432
+ </VStack>
433
+ <VStack align='start' gap={4}>
434
+ <span className='sb-annotation'>text prefixes</span>
435
+ <div style={{ width: '600px' }}>
436
+ <CodeEditorRoot
437
+ defaultValue={diffCode}
438
+ language='text'
439
+ lines={diffLines}
440
+ data-testid='code-editor-line-diff'
441
+ >
442
+ <CodeEditorContent lineNumbers aria-label='Diff prefixes' />
443
+ </CodeEditorRoot>
444
+ </div>
445
+ </VStack>
446
+ <VStack align='start' gap={4}>
447
+ <span className='sb-annotation'>ReactNode prefixes with tooltips</span>
448
+ <div style={{ width: '600px' }}>
449
+ <CodeEditorRoot
450
+ defaultValue={annotatedHeadersCode}
451
+ language='text'
452
+ lines={iconLines}
453
+ data-testid='code-editor-line-icons'
454
+ >
455
+ <CodeEditorContent lineNumbers aria-label='Annotated headers' />
456
+ </CodeEditorRoot>
457
+ </div>
458
+ </VStack>
459
+ </VStack>
460
+ );
461
+
462
+ /**
463
+ * `ranges` colours character offsets inside a line (start inclusive, end exclusive). The line
464
+ * keeps its background, and only the range gets the colour.
465
+ */
466
+ export const Ranges: StoryFn<typeof meta> = () => (
467
+ <div style={{ width: '600px' }}>
468
+ <CodeEditorRoot
469
+ defaultValue={rangesCode}
470
+ language='text'
471
+ lines={rangeLines}
472
+ data-testid='code-editor-ranges'
473
+ >
474
+ <CodeEditorContent lineNumbers aria-label='Request with ranges' />
475
+ </CodeEditorRoot>
476
+ </div>
477
+ );
478
+
479
+ /**
480
+ * `language='http'` under Prism. The colours come from the adapter and the structure (start
481
+ * line, headers, JSON body) comes from the editor's own HTTP grammar.
482
+ */
483
+ export const HttpRequestWithPrism: StoryFn<typeof meta> = () => {
484
+ const [value, setValue] = useState(httpRequestCode);
485
+
486
+ return (
487
+ <CodeSnippetAdapterProvider adapter={loadPrismAdapter}>
488
+ <div style={{ width: '600px' }}>
489
+ <CodeEditorRoot
490
+ value={value}
491
+ onChange={setValue}
492
+ language='http'
493
+ data-testid='code-editor-http-request'
494
+ >
495
+ <CodeEditorContent lineNumbers aria-label='HTTP request' />
496
+ </CodeEditorRoot>
497
+ </div>
498
+ </CodeSnippetAdapterProvider>
499
+ );
500
+ };
501
+
502
+ /**
503
+ * The response side under Shiki. After an edit, highlighting is repainted in the background,
504
+ * so for a moment you may see the previous colours mapped through your change.
505
+ */
506
+ export const HttpResponseWithShiki: StoryFn<typeof meta> = () => {
507
+ const [value, setValue] = useState(httpResponseCode);
508
+
509
+ return (
510
+ <CodeSnippetAdapterProvider adapter={loadShikiAdapter}>
511
+ <div style={{ width: '600px' }}>
512
+ <CodeEditorRoot
513
+ value={value}
514
+ onChange={setValue}
515
+ language='http'
516
+ data-testid='code-editor-http-response'
517
+ >
518
+ <CodeEditorContent lineNumbers aria-label='HTTP response' />
519
+ </CodeEditorRoot>
520
+ </div>
521
+ </CodeSnippetAdapterProvider>
522
+ );
523
+ };
524
+
525
+ /**
526
+ * `folds` as a function of the value: `getHttpFolds` runs again after edits, so adding a header
527
+ * grows the headers fold. Collapsed state is kept by fold `id`. The second editor starts at
528
+ * line 100, and the fold function gets the same offset.
529
+ */
530
+ export const HttpFolds: StoryFn<typeof meta> = () => {
531
+ const [request, setRequest] = useState(foldableRequestCode);
532
+ const [response, setResponse] = useState(foldableResponseCode);
533
+
534
+ return (
535
+ <VStack gap={16}>
536
+ <VStack align='start' gap={4}>
537
+ <span className='sb-annotation'>headers collapsed by default</span>
538
+ <div style={{ width: '600px' }}>
539
+ <CodeEditorRoot
540
+ value={request}
541
+ onChange={setRequest}
542
+ language='http'
543
+ folds={foldRequestHeadersCollapsed}
544
+ data-testid='code-editor-http-folds-request'
545
+ >
546
+ <CodeEditorContent lineNumbers aria-label='Foldable HTTP request' />
547
+ </CodeEditorRoot>
548
+ </div>
549
+ </VStack>
550
+ <VStack align='start' gap={4}>
551
+ <span className='sb-annotation'>startingLineNumber = 100</span>
552
+ <div style={{ width: '600px' }}>
553
+ <CodeEditorRoot
554
+ value={response}
555
+ onChange={setResponse}
556
+ language='http'
557
+ startingLineNumber={100}
558
+ folds={foldHttp}
559
+ data-testid='code-editor-http-folds-response'
560
+ >
561
+ <CodeEditorContent lineNumbers aria-label='Foldable HTTP response' />
562
+ </CodeEditorRoot>
563
+ </div>
564
+ </VStack>
565
+ </VStack>
566
+ );
567
+ };
568
+
569
+ /**
570
+ * `maxLines` limits the height, and the editor scrolls inside it (no rows are removed). The
571
+ * button appears on its own when at least three lines are hidden. Render
572
+ * `CodeSnippetShowMoreButton` yourself only to pass props to the real button.
573
+ */
574
+ export const ShowMore: StoryFn<typeof meta> = () => (
575
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '24px', width: '500px' }}>
576
+ <div>
577
+ <p className='sb-annotation mb-8'>12 lines, clamped at 7 — 5 hidden</p>
578
+ <CodeEditorRoot
579
+ defaultValue={showMoreCode}
580
+ language='text'
581
+ maxLines={7}
582
+ data-testid='code-editor-show-more'
583
+ >
584
+ <CodeEditorContent aria-label='Request headers' />
585
+ </CodeEditorRoot>
586
+ </div>
587
+ <div>
588
+ <p className='sb-annotation mb-8'>9 lines, clamped at 7 — 2 hidden, no button</p>
589
+ <CodeEditorRoot
590
+ defaultValue={showMoreThresholdCode}
591
+ language='text'
592
+ maxLines={7}
593
+ data-testid='code-editor-show-more-threshold'
594
+ >
595
+ <CodeEditorContent aria-label='Request headers' />
596
+ </CodeEditorRoot>
597
+ </div>
598
+ <div>
599
+ <p className='sb-annotation mb-8'>the button rendered by hand</p>
600
+ <CodeEditorRoot
601
+ defaultValue={showMoreCode}
602
+ language='text'
603
+ maxLines={7}
604
+ data-testid='code-editor-show-more-manual'
605
+ >
606
+ <CodeEditorContent aria-label='Request headers' />
607
+ <CodeSnippetShowMoreButton data-analytics-id='CODE_EDITOR_SHOW_MORE' />
608
+ </CodeEditorRoot>
609
+ </div>
610
+ </div>
611
+ );
612
+
613
+ /**
614
+ * Wrapping can be uncontrolled (`defaultWrapLines`, driven by the wrap button) or controlled
615
+ * (`wrapLines` plus `onWrapLinesChange`). Colour sticks and prefixes stay on the first visual row.
616
+ */
617
+ export const Wrap: StoryFn<typeof meta> = () => {
618
+ const [wrap, setWrap] = useState(true);
619
+
620
+ return (
621
+ <VStack gap={16}>
622
+ <VStack align='start' gap={4}>
623
+ <span className='sb-annotation'>no wrapping</span>
624
+ <div style={{ width: '600px' }}>
625
+ <CodeEditorRoot
626
+ defaultValue={longCode}
627
+ language='text'
628
+ lines={wrapDiffLines}
629
+ data-testid='code-editor-wrap-off'
630
+ >
631
+ <CodeEditorContent lineNumbers aria-label='Long lines' />
632
+ </CodeEditorRoot>
633
+ </div>
634
+ </VStack>
635
+ <VStack align='start' gap={4}>
636
+ <span className='sb-annotation'>defaultWrapLines + wrap button</span>
637
+ <div style={{ width: '600px' }}>
638
+ <CodeEditorRoot
639
+ defaultValue={longCode}
640
+ language='text'
641
+ defaultWrapLines
642
+ lines={wrapDiffLines}
643
+ data-testid='code-editor-wrap-uncontrolled'
644
+ >
645
+ <CodeSnippetActions>
646
+ <CodeSnippetWrapButton />
647
+ </CodeSnippetActions>
648
+ <CodeEditorContent lineNumbers aria-label='Long lines, wrapped' />
649
+ </CodeEditorRoot>
650
+ </div>
651
+ </VStack>
652
+ <VStack align='start' gap={4}>
653
+ <span className='sb-annotation'>controlled — wrapLines = {String(wrap)}</span>
654
+ <div style={{ width: '600px' }}>
655
+ <CodeEditorRoot
656
+ defaultValue={longCode}
657
+ language='text'
658
+ wrapLines={wrap}
659
+ onWrapLinesChange={setWrap}
660
+ data-testid='code-editor-wrap-controlled'
661
+ >
662
+ <CodeSnippetActions>
663
+ <CodeSnippetWrapButton />
664
+ </CodeSnippetActions>
665
+ <CodeEditorContent lineNumbers aria-label='Long lines, controlled wrap' />
666
+ </CodeEditorRoot>
667
+ </div>
668
+ </VStack>
669
+ </VStack>
670
+ );
671
+ };
672
+
673
+ /**
674
+ * The same three sizes as CodeSnippet: `sm` (12px, default), `md` (14px) and `lg` (16px), each
675
+ * on 20px rows.
676
+ */
677
+ export const Sizes: StoryFn<typeof meta> = () => (
678
+ <VStack gap={16}>
679
+ <VStack align='start' gap={4}>
680
+ <span className='sb-annotation'>sm (default)</span>
681
+ <div style={{ width: '600px' }}>
682
+ <CodeEditorRoot
683
+ defaultValue={bashCode}
684
+ language='bash'
685
+ size='sm'
686
+ data-testid='code-editor-size-sm'
687
+ >
688
+ <CodeEditorContent lineNumbers aria-label='Install commands, small' />
689
+ </CodeEditorRoot>
690
+ </div>
691
+ </VStack>
692
+ <VStack align='start' gap={4}>
693
+ <span className='sb-annotation'>md</span>
694
+ <div style={{ width: '600px' }}>
695
+ <CodeEditorRoot
696
+ defaultValue={bashCode}
697
+ language='bash'
698
+ size='md'
699
+ data-testid='code-editor-size-md'
700
+ >
701
+ <CodeEditorContent lineNumbers aria-label='Install commands, medium' />
702
+ </CodeEditorRoot>
703
+ </div>
704
+ </VStack>
705
+ <VStack align='start' gap={4}>
706
+ <span className='sb-annotation'>lg</span>
707
+ <div style={{ width: '600px' }}>
708
+ <CodeEditorRoot
709
+ defaultValue={bashCode}
710
+ language='bash'
711
+ size='lg'
712
+ data-testid='code-editor-size-lg'
713
+ >
714
+ <CodeEditorContent lineNumbers aria-label='Install commands, large' />
715
+ </CodeEditorRoot>
716
+ </div>
717
+ </VStack>
718
+ </VStack>
719
+ );
720
+
721
+ /**
722
+ * `readOnly` lets you select, search and copy without focusing the code or showing a caret. Use it when the value
723
+ * can change elsewhere but not here. If it never changes, use `CodeSnippet`.
724
+ */
725
+ export const ReadOnly: StoryFn<typeof meta> = () => (
726
+ <div style={{ width: '600px' }}>
727
+ <CodeEditorRoot
728
+ value={httpResponseCode}
729
+ language='http'
730
+ readOnly
731
+ data-testid='code-editor-read-only'
732
+ >
733
+ <CodeSnippetHeader>
734
+ <CodeSnippetTitle>Response</CodeSnippetTitle>
735
+ <CodeSnippetActions>
736
+ <CodeSnippetCopyButton />
737
+ </CodeSnippetActions>
738
+ </CodeSnippetHeader>
739
+ <CodeEditorContent lineNumbers aria-label='HTTP response, read only' />
740
+ </CodeEditorRoot>
741
+ </div>
742
+ );
743
+
744
+ /**
745
+ * Tabs swap `value`, and `documentId` swaps the editor's whole state with it, so each tab keeps
746
+ * its own undo history, selection and collapsed folds.
747
+ */
748
+ export const Tabs: StoryFn<typeof meta> = () => {
749
+ const [tab, setTab] = useState<TabId>('request');
750
+ const [docs, setDocs] = useState<Record<TabId, string>>(tabDocuments);
751
+
752
+ return (
753
+ <div style={{ width: '600px' }}>
754
+ <CodeEditorRoot
755
+ documentId={tab}
756
+ value={docs[tab]}
757
+ onChange={value => setDocs(prev => ({ ...prev, [tab]: value }))}
758
+ language='http'
759
+ data-testid='code-editor-tabs'
760
+ >
761
+ <CodeSnippetHeader>
762
+ <CodeSnippetTabs
763
+ value={tab}
764
+ onValueChange={value => {
765
+ if (isTabId(value)) setTab(value);
766
+ }}
767
+ >
768
+ <CodeSnippetTab value='request' data-testid='code-editor-tabs--tab-request'>
769
+ Request
770
+ </CodeSnippetTab>
771
+ <CodeSnippetTab value='response' data-testid='code-editor-tabs--tab-response'>
772
+ Response
773
+ </CodeSnippetTab>
774
+ </CodeSnippetTabs>
775
+ <CodeSnippetActions>
776
+ <CodeSnippetCopyButton />
777
+ </CodeSnippetActions>
778
+ </CodeSnippetHeader>
779
+ <CodeEditorContent lineNumbers aria-label='HTTP message' />
780
+ </CodeEditorRoot>
781
+ </div>
782
+ );
783
+ };
784
+
785
+ // --- Parity stories: CodeSnippet above, read-only CodeEditor below, identical props ---
786
+
787
+ interface ParityPairProps {
788
+ testId: string;
789
+ code: string;
790
+ language: CodeEditorLanguage;
791
+ lines?: Record<number, LineConfig>;
792
+ folds?: FoldRegion[];
793
+ /** Initial wrapping for both (the wrap button toggles each one) */
794
+ wrapLines?: boolean;
795
+ size?: CodeSnippetSize;
796
+ maxLines?: number;
797
+ /** Shared chrome (header, tabs, actions), rendered before the content in both roots */
798
+ children?: ReactNode;
799
+ }
800
+
801
+ const ParityPair = ({
802
+ testId,
803
+ code,
804
+ language,
805
+ lines,
806
+ folds,
807
+ wrapLines,
808
+ size,
809
+ maxLines,
810
+ children,
811
+ }: ParityPairProps) => (
812
+ <VStack gap={16}>
813
+ <VStack align='start' gap={4}>
814
+ <span className='sb-annotation'>CodeSnippet</span>
815
+ <div style={{ width: '600px' }}>
816
+ <CodeSnippetRoot
817
+ code={code}
818
+ language={language}
819
+ lines={lines}
820
+ folds={folds}
821
+ wrapLines={wrapLines}
822
+ size={size}
823
+ maxLines={maxLines}
824
+ data-testid={`${testId}-snippet`}
825
+ >
826
+ {children}
827
+ <CodeSnippetContent>
828
+ <CodeSnippetLineNumbers />
829
+ <CodeSnippetCode />
830
+ </CodeSnippetContent>
831
+ </CodeSnippetRoot>
832
+ </div>
833
+ </VStack>
834
+ <VStack align='start' gap={4}>
835
+ <span className='sb-annotation'>CodeEditor (readOnly)</span>
836
+ <div style={{ width: '600px' }}>
837
+ <CodeEditorRoot
838
+ value={code}
839
+ language={language}
840
+ lines={lines}
841
+ folds={folds}
842
+ defaultWrapLines={wrapLines}
843
+ size={size}
844
+ maxLines={maxLines}
845
+ readOnly
846
+ data-testid={`${testId}-editor`}
847
+ >
848
+ {children}
849
+ <CodeEditorContent lineNumbers aria-label='Parity editor' />
850
+ </CodeEditorRoot>
851
+ </div>
852
+ </VStack>
853
+ </VStack>
854
+ );
855
+
856
+ /** Header with tabs, a title-less tab strip and header actions — the same element in both roots. */
857
+ const PARITY_HEADER_FRAME = (
858
+ <CodeSnippetHeader>
859
+ <CodeSnippetTabs defaultValue='request'>
860
+ <CodeSnippetTab value='request'>Request</CodeSnippetTab>
861
+ <CodeSnippetTab value='response'>Response</CodeSnippetTab>
862
+ </CodeSnippetTabs>
863
+ <CodeSnippetActions>
864
+ <CodeSnippetWrapButton />
865
+ <CodeSnippetCopyButton />
866
+ <CodeSnippetFullscreenButton />
867
+ </CodeSnippetActions>
868
+ </CodeSnippetHeader>
869
+ );
870
+
871
+ /** Floating actions (no header) — the same element in both roots. */
872
+ const PARITY_FLOATING_FRAME = (
873
+ <CodeSnippetActions>
874
+ <CodeSnippetWrapButton />
875
+ <CodeSnippetCopyButton />
876
+ </CodeSnippetActions>
877
+ );
878
+
879
+ /**
880
+ * Parity check: the same code and props in CodeSnippet and in a read-only CodeEditor should look
881
+ * identical. Accepted differences: a native thin scrollbar, and CodeMirror's caret and selection
882
+ * layer (shown only while focused).
883
+ */
884
+ export const ParityDefault: StoryFn<typeof meta> = () => (
885
+ <ParityPair testId='parity-default' code={sampleCode} language='text' />
886
+ );
887
+
888
+ /**
889
+ * Parity check with line colours, text prefixes and a tooltipped icon prefix: same stick, same
890
+ * tint, same prefix column.
891
+ */
892
+ export const ParityLineColors: StoryFn<typeof meta> = () => (
893
+ <ParityPair
894
+ testId='parity-line-colors'
895
+ code={colorsCode}
896
+ language='text'
897
+ lines={parityColorLines}
898
+ />
899
+ );
900
+
901
+ /**
902
+ * Parity check with the headers fold collapsed: same chevrons and the same summary row in place
903
+ * of the hidden lines.
904
+ */
905
+ export const ParityFoldsCollapsed: StoryFn<typeof meta> = () => (
906
+ <ParityPair
907
+ testId='parity-folds-collapsed'
908
+ code={foldableRequestCode}
909
+ language='text'
910
+ folds={parityCollapsedFolds}
911
+ />
912
+ );
913
+
914
+ /**
915
+ * Parity check for an HTTP request with a JSON body, both under the same Prism provider: token
916
+ * colours come from the same adapter.
917
+ */
918
+ export const ParityHttpPrism: StoryFn<typeof meta> = () => (
919
+ <CodeSnippetAdapterProvider adapter={loadPrismAdapter}>
920
+ <ParityPair testId='parity-http-prism' code={httpRequestCode} language='http' />
921
+ </CodeSnippetAdapterProvider>
922
+ );
923
+
924
+ /**
925
+ * Parity check for `ranges`: the same bold, coloured spans inside the same tinted lines.
926
+ */
927
+ export const ParityRanges: StoryFn<typeof meta> = () => (
928
+ <ParityPair testId='parity-ranges' code={rangesCode} language='text' lines={rangeLines} />
929
+ );
930
+
931
+ /**
932
+ * Parity check for wrapped lines: long lines break at the same points and line numbers stay on
933
+ * the first row of each wrapped line.
934
+ */
935
+ export const ParityWrap: StoryFn<typeof meta> = () => (
936
+ <ParityPair testId='parity-wrap' code={longCode} language='text' wrapLines />
937
+ );
938
+
939
+ /**
940
+ * Parity check for the three sizes: the same font size, line height and gutter padding per size.
941
+ */
942
+ export const ParitySizes: StoryFn<typeof meta> = () => (
943
+ <VStack gap={24}>
944
+ <ParityPair testId='parity-size-sm' code={bashCode} language='bash' size='sm' />
945
+ <ParityPair testId='parity-size-md' code={bashCode} language='bash' size='md' />
946
+ <ParityPair testId='parity-size-lg' code={bashCode} language='bash' size='lg' />
947
+ </VStack>
948
+ );
949
+
950
+ /**
951
+ * Parity check for the shared frame: a header with tabs and actions, and floating actions
952
+ * without a header, sit in the same place with the same spacing.
953
+ */
954
+ export const ParityFrame: StoryFn<typeof meta> = () => (
955
+ <VStack gap={24}>
956
+ <ParityPair testId='parity-frame-header' code={sampleCode} language='text'>
957
+ {PARITY_HEADER_FRAME}
958
+ </ParityPair>
959
+ <ParityPair testId='parity-frame-floating' code={sampleCode} language='text'>
960
+ {PARITY_FLOATING_FRAME}
961
+ </ParityPair>
962
+ </VStack>
963
+ );
964
+
965
+ /**
966
+ * Parity check for `maxLines`: the same clamped height and the same "Show N more lines" button.
967
+ */
968
+ export const ParityShowMore: StoryFn<typeof meta> = () => (
969
+ <ParityPair testId='parity-show-more' code={showMoreCode} language='text' maxLines={7} />
970
+ );
971
+
972
+ // --- Languages ---
973
+
974
+ const PYTHON_SAMPLE = `from dataclasses import dataclass
975
+
976
+
977
+ @dataclass
978
+ class Rule:
979
+ action: str
980
+ point: list[str]
981
+ enabled: bool = True
982
+
983
+
984
+ def active(rules: list[Rule]) -> list[Rule]:
985
+ return [r for r in rules if r.enabled]
986
+ `;
987
+ const LUA_SAMPLE = `local cjson = require("cjson")
988
+
989
+ local BLOCKED = { "10.0.0.1", "10.0.0.2" }
990
+
991
+ local function check(ctx)
992
+ local ip = ngx.var.remote_addr
993
+ for _, blocked in pairs(BLOCKED) do
994
+ if ip ~= blocked then goto continue end
995
+ ngx.log(ngx.WARN, "blocked ", ip)
996
+ ngx.exit(403)
997
+ ::continue::
998
+ end
999
+ ngx.say(cjson.encode({ ok = true, count = #BLOCKED }))
1000
+ end
1001
+
1002
+ return { check = check }
1003
+ `;
1004
+ const JSON_SAMPLE = `{
1005
+ "action": "block",
1006
+ "point": ["header", "X-Forwarded-For"],
1007
+ "enabled": true,
1008
+ "threshold": 42
1009
+ }
1010
+ `;
1011
+ const JAVASCRIPT_SAMPLE = `export async function fetchRules(client, { limit = 50 } = {}) {
1012
+ const res = await client.get('/api/v2/rules', { params: { limit } });
1013
+ return res.data.filter(rule => rule.enabled);
1014
+ }
1015
+ `;
1016
+ const TYPESCRIPT_SAMPLE = `interface Rule {
1017
+ action: 'block' | 'monitor';
1018
+ point: string[];
1019
+ enabled: boolean;
1020
+ }
1021
+
1022
+ export const activeRules = (rules: readonly Rule[]): Rule[] =>
1023
+ rules.filter((rule): rule is Rule => rule.enabled);
1024
+ `;
1025
+ const YAML_SAMPLE = `rules:
1026
+ - action: block
1027
+ point: [header, X-Forwarded-For]
1028
+ enabled: true
1029
+ - action: monitor
1030
+ point: [query, id]
1031
+ enabled: false
1032
+ `;
1033
+
1034
+ interface LanguageSample {
1035
+ id: string;
1036
+ label: string;
1037
+ language: CodeEditorLanguage;
1038
+ value: string;
1039
+ }
1040
+
1041
+ const LANGUAGE_SAMPLES = [
1042
+ { id: 'python', label: 'Python', language: 'python', value: PYTHON_SAMPLE },
1043
+ { id: 'json', label: 'JSON', language: 'json', value: JSON_SAMPLE },
1044
+ { id: 'javascript', label: 'JavaScript', language: 'javascript', value: JAVASCRIPT_SAMPLE },
1045
+ { id: 'typescript', label: 'TypeScript', language: 'typescript', value: TYPESCRIPT_SAMPLE },
1046
+ { id: 'yaml', label: 'YAML', language: 'yaml', value: YAML_SAMPLE },
1047
+ { id: 'lua', label: 'Lua', language: 'lua', value: LUA_SAMPLE },
1048
+ ] as const satisfies readonly LanguageSample[];
1049
+
1050
+ const LanguageExample = ({ sample }: { sample: LanguageSample }) => {
1051
+ const [value, setValue] = useState(sample.value);
1052
+
1053
+ return (
1054
+ <VStack align='start' gap={4}>
1055
+ <span className='sb-annotation'>{sample.label}</span>
1056
+ <div style={{ width: '600px' }}>
1057
+ <CodeEditorRoot
1058
+ value={value}
1059
+ onChange={setValue}
1060
+ language={sample.language}
1061
+ data-testid={`lang-${sample.id}`}
1062
+ >
1063
+ <CodeSnippetHeader>
1064
+ <CodeSnippetTitle>{sample.label}</CodeSnippetTitle>
1065
+ <CodeSnippetActions>
1066
+ <CodeSnippetCopyButton />
1067
+ </CodeSnippetActions>
1068
+ </CodeSnippetHeader>
1069
+ <CodeEditorContent lineNumbers aria-label={`${sample.label} example`} />
1070
+ </CodeEditorRoot>
1071
+ </div>
1072
+ </VStack>
1073
+ );
1074
+ };
1075
+
1076
+ /**
1077
+ * Colours come from the adapter (Shiki here); JavaScript, TypeScript, Python and Lua parsers load
1078
+ * on first use.
1079
+ */
1080
+ export const Languages: StoryFn<typeof meta> = () => (
1081
+ <CodeSnippetAdapterProvider adapter={loadShikiAdapter}>
1082
+ <VStack gap={16}>
1083
+ {LANGUAGE_SAMPLES.map(sample => (
1084
+ <LanguageExample key={sample.id} sample={sample} />
1085
+ ))}
1086
+ </VStack>
1087
+ </CodeSnippetAdapterProvider>
1088
+ );
1089
+
1090
+ // --- Syntax errors ---
1091
+
1092
+ interface SyntaxErrorSample {
1093
+ language: CodeEditorLanguage;
1094
+ label: string;
1095
+ value: string;
1096
+ }
1097
+
1098
+ /** One intentionally broken sample per language with a structure parser. */
1099
+ const SYNTAX_ERROR_SAMPLES = [
1100
+ { language: 'json', label: 'JSON', value: '{\n "action": "block"\n "enabled": true\n}\n' },
1101
+ { language: 'yaml', label: 'YAML', value: 'rules:\n - action: block\n point: [header, id\n' },
1102
+ {
1103
+ language: 'javascript',
1104
+ label: 'JavaScript',
1105
+ value: 'function fetchRules( {\n return client.get("/api/v2/rules");\n}\n',
1106
+ },
1107
+ { language: 'typescript', label: 'TypeScript', value: 'let limit: = 50;\n' },
1108
+ { language: 'python', label: 'Python', value: 'def active(:\n pass\n' },
1109
+ { language: 'lua', label: 'Lua', value: 'local limit = = 50\nreturn limit\n' },
1110
+ {
1111
+ language: 'http',
1112
+ label: 'HTTP',
1113
+ value: 'POST /rules HTTP/1.1\nContent-Type: application/json\n\n{\n "action": "block",\n}\n',
1114
+ },
1115
+ ] as const satisfies readonly SyntaxErrorSample[];
1116
+
1117
+ const SyntaxErrorExample = ({ sample }: { sample: SyntaxErrorSample }) => {
1118
+ const [value, setValue] = useState(sample.value);
1119
+ const [diagnostics, setDiagnostics] = useState<CodeEditorDiagnostic[]>([]);
1120
+ const testId = `syntax-${sample.language}`;
1121
+
1122
+ return (
1123
+ <VStack align='start' gap={4}>
1124
+ <span className='sb-annotation'>{sample.label}</span>
1125
+ <div style={{ width: '600px' }}>
1126
+ <CodeEditorRoot
1127
+ value={value}
1128
+ onChange={setValue}
1129
+ language={sample.language}
1130
+ onDiagnosticsChange={setDiagnostics}
1131
+ data-testid={testId}
1132
+ >
1133
+ <CodeEditorContent lineNumbers aria-label={`Broken ${sample.label} example`} />
1134
+ </CodeEditorRoot>
1135
+ </div>
1136
+ <span className='sb-annotation' data-testid={`${testId}--count`}>
1137
+ {diagnostics.length === 1 ? '1 diagnostic' : `${diagnostics.length} diagnostics`}
1138
+ </span>
1139
+ </VStack>
1140
+ );
1141
+ };
1142
+
1143
+ /**
1144
+ * Syntax errors for every language with a structure parser: JSON and an HTTP JSON body use the
1145
+ * precise `JSON.parse` message, JavaScript and TypeScript use Babel, Lua uses luaparse (first error only), YAML and Python report
1146
+ * Lezer error nodes. Hover an underline to read the message; the count below each editor comes from
1147
+ * `onDiagnosticsChange`. Bash and plain text have no syntax diagnostics.
1148
+ */
1149
+ export const SyntaxErrors: StoryFn<typeof meta> = () => (
1150
+ <CodeSnippetAdapterProvider adapter={loadShikiAdapter}>
1151
+ <VStack gap={16}>
1152
+ {SYNTAX_ERROR_SAMPLES.map(sample => (
1153
+ <SyntaxErrorExample key={sample.language} sample={sample} />
1154
+ ))}
1155
+ </VStack>
1156
+ </CodeSnippetAdapterProvider>
1157
+ );
1158
+
1159
+ const DIFF_ORIGINAL = `POST /api/v2/users HTTP/1.1
1160
+ Host: api.wallarm.com
1161
+ Content-Type: application/json
1162
+ X-Request-Id: 42
1163
+
1164
+ {
1165
+ "name": "Ann",
1166
+ "role": "viewer"
1167
+ }`;
1168
+
1169
+ const DIFF_MODIFIED = `POST /api/v2/users HTTP/1.1
1170
+ Host: api.wallarm.com
1171
+ Content-Type: application/json
1172
+ Authorization: Bearer <token>
1173
+
1174
+ {
1175
+ "name": "Ann",
1176
+ "role": "admin"
1177
+ }`;
1178
+
1179
+ /**
1180
+ * `original` turns on diff mode: added and changed lines read as `success` lines with a `+`,
1181
+ * removed lines as `danger` rows with a `-` and no line number. The rows stay editable, and the
1182
+ * diff updates as you type.
1183
+ */
1184
+ export const Diff: StoryFn<typeof meta> = () => {
1185
+ const [value, setValue] = useState(DIFF_MODIFIED);
1186
+
1187
+ return (
1188
+ <CodeEditorRoot
1189
+ data-testid='code-editor-diff'
1190
+ language='http'
1191
+ original={DIFF_ORIGINAL}
1192
+ value={value}
1193
+ onChange={setValue}
1194
+ >
1195
+ <CodeEditorContent aria-label='Request draft compared with the stored request' lineNumbers />
1196
+ </CodeEditorRoot>
1197
+ );
1198
+ };
1199
+
1200
+ const DIFF_WRAP_ORIGINAL = `GET /api/v2/rules HTTP/1.1
1201
+ Host: api.wallarm.com
1202
+ X-Debug-Trace: gateway=eu-central-1;route=/api/v2/rules;upstream=rules-service;sampled=true;span=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
1203
+ Accept: application/json`;
1204
+
1205
+ const DIFF_WRAP_MODIFIED = `GET /api/v2/rules HTTP/1.1
1206
+ Host: api.wallarm.com
1207
+ Accept: application/json`;
1208
+
1209
+ /**
1210
+ * With wrapping on, a removed line longer than the frame wraps inside its `danger` row and its
1211
+ * `-` marker stays on the first visual row, beside where the line starts.
1212
+ */
1213
+ export const DiffWrapLines: StoryFn<typeof meta> = () => {
1214
+ const [value, setValue] = useState(DIFF_WRAP_MODIFIED);
1215
+
1216
+ return (
1217
+ <div className='w-480'>
1218
+ <CodeEditorRoot
1219
+ data-testid='code-editor-diff-wrap'
1220
+ language='http'
1221
+ original={DIFF_WRAP_ORIGINAL}
1222
+ value={value}
1223
+ onChange={setValue}
1224
+ defaultWrapLines
1225
+ >
1226
+ <CodeEditorContent aria-label='Request without the debug header' lineNumbers />
1227
+ </CodeEditorRoot>
1228
+ </div>
1229
+ );
1230
+ };
1231
+
1232
+ const analyticsRequest = `POST /api/v1/rules HTTP/1.1
1233
+ Host: api.example.com
1234
+ Content-Type: application/json
1235
+ Authorization: Bearer token123
1236
+
1237
+ {
1238
+ "action": "block"
1239
+ }`;
1240
+
1241
+ const analyticsFolds: FoldRegion[] = [
1242
+ {
1243
+ id: 'headers',
1244
+ startLine: 2,
1245
+ endLine: 4,
1246
+ label: 'Headers',
1247
+ toggleProps: { 'data-analytics-id': 'CODE_EDITOR_FOLD_HEADERS' },
1248
+ summaryProps: { 'data-analytics-id': 'CODE_EDITOR_EXPAND_HEADERS' },
1249
+ },
1250
+ ];
1251
+
1252
+ /**
1253
+ * Where analytics attributes land. `data-*` / `aria-*` / `id` on `CodeEditorContent`
1254
+ * reach the typing surface (`role="textbox"`), chrome buttons take them directly, and
1255
+ * fold buttons take them through `toggleProps` / `summaryProps`. Popups drawn by the
1256
+ * editor (autocomplete, tooltips, search panel) are not attributable — see
1257
+ * `CodeEditor/ANALYTICS_GAPS.md`.
1258
+ */
1259
+ export const AnalyticsAttributes: StoryFn<typeof meta> = () => (
1260
+ <CodeEditorRoot
1261
+ data-testid='analytics-editor'
1262
+ language='http'
1263
+ defaultValue={analyticsRequest}
1264
+ folds={analyticsFolds}
1265
+ >
1266
+ <CodeSnippetHeader>
1267
+ <CodeSnippetTitle>Request</CodeSnippetTitle>
1268
+ <CodeSnippetActions>
1269
+ <CodeSnippetCopyButton data-analytics-id='CODE_EDITOR_COPY' />
1270
+ <CodeSnippetWrapButton data-analytics-id='CODE_EDITOR_WRAP' />
1271
+ <CodeSnippetFullscreenButton data-analytics-id='CODE_EDITOR_FULLSCREEN' />
1272
+ </CodeSnippetActions>
1273
+ </CodeSnippetHeader>
1274
+ <CodeEditorContent
1275
+ aria-label='HTTP request'
1276
+ lineNumbers
1277
+ data-analytics-id='CODE_EDITOR_REQUEST'
1278
+ data-analytics-props='{"surface":"rule-editor"}'
1279
+ />
1280
+ </CodeEditorRoot>
1281
+ );
1282
+
1283
+ /**
1284
+ * A controlled HTTP request with header and body folds and a JSON Schema on the body —
1285
+ * `retries` breaks the schema's maximum on purpose, so the underline and its hover message
1286
+ * are part of the example. The editor's description points at `CODE_EDITOR_KEYBOARD_HINT`.
1287
+ */
1288
+ export const EditingWorkflow: StoryFn<typeof meta> = () => <EditingWorkflowDemo />;
1289
+
1290
+ /**
1291
+ * Each tab passes its own `documentId`, so switching swaps in that document's undo history,
1292
+ * selection and collapsed folds instead of replacing the text of one shared document.
1293
+ */
1294
+ export const TabsKeepHistory: StoryFn<typeof meta> = () => <TabsKeepHistoryDemo />;
1295
+
1296
+ /**
1297
+ * 2 000 read-only lines clamped by `maxLines` — the top of the envelope the colour painter is
1298
+ * built for, where `readOnly` still lets the text be selected, searched and copied.
1299
+ */
1300
+ export const LongDocument: StoryFn<typeof meta> = () => <LongDocumentDemo />;
1301
+
1302
+ /**
1303
+ * Fullscreen opened from a modal `Drawer` stacks above it: the editor and its buttons take
1304
+ * pointer and keyboard input, and Escape leaves fullscreen while the drawer stays open.
1305
+ */
1306
+ export const FullscreenInsideDrawer: StoryFn<typeof meta> = () => {
1307
+ const [value, setValue] = useState(jsonCode);
1308
+
1309
+ return (
1310
+ <Drawer>
1311
+ <DrawerTrigger asChild>
1312
+ <Button variant='outline' color='neutral'>
1313
+ Open Drawer
1314
+ </Button>
1315
+ </DrawerTrigger>
1316
+ <DrawerContent>
1317
+ <DrawerHeader>
1318
+ <DrawerTitle>Rule</DrawerTitle>
1319
+ </DrawerHeader>
1320
+ <DrawerBody>
1321
+ <CodeEditorRoot value={value} onChange={setValue} language='json'>
1322
+ <CodeSnippetHeader>
1323
+ <CodeSnippetTitle>rule.json</CodeSnippetTitle>
1324
+ <CodeSnippetActions>
1325
+ <CodeSnippetFullscreenButton />
1326
+ <CodeSnippetCopyButton />
1327
+ </CodeSnippetActions>
1328
+ </CodeSnippetHeader>
1329
+ <CodeEditorContent lineNumbers aria-label='Rule JSON' />
1330
+ </CodeEditorRoot>
1331
+ </DrawerBody>
1332
+ </DrawerContent>
1333
+ </Drawer>
1334
+ );
1335
+ };
1336
+ ```
1337
+
1338
+ ### CodeEditor/story-content/_storyEditingWorkflow.tsx
1339
+
1340
+ ```tsx
1341
+ import { type FC, useState } from 'react';
1342
+ import { CodeSnippetActions } from '../../CodeSnippet/CodeSnippetActions';
1343
+ import { CodeSnippetCopyButton } from '../../CodeSnippet/CodeSnippetCopyButton';
1344
+ import { CodeSnippetFullscreenButton } from '../../CodeSnippet/CodeSnippetFullscreenButton';
1345
+ import { CodeSnippetHeader } from '../../CodeSnippet/CodeSnippetHeader';
1346
+ import { CodeSnippetTitle } from '../../CodeSnippet/CodeSnippetTitle';
1347
+ import { CodeSnippetWrapButton } from '../../CodeSnippet/CodeSnippetWrapButton';
1348
+ import { CodeEditorContent } from '../CodeEditorContent';
1349
+ import { CodeEditorRoot } from '../CodeEditorRoot';
1350
+ import { CODE_EDITOR_KEYBOARD_HINT } from '../lib/keyboardHint';
1351
+ import { EDITING_REQUEST, httpFolds, RULE_SCHEMA } from './_storyFixtures';
1352
+
1353
+ const HINT_ID = 'code-editor-editing-workflow-hint';
1354
+
1355
+ export const EditingWorkflowDemo: FC = () => {
1356
+ const [value, setValue] = useState(EDITING_REQUEST);
1357
+
1358
+ return (
1359
+ <div className='w-640'>
1360
+ <CodeEditorRoot
1361
+ value={value}
1362
+ onChange={setValue}
1363
+ language='http'
1364
+ folds={httpFolds}
1365
+ schema={RULE_SCHEMA}
1366
+ data-testid='editing'
1367
+ >
1368
+ <CodeSnippetHeader>
1369
+ <CodeSnippetTitle>Request</CodeSnippetTitle>
1370
+ <CodeSnippetActions>
1371
+ <CodeSnippetFullscreenButton />
1372
+ <CodeSnippetWrapButton />
1373
+ <CodeSnippetCopyButton />
1374
+ </CodeSnippetActions>
1375
+ </CodeSnippetHeader>
1376
+ <CodeEditorContent lineNumbers aria-label='HTTP request' aria-describedby={HINT_ID} />
1377
+ </CodeEditorRoot>
1378
+ <span id={HINT_ID} className='sr-only'>
1379
+ {CODE_EDITOR_KEYBOARD_HINT}
1380
+ </span>
1381
+ </div>
1382
+ );
1383
+ };
1384
+
1385
+ EditingWorkflowDemo.displayName = 'EditingWorkflowDemo';
1386
+ ```
1387
+
1388
+ ### CodeEditor/story-content/_storyLongDocument.tsx
1389
+
1390
+ ```tsx
1391
+ import type { FC } from 'react';
1392
+ import { CodeEditorContent } from '../CodeEditorContent';
1393
+ import { CodeEditorRoot } from '../CodeEditorRoot';
1394
+ import { LONG_DOCUMENT } from './_storyFixtures';
1395
+
1396
+ export const LongDocumentDemo: FC = () => (
1397
+ <div className='w-640'>
1398
+ <CodeEditorRoot
1399
+ defaultValue={LONG_DOCUMENT}
1400
+ readOnly
1401
+ language='json'
1402
+ maxLines={12}
1403
+ data-testid='long-document'
1404
+ >
1405
+ <CodeEditorContent lineNumbers aria-label='Access log' />
1406
+ </CodeEditorRoot>
1407
+ </div>
1408
+ );
1409
+
1410
+ LongDocumentDemo.displayName = 'LongDocumentDemo';
1411
+ ```
1412
+
1413
+ ### CodeEditor/story-content/_storyTabsKeepHistory.tsx
1414
+
1415
+ ```tsx
1416
+ import { type FC, useState } from 'react';
1417
+ import { CodeSnippetHeader } from '../../CodeSnippet/CodeSnippetHeader';
1418
+ import { CodeSnippetTab } from '../../CodeSnippet/CodeSnippetTab';
1419
+ import { CodeSnippetTabs } from '../../CodeSnippet/CodeSnippetTabs';
1420
+ import { CodeEditorContent } from '../CodeEditorContent';
1421
+ import { CodeEditorRoot } from '../CodeEditorRoot';
1422
+ import { isTabId, TAB_DOCUMENTS, type TabId } from './_storyFixtures';
1423
+
1424
+ export const TabsKeepHistoryDemo: FC = () => {
1425
+ const [tab, setTab] = useState<TabId>('request');
1426
+ const [documents, setDocuments] = useState<Record<TabId, string>>(TAB_DOCUMENTS);
1427
+
1428
+ return (
1429
+ <div className='w-480'>
1430
+ <CodeEditorRoot
1431
+ documentId={tab}
1432
+ value={documents[tab]}
1433
+ onChange={value => setDocuments(previous => ({ ...previous, [tab]: value }))}
1434
+ language='json'
1435
+ data-testid='tabs-editor'
1436
+ >
1437
+ <CodeSnippetHeader>
1438
+ <CodeSnippetTabs
1439
+ value={tab}
1440
+ onValueChange={next => {
1441
+ if (isTabId(next)) setTab(next);
1442
+ }}
1443
+ >
1444
+ <CodeSnippetTab value='request' data-testid='tabs-editor--tab-request'>
1445
+ Request
1446
+ </CodeSnippetTab>
1447
+ <CodeSnippetTab value='response' data-testid='tabs-editor--tab-response'>
1448
+ Response
1449
+ </CodeSnippetTab>
1450
+ </CodeSnippetTabs>
1451
+ </CodeSnippetHeader>
1452
+ <CodeEditorContent lineNumbers aria-label='Rule check payload' />
1453
+ </CodeEditorRoot>
1454
+ </div>
1455
+ );
1456
+ };
1457
+
1458
+ TabsKeepHistoryDemo.displayName = 'TabsKeepHistoryDemo';
1459
+ ```
1460
+
1461
+ ### CodeEditor/story-content/_storyFixtures.ts
1462
+
1463
+ ```tsx
1464
+ import { getHttpFolds } from '../../CodeSnippet/lib/httpFolds';
1465
+ import type { CodeEditorFolds, JsonSchema } from '../types';
1466
+
1467
+ /**
1468
+ * Line map the E2E suite relies on (`CodeEditor.e2e.ts`): 1 start line, 2 `Host`,
1469
+ * 4 `X-Env: staging`, 7 `"name"`, 9 `"retries": 9` (breaks the schema maximum),
1470
+ * 10 a line longer than the frame. `staging` appears exactly twice (lines 4 and 8).
1471
+ */
1472
+ export const EDITING_REQUEST = [
1473
+ 'POST /api/v1/rules HTTP/1.1',
1474
+ 'Host: api.wallarm.example',
1475
+ 'Content-Type: application/json',
1476
+ 'X-Env: staging',
1477
+ '',
1478
+ '{',
1479
+ ' "name": "Block scanners",',
1480
+ ' "env": "staging",',
1481
+ ' "retries": 9,',
1482
+ ' "description": "Blocks requests from known vulnerability scanners on every public endpoint of the API gateway, including the legacy routes kept only for older mobile clients"',
1483
+ '}',
1484
+ ].join('\n');
1485
+
1486
+ /** Applies to the JSON body of `EDITING_REQUEST`. Module-level so its identity is stable. */
1487
+ export const RULE_SCHEMA: JsonSchema = {
1488
+ type: 'object',
1489
+ required: ['name', 'env'],
1490
+ properties: {
1491
+ name: { type: 'string', title: 'Rule name' },
1492
+ env: { enum: ['staging', 'production'], description: 'Where the rule is deployed.' },
1493
+ retries: {
1494
+ type: 'integer',
1495
+ minimum: 0,
1496
+ maximum: 5,
1497
+ description: 'How many times a failed check is retried.',
1498
+ },
1499
+ description: { type: 'string' },
1500
+ },
1501
+ };
1502
+
1503
+ /** Headers and body folds recomputed from the edited value (stable reference). */
1504
+ export const httpFolds: CodeEditorFolds = (value, { startingLineNumber }) =>
1505
+ getHttpFolds(value, { startingLineNumber });
1506
+
1507
+ export type TabId = 'request' | 'response';
1508
+
1509
+ export const isTabId = (value: string): value is TabId =>
1510
+ value === 'request' || value === 'response';
1511
+
1512
+ /** Line 3 of each document ends with a quoted string the E2E suite edits. */
1513
+ export const TAB_DOCUMENTS: Record<TabId, string> = {
1514
+ request: ['{', ' "action": "block",', ' "path": "/login"', '}'].join('\n'),
1515
+ response: ['{', ' "status": 403,', ' "reason": "blocked"', '}'].join('\n'),
1516
+ };
1517
+
1518
+ const LONG_DOCUMENT_EVENTS = 1996;
1519
+
1520
+ /** Exactly 2 000 lines — the top of the adapter painter's performance envelope. */
1521
+ export const LONG_DOCUMENT = [
1522
+ '{',
1523
+ ' "events": [',
1524
+ ...Array.from({ length: LONG_DOCUMENT_EVENTS }, (_, index) => {
1525
+ const id = index + 1;
1526
+ const status = id % 7 === 0 ? 403 : 200;
1527
+ const comma = id === LONG_DOCUMENT_EVENTS ? '' : ',';
1528
+ return ` { "id": ${id}, "method": "GET", "path": "/api/v1/items/${id}", "status": ${status} }${comma}`;
1529
+ }),
1530
+ ' ]',
1531
+ '}',
1532
+ ].join('\n');
1533
+ ```