@fortanix/baklava 1.0.0-beta-20241114

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 (454) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/LICENSE +373 -0
  3. package/README.md +43 -0
  4. package/app/Demo.tsx +33 -0
  5. package/app/index.html +12 -0
  6. package/app/lib.ts +54 -0
  7. package/app/main.tsx +32 -0
  8. package/dist/baklava.d.ts +752 -0
  9. package/dist/baklava.js +4962 -0
  10. package/dist/lib.css +1 -0
  11. package/package.json +102 -0
  12. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-100.woff2 +0 -0
  13. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-200.woff2 +0 -0
  14. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-300.woff2 +0 -0
  15. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-500.woff2 +0 -0
  16. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-600.woff2 +0 -0
  17. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-700.woff2 +0 -0
  18. package/src/assets/fonts/montserrat/montserrat-v25-latin_latin-ext-regular.woff2 +0 -0
  19. package/src/assets/fonts/open-sans/open-sans-v23-latin-600.woff2 +0 -0
  20. package/src/assets/fonts/open-sans/open-sans-v23-latin-700.woff2 +0 -0
  21. package/src/assets/fonts/open-sans/open-sans-v23-latin-regular.woff2 +0 -0
  22. package/src/assets/fonts/source-code-pro/source-code-pro-v14-latin-regular.woff2 +0 -0
  23. package/src/assets/icons/_icons.ts +58 -0
  24. package/src/assets/icons/accounts.svg +11 -0
  25. package/src/assets/icons/alert.svg +3 -0
  26. package/src/assets/icons/apache.svg +3 -0
  27. package/src/assets/icons/apps.svg +5 -0
  28. package/src/assets/icons/assessment.svg +11 -0
  29. package/src/assets/icons/audit-log.svg +12 -0
  30. package/src/assets/icons/authentication.svg +12 -0
  31. package/src/assets/icons/calendar.svg +10 -0
  32. package/src/assets/icons/caret-down.svg +3 -0
  33. package/src/assets/icons/check.svg +3 -0
  34. package/src/assets/icons/cloud-accounts.svg +15 -0
  35. package/src/assets/icons/copy.svg +4 -0
  36. package/src/assets/icons/cross.svg +4 -0
  37. package/src/assets/icons/dashboard.svg +12 -0
  38. package/src/assets/icons/dataverse.svg +12 -0
  39. package/src/assets/icons/delete.svg +5 -0
  40. package/src/assets/icons/docs.svg +10 -0
  41. package/src/assets/icons/download.svg +11 -0
  42. package/src/assets/icons/edit-params.svg +3 -0
  43. package/src/assets/icons/edit.svg +10 -0
  44. package/src/assets/icons/email.svg +3 -0
  45. package/src/assets/icons/eye.svg +11 -0
  46. package/src/assets/icons/file-error.svg +17 -0
  47. package/src/assets/icons/file.svg +15 -0
  48. package/src/assets/icons/folder.svg +14 -0
  49. package/src/assets/icons/fortanix-ki.svg +13 -0
  50. package/src/assets/icons/graph.svg +9 -0
  51. package/src/assets/icons/groups.svg +10 -0
  52. package/src/assets/icons/hide.svg +3 -0
  53. package/src/assets/icons/home.svg +11 -0
  54. package/src/assets/icons/iam.svg +11 -0
  55. package/src/assets/icons/info.svg +4 -0
  56. package/src/assets/icons/infrastructure.svg +5 -0
  57. package/src/assets/icons/integrations.svg +3 -0
  58. package/src/assets/icons/key-link.svg +12 -0
  59. package/src/assets/icons/key.svg +4 -0
  60. package/src/assets/icons/no-login.svg +10 -0
  61. package/src/assets/icons/page-forward.svg +4 -0
  62. package/src/assets/icons/plugins.svg +4 -0
  63. package/src/assets/icons/policy.svg +13 -0
  64. package/src/assets/icons/print.svg +11 -0
  65. package/src/assets/icons/scripts.svg +4 -0
  66. package/src/assets/icons/search.svg +3 -0
  67. package/src/assets/icons/security-object.svg +5 -0
  68. package/src/assets/icons/services.svg +10 -0
  69. package/src/assets/icons/settings.svg +12 -0
  70. package/src/assets/icons/solutions.svg +3 -0
  71. package/src/assets/icons/success.svg +3 -0
  72. package/src/assets/icons/tasks.svg +10 -0
  73. package/src/assets/icons/user-profile.svg +3 -0
  74. package/src/assets/icons/user.svg +10 -0
  75. package/src/assets/icons/warning.svg +3 -0
  76. package/src/assets/icons/workflows.svg +11 -0
  77. package/src/assets/icons_new/Accounts.svg +11 -0
  78. package/src/assets/icons_new/Alert.svg +3 -0
  79. package/src/assets/icons_new/Apache.svg +3 -0
  80. package/src/assets/icons_new/Apps.svg +5 -0
  81. package/src/assets/icons_new/Assessment.svg +11 -0
  82. package/src/assets/icons_new/Audit Log.svg +12 -0
  83. package/src/assets/icons_new/Authentication.svg +12 -0
  84. package/src/assets/icons_new/Calendar.svg +10 -0
  85. package/src/assets/icons_new/Carrot Down.svg +3 -0
  86. package/src/assets/icons_new/Cloud Accounts.svg +15 -0
  87. package/src/assets/icons_new/Copy.svg +4 -0
  88. package/src/assets/icons_new/Dashboard.svg +12 -0
  89. package/src/assets/icons_new/Dataverse.svg +12 -0
  90. package/src/assets/icons_new/Delete.svg +5 -0
  91. package/src/assets/icons_new/Docs.svg +10 -0
  92. package/src/assets/icons_new/Download.svg +11 -0
  93. package/src/assets/icons_new/Edit Params.svg +3 -0
  94. package/src/assets/icons_new/Edit.svg +10 -0
  95. package/src/assets/icons_new/Email.svg +3 -0
  96. package/src/assets/icons_new/Eye.svg +11 -0
  97. package/src/assets/icons_new/Groups.svg +10 -0
  98. package/src/assets/icons_new/Hide.svg +3 -0
  99. package/src/assets/icons_new/Home.svg +11 -0
  100. package/src/assets/icons_new/IAM.svg +11 -0
  101. package/src/assets/icons_new/Info.svg +4 -0
  102. package/src/assets/icons_new/Infrastructure.svg +5 -0
  103. package/src/assets/icons_new/Integrations.svg +3 -0
  104. package/src/assets/icons_new/KI.svg +13 -0
  105. package/src/assets/icons_new/Key Link.svg +12 -0
  106. package/src/assets/icons_new/Key.svg +4 -0
  107. package/src/assets/icons_new/No Login.svg +10 -0
  108. package/src/assets/icons_new/Page FWD.svg +4 -0
  109. package/src/assets/icons_new/Plugins.svg +4 -0
  110. package/src/assets/icons_new/Policy.svg +13 -0
  111. package/src/assets/icons_new/Print.svg +11 -0
  112. package/src/assets/icons_new/Scripts.svg +4 -0
  113. package/src/assets/icons_new/Search.svg +3 -0
  114. package/src/assets/icons_new/Security Objects.svg +5 -0
  115. package/src/assets/icons_new/Services.svg +10 -0
  116. package/src/assets/icons_new/Settings.svg +12 -0
  117. package/src/assets/icons_new/Solutions.svg +3 -0
  118. package/src/assets/icons_new/Tasks.svg +10 -0
  119. package/src/assets/icons_new/User Account.svg +3 -0
  120. package/src/assets/icons_new/Users.svg +10 -0
  121. package/src/assets/icons_new/Workflows.svg +11 -0
  122. package/src/assets/icons_old/_icons.ts +172 -0
  123. package/src/assets/icons_old/account.svg +4 -0
  124. package/src/assets/icons_old/accounts.svg +4 -0
  125. package/src/assets/icons_old/add.svg +4 -0
  126. package/src/assets/icons_old/alert.svg +4 -0
  127. package/src/assets/icons_old/app.svg +4 -0
  128. package/src/assets/icons_old/arrow-drop-down.svg +4 -0
  129. package/src/assets/icons_old/arrow-drop-up.svg +4 -0
  130. package/src/assets/icons_old/arrow-expand.svg +4 -0
  131. package/src/assets/icons_old/arrow-left.svg +5 -0
  132. package/src/assets/icons_old/arrow-right.svg +4 -0
  133. package/src/assets/icons_old/audit-log.svg +4 -0
  134. package/src/assets/icons_old/bell.svg +4 -0
  135. package/src/assets/icons_old/billing.svg +4 -0
  136. package/src/assets/icons_old/bug.svg +4 -0
  137. package/src/assets/icons_old/builds.svg +4 -0
  138. package/src/assets/icons_old/calendar.svg +4 -0
  139. package/src/assets/icons_old/certificate.svg +4 -0
  140. package/src/assets/icons_old/check.svg +4 -0
  141. package/src/assets/icons_old/checkbox-checked.svg +4 -0
  142. package/src/assets/icons_old/checkbox-disabled.svg +4 -0
  143. package/src/assets/icons_old/checkbox-unchecked.svg +4 -0
  144. package/src/assets/icons_old/chevron-left.svg +4 -0
  145. package/src/assets/icons_old/chevron-right.svg +4 -0
  146. package/src/assets/icons_old/clear-all.svg +4 -0
  147. package/src/assets/icons_old/color-picker.svg +10 -0
  148. package/src/assets/icons_old/connection.svg +4 -0
  149. package/src/assets/icons_old/copy.svg +4 -0
  150. package/src/assets/icons_old/cross-thin.svg +4 -0
  151. package/src/assets/icons_old/cross.svg +4 -0
  152. package/src/assets/icons_old/crypto-policy.svg +4 -0
  153. package/src/assets/icons_old/customers.svg +4 -0
  154. package/src/assets/icons_old/dashboard.svg +4 -0
  155. package/src/assets/icons_old/data-center.svg +4 -0
  156. package/src/assets/icons_old/data-connector-read.svg +6 -0
  157. package/src/assets/icons_old/data-connector-write.svg +6 -0
  158. package/src/assets/icons_old/dataset.svg +3 -0
  159. package/src/assets/icons_old/dataverse.svg +6 -0
  160. package/src/assets/icons_old/delete.svg +4 -0
  161. package/src/assets/icons_old/deployment-deployed.svg +4 -0
  162. package/src/assets/icons_old/deployment-none.svg +4 -0
  163. package/src/assets/icons_old/derive.svg +4 -0
  164. package/src/assets/icons_old/docs.svg +4 -0
  165. package/src/assets/icons_old/document-blank.svg +4 -0
  166. package/src/assets/icons_old/domain.svg +4 -0
  167. package/src/assets/icons_old/download-cloud.svg +4 -0
  168. package/src/assets/icons_old/download.svg +4 -0
  169. package/src/assets/icons_old/edit-params.svg +4 -0
  170. package/src/assets/icons_old/edit.svg +4 -0
  171. package/src/assets/icons_old/em-app.svg +4 -0
  172. package/src/assets/icons_old/em-dashboard.svg +4 -0
  173. package/src/assets/icons_old/email.svg +4 -0
  174. package/src/assets/icons_old/empty-credential.svg +4 -0
  175. package/src/assets/icons_old/enterprise-badge.svg +6 -0
  176. package/src/assets/icons_old/environment-production.svg +4 -0
  177. package/src/assets/icons_old/environment-test.svg +4 -0
  178. package/src/assets/icons_old/event-critical.svg +4 -0
  179. package/src/assets/icons_old/event-error.svg +4 -0
  180. package/src/assets/icons_old/event-success.svg +4 -0
  181. package/src/assets/icons_old/event-warning.svg +4 -0
  182. package/src/assets/icons_old/expiration.svg +4 -0
  183. package/src/assets/icons_old/export.svg +4 -0
  184. package/src/assets/icons_old/external.svg +4 -0
  185. package/src/assets/icons_old/eye-closed.svg +4 -0
  186. package/src/assets/icons_old/eye.svg +4 -0
  187. package/src/assets/icons_old/file.svg +7 -0
  188. package/src/assets/icons_old/flag.svg +4 -0
  189. package/src/assets/icons_old/forbid.svg +4 -0
  190. package/src/assets/icons_old/fortanix-app-aci.svg +6 -0
  191. package/src/assets/icons_old/fortanix-app-edp.svg +4 -0
  192. package/src/assets/icons_old/fortanix-app-enclave-os.svg +4 -0
  193. package/src/assets/icons_old/frame-expand.svg +4 -0
  194. package/src/assets/icons_old/fresh.svg +4 -0
  195. package/src/assets/icons_old/generated.svg +4 -0
  196. package/src/assets/icons_old/gift.svg +4 -0
  197. package/src/assets/icons_old/global.svg +4 -0
  198. package/src/assets/icons_old/group.svg +4 -0
  199. package/src/assets/icons_old/help.svg +4 -0
  200. package/src/assets/icons_old/home-info.svg +5 -0
  201. package/src/assets/icons_old/home.svg +4 -0
  202. package/src/assets/icons_old/horizontal-collapse.svg +5 -0
  203. package/src/assets/icons_old/horizontal-expand.svg +5 -0
  204. package/src/assets/icons_old/hsm.svg +4 -0
  205. package/src/assets/icons_old/info.svg +4 -0
  206. package/src/assets/icons_old/install.svg +4 -0
  207. package/src/assets/icons_old/integration.svg +7 -0
  208. package/src/assets/icons_old/key-clone.svg +4 -0
  209. package/src/assets/icons_old/key-custodian-policy.svg +10 -0
  210. package/src/assets/icons_old/key-destroy.svg +4 -0
  211. package/src/assets/icons_old/key-download.svg +4 -0
  212. package/src/assets/icons_old/key-justification-policy.svg +5 -0
  213. package/src/assets/icons_old/key-link.svg +4 -0
  214. package/src/assets/icons_old/key-metadata-policy.svg +5 -0
  215. package/src/assets/icons_old/key-primary.svg +11 -0
  216. package/src/assets/icons_old/key-remove.svg +4 -0
  217. package/src/assets/icons_old/key-rotation.svg +4 -0
  218. package/src/assets/icons_old/key-undo-policy.svg +10 -0
  219. package/src/assets/icons_old/key-wrapping.svg +6 -0
  220. package/src/assets/icons_old/key.svg +4 -0
  221. package/src/assets/icons_old/leave-account.svg +4 -0
  222. package/src/assets/icons_old/link.svg +4 -0
  223. package/src/assets/icons_old/lock-closed.svg +4 -0
  224. package/src/assets/icons_old/lock.svg +4 -0
  225. package/src/assets/icons_old/locked-user.svg +4 -0
  226. package/src/assets/icons_old/marketplace.svg +4 -0
  227. package/src/assets/icons_old/minus.svg +4 -0
  228. package/src/assets/icons_old/monitoring.svg +4 -0
  229. package/src/assets/icons_old/no-logging.svg +4 -0
  230. package/src/assets/icons_old/node-cluster.svg +4 -0
  231. package/src/assets/icons_old/node.svg +4 -0
  232. package/src/assets/icons_old/operations.svg +13 -0
  233. package/src/assets/icons_old/options.svg +4 -0
  234. package/src/assets/icons_old/play.svg +4 -0
  235. package/src/assets/icons_old/plug.svg +4 -0
  236. package/src/assets/icons_old/plugin-clone.svg +4 -0
  237. package/src/assets/icons_old/plugin.svg +4 -0
  238. package/src/assets/icons_old/plugins.svg +4 -0
  239. package/src/assets/icons_old/pod.svg +4 -0
  240. package/src/assets/icons_old/print.svg +4 -0
  241. package/src/assets/icons_old/projects.svg +11 -0
  242. package/src/assets/icons_old/python.svg +4 -0
  243. package/src/assets/icons_old/quorum.svg +4 -0
  244. package/src/assets/icons_old/refresh.svg +4 -0
  245. package/src/assets/icons_old/regenerate.svg +4 -0
  246. package/src/assets/icons_old/region.svg +4 -0
  247. package/src/assets/icons_old/reports.svg +3 -0
  248. package/src/assets/icons_old/request-approve.svg +4 -0
  249. package/src/assets/icons_old/request-decline.svg +4 -0
  250. package/src/assets/icons_old/reseller.svg +4 -0
  251. package/src/assets/icons_old/script.svg +7 -0
  252. package/src/assets/icons_old/search.svg +4 -0
  253. package/src/assets/icons_old/service-account.svg +4 -0
  254. package/src/assets/icons_old/settings.svg +4 -0
  255. package/src/assets/icons_old/sidebar-closed.svg +8 -0
  256. package/src/assets/icons_old/sidebar-open.svg +8 -0
  257. package/src/assets/icons_old/sign-out.svg +4 -0
  258. package/src/assets/icons_old/sign.svg +4 -0
  259. package/src/assets/icons_old/software.svg +4 -0
  260. package/src/assets/icons_old/sql-aggregate.svg +7 -0
  261. package/src/assets/icons_old/sql.svg +7 -0
  262. package/src/assets/icons_old/stack.svg +4 -0
  263. package/src/assets/icons_old/star-empty.svg +4 -0
  264. package/src/assets/icons_old/star-fill.svg +4 -0
  265. package/src/assets/icons_old/subscription.svg +5 -0
  266. package/src/assets/icons_old/support.svg +11 -0
  267. package/src/assets/icons_old/switcher.svg +4 -0
  268. package/src/assets/icons_old/sysadmin.svg +4 -0
  269. package/src/assets/icons_old/tag.svg +4 -0
  270. package/src/assets/icons_old/target.svg +4 -0
  271. package/src/assets/icons_old/tasks.svg +4 -0
  272. package/src/assets/icons_old/tfa-user.svg +4 -0
  273. package/src/assets/icons_old/tfa.svg +4 -0
  274. package/src/assets/icons_old/tokenization.svg +4 -0
  275. package/src/assets/icons_old/tools.svg +4 -0
  276. package/src/assets/icons_old/transition-from.svg +4 -0
  277. package/src/assets/icons_old/transition-to.svg +4 -0
  278. package/src/assets/icons_old/upload.svg +4 -0
  279. package/src/assets/icons_old/user-remove.svg +3 -0
  280. package/src/assets/icons_old/user.svg +4 -0
  281. package/src/assets/icons_old/view-type-cards.svg +4 -0
  282. package/src/assets/icons_old/view-type-list.svg +4 -0
  283. package/src/assets/icons_old/view-type-table.svg +4 -0
  284. package/src/assets/icons_old/warning.svg +4 -0
  285. package/src/assets/icons_old/workflow.svg +3 -0
  286. package/src/assets/icons_old/wrap.svg +4 -0
  287. package/src/assets/icons_old/wrench.svg +4 -0
  288. package/src/assets/images/fortanix_logo_icon.svg +20 -0
  289. package/src/components/actions/Button/Button.module.scss +81 -0
  290. package/src/components/actions/Button/Button.stories.tsx +262 -0
  291. package/src/components/actions/Button/Button.tsx +133 -0
  292. package/src/components/actions/ButtonAsLink/ButtonAsLink.module.scss +13 -0
  293. package/src/components/actions/ButtonAsLink/ButtonAsLink.stories.tsx +49 -0
  294. package/src/components/actions/ButtonAsLink/ButtonAsLink.tsx +56 -0
  295. package/src/components/actions/Link/Link.module.scss +38 -0
  296. package/src/components/actions/Link/Link.stories.tsx +54 -0
  297. package/src/components/actions/Link/Link.tsx +59 -0
  298. package/src/components/actions/LinkAsButton/LinkAsButton.stories.tsx +70 -0
  299. package/src/components/actions/LinkAsButton/LinkAsButton.tsx +59 -0
  300. package/src/components/containers/Alert/Alert.module.scss +41 -0
  301. package/src/components/containers/Alert/Alert.stories.tsx +47 -0
  302. package/src/components/containers/Alert/Alert.tsx +65 -0
  303. package/src/components/containers/Banner/Banner.module.scss +100 -0
  304. package/src/components/containers/Banner/Banner.stories.tsx +198 -0
  305. package/src/components/containers/Banner/Banner.tsx +121 -0
  306. package/src/components/containers/Card/Card.module.scss +32 -0
  307. package/src/components/containers/Card/Card.stories.tsx +67 -0
  308. package/src/components/containers/Card/Card.tsx +48 -0
  309. package/src/components/containers/Dialog/Dialog.module.scss +166 -0
  310. package/src/components/containers/Dialog/Dialog.stories.tsx +32 -0
  311. package/src/components/containers/Dialog/Dialog.tsx +130 -0
  312. package/src/components/containers/Panel/Panel.module.scss +32 -0
  313. package/src/components/containers/Panel/Panel.stories.tsx +46 -0
  314. package/src/components/containers/Panel/Panel.tsx +48 -0
  315. package/src/components/forms/context/Form/Form.module.scss +11 -0
  316. package/src/components/forms/context/Form/Form.stories.tsx +99 -0
  317. package/src/components/forms/context/Form/Form.tsx +106 -0
  318. package/src/components/forms/context/Form/FormOptics.tsx +109 -0
  319. package/src/components/forms/context/SubmitButton/SubmitButton.module.scss +9 -0
  320. package/src/components/forms/context/SubmitButton/SubmitButton.stories.tsx +132 -0
  321. package/src/components/forms/context/SubmitButton/SubmitButton.tsx +98 -0
  322. package/src/components/forms/controls/Checkbox/Checkbox.module.scss +67 -0
  323. package/src/components/forms/controls/Checkbox/Checkbox.stories.tsx +119 -0
  324. package/src/components/forms/controls/Checkbox/Checkbox.tsx +53 -0
  325. package/src/components/forms/controls/Input/Input.module.scss +40 -0
  326. package/src/components/forms/controls/Input/Input.stories.tsx +55 -0
  327. package/src/components/forms/controls/Input/Input.tsx +44 -0
  328. package/src/components/forms/controls/SegmentedControl/SegmentedControl.module.scss +76 -0
  329. package/src/components/forms/controls/SegmentedControl/SegmentedControl.stories.tsx +92 -0
  330. package/src/components/forms/controls/SegmentedControl/SegmentedControl.tsx +103 -0
  331. package/src/components/forms/controls/Select/Select.module.scss +105 -0
  332. package/src/components/forms/controls/Select/Select.stories.tsx +43 -0
  333. package/src/components/forms/controls/Select/Select.tsx +166 -0
  334. package/src/components/forms/controls/Switch/Switch.module.scss +63 -0
  335. package/src/components/forms/controls/Switch/Switch.stories.tsx +50 -0
  336. package/src/components/forms/controls/Switch/Switch.tsx +46 -0
  337. package/src/components/forms/fields/CheckboxField/CheckboxField.module.scss +46 -0
  338. package/src/components/forms/fields/CheckboxField/CheckboxField.stories.tsx +74 -0
  339. package/src/components/forms/fields/CheckboxField/CheckboxField.tsx +118 -0
  340. package/src/components/forms/fields/CheckboxGroup/CheckboxGroup.module.scss +22 -0
  341. package/src/components/forms/fields/CheckboxGroup/CheckboxGroup.stories.tsx +36 -0
  342. package/src/components/forms/fields/CheckboxGroup/CheckboxGroup.tsx +37 -0
  343. package/src/components/forms/fields/InputField/InputField.module.scss +24 -0
  344. package/src/components/forms/fields/InputField/InputField.stories.tsx +57 -0
  345. package/src/components/forms/fields/InputField/InputField.tsx +72 -0
  346. package/src/components/graphics/Icon/Icon.module.scss +42 -0
  347. package/src/components/graphics/Icon/Icon.stories.tsx +67 -0
  348. package/src/components/graphics/Icon/Icon.tsx +50 -0
  349. package/src/components/graphics/PlaceholderEmpty/PlaceholderEmpty.module.scss +76 -0
  350. package/src/components/graphics/PlaceholderEmpty/PlaceholderEmpty.stories.tsx +101 -0
  351. package/src/components/graphics/PlaceholderEmpty/PlaceholderEmpty.tsx +91 -0
  352. package/src/components/graphics/ProgressBar/ProgressBar.module.scss +43 -0
  353. package/src/components/graphics/ProgressBar/ProgressBar.stories.tsx +70 -0
  354. package/src/components/graphics/ProgressBar/ProgressBar.tsx +58 -0
  355. package/src/components/graphics/Spinner/Spinner.module.scss +61 -0
  356. package/src/components/graphics/Spinner/Spinner.stories.tsx +56 -0
  357. package/src/components/graphics/Spinner/Spinner.tsx +41 -0
  358. package/src/components/lists/PropertyList/PropertyList.module.scss +33 -0
  359. package/src/components/lists/PropertyList/PropertyList.stories.tsx +45 -0
  360. package/src/components/lists/PropertyList/PropertyList.tsx +60 -0
  361. package/src/components/navigations/Stepper/Stepper.module.scss +88 -0
  362. package/src/components/navigations/Stepper/Stepper.stories.tsx +68 -0
  363. package/src/components/navigations/Stepper/Stepper.tsx +95 -0
  364. package/src/components/navigations/Tabs/Tabs.module.scss +71 -0
  365. package/src/components/navigations/Tabs/Tabs.stories.tsx +106 -0
  366. package/src/components/navigations/Tabs/Tabs.tsx +121 -0
  367. package/src/components/overlays/DropdownMenu/DropdownMenu.module.scss +113 -0
  368. package/src/components/overlays/DropdownMenu/DropdownMenu.stories.tsx +91 -0
  369. package/src/components/overlays/DropdownMenu/DropdownMenu.tsx +155 -0
  370. package/src/components/overlays/DropdownMenu/DropdownMenuProvider.module.scss +105 -0
  371. package/src/components/overlays/DropdownMenu/DropdownMenuProvider.stories.tsx +71 -0
  372. package/src/components/overlays/DropdownMenu/DropdownMenuProvider.tsx +168 -0
  373. package/src/components/overlays/Modal/Modal.module.scss +185 -0
  374. package/src/components/overlays/Modal/Modal.stories.tsx +144 -0
  375. package/src/components/overlays/Modal/Modal.tsx +202 -0
  376. package/src/components/overlays/Toast/Toast.module.scss +123 -0
  377. package/src/components/overlays/Toast/Toast.stories.tsx +219 -0
  378. package/src/components/overlays/Toast/Toast.tsx +233 -0
  379. package/src/components/overlays/Toast/ToastyOverride.scss +27 -0
  380. package/src/components/overlays/Tooltip/Tooltip.module.scss +162 -0
  381. package/src/components/overlays/Tooltip/Tooltip.stories.tsx +115 -0
  382. package/src/components/overlays/Tooltip/Tooltip.tsx +75 -0
  383. package/src/components/overlays/Tooltip/TooltipProvider.stories.tsx +169 -0
  384. package/src/components/overlays/Tooltip/TooltipProvider.tsx +164 -0
  385. package/src/components/util/Clipboard/Clipboard.tsx +11 -0
  386. package/src/components/util/Popover/Popover.tsx +219 -0
  387. package/src/docs/Changelog.mdx +7 -0
  388. package/src/docs/Colors.mdx +113 -0
  389. package/src/docs/Colors.module.scss +56 -0
  390. package/src/docs/Iconography.mdx +70 -0
  391. package/src/docs/Iconography.module.scss +37 -0
  392. package/src/docs/Introduction.mdx +26 -0
  393. package/src/docs/Typography.mdx +109 -0
  394. package/src/docs/Typography.module.scss +22 -0
  395. package/src/layouts/AppLayout/AppLayout.module.scss +110 -0
  396. package/src/layouts/AppLayout/AppLayout.stories.tsx +112 -0
  397. package/src/layouts/AppLayout/AppLayout.tsx +31 -0
  398. package/src/layouts/AppLayout/Breadcrumbs/Breadcrumbs.module.scss +47 -0
  399. package/src/layouts/AppLayout/Breadcrumbs/Breadcrumbs.stories.tsx +66 -0
  400. package/src/layouts/AppLayout/Breadcrumbs/Breadcrumbs.tsx +63 -0
  401. package/src/layouts/AppLayout/Header/AccountSelector.module.scss +24 -0
  402. package/src/layouts/AppLayout/Header/AccountSelector.stories.tsx +31 -0
  403. package/src/layouts/AppLayout/Header/AccountSelector.tsx +51 -0
  404. package/src/layouts/AppLayout/Header/Header.module.scss +74 -0
  405. package/src/layouts/AppLayout/Header/Header.stories.tsx +30 -0
  406. package/src/layouts/AppLayout/Header/Header.tsx +31 -0
  407. package/src/layouts/AppLayout/Header/SolutionSelector.module.scss +24 -0
  408. package/src/layouts/AppLayout/Header/SolutionSelector.stories.tsx +31 -0
  409. package/src/layouts/AppLayout/Header/SolutionSelector.tsx +50 -0
  410. package/src/layouts/AppLayout/Header/UserMenu.module.scss +31 -0
  411. package/src/layouts/AppLayout/Header/UserMenu.stories.tsx +32 -0
  412. package/src/layouts/AppLayout/Header/UserMenu.tsx +67 -0
  413. package/src/layouts/AppLayout/Logo/Logo.module.scss +78 -0
  414. package/src/layouts/AppLayout/Logo/Logo.tsx +38 -0
  415. package/src/layouts/AppLayout/Nav/Nav.module.scss +73 -0
  416. package/src/layouts/AppLayout/Nav/Nav.stories.tsx +32 -0
  417. package/src/layouts/AppLayout/Nav/Nav.tsx +75 -0
  418. package/src/layouts/AppLayout/Sidebar/Sidebar.module.scss +46 -0
  419. package/src/layouts/AppLayout/Sidebar/Sidebar.stories.tsx +30 -0
  420. package/src/layouts/AppLayout/Sidebar/Sidebar.tsx +33 -0
  421. package/src/layouts/FormLayout/FormLayout.module.scss +19 -0
  422. package/src/layouts/FormLayout/FormLayout.stories.tsx +64 -0
  423. package/src/layouts/FormLayout/FormLayout.tsx +32 -0
  424. package/src/styling/accessibility.css +24 -0
  425. package/src/styling/context/theming.scss +26 -0
  426. package/src/styling/context/theming_mixins.scss +79 -0
  427. package/src/styling/defs.scss +60 -0
  428. package/src/styling/fonts.css +126 -0
  429. package/src/styling/fonts_mixins.scss +16 -0
  430. package/src/styling/global.scss +49 -0
  431. package/src/styling/lib/normalize.css +78 -0
  432. package/src/styling/lib/reset-custom.css +58 -0
  433. package/src/styling/lib/reset.css +115 -0
  434. package/src/styling/main.scss +29 -0
  435. package/src/styling/variables.css +18 -0
  436. package/src/styling/variables.scss +928 -0
  437. package/src/styling/variables.ts +64 -0
  438. package/src/types/globals.d.ts +14 -0
  439. package/src/types/vite-env.d.ts +1 -0
  440. package/src/typography/BodyText/BodyText.mixins.scss +224 -0
  441. package/src/typography/BodyText/BodyText.module.scss +28 -0
  442. package/src/typography/BodyText/BodyText.stories.tsx +109 -0
  443. package/src/typography/BodyText/BodyText.tsx +30 -0
  444. package/src/typography/Heading/Heading.mixins.scss +42 -0
  445. package/src/typography/Heading/Heading.module.scss +15 -0
  446. package/src/typography/Heading/Heading.stories.tsx +112 -0
  447. package/src/typography/Heading/Heading.tsx +57 -0
  448. package/src/util/componentUtil.ts +19 -0
  449. package/src/util/drag.ts +197 -0
  450. package/src/util/reactUtil.ts +40 -0
  451. package/src/util/storybook/OverflowTester.css +13 -0
  452. package/src/util/storybook/OverflowTester.tsx +30 -0
  453. package/src/util/time.ts +12 -0
  454. package/src/util/types.ts +8 -0
@@ -0,0 +1,130 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ import { classNames as cx, type ClassNameArgument } from '../../../util/componentUtil.ts';
6
+ import * as React from 'react';
7
+
8
+ import { Button } from '../../actions/Button/Button.tsx';
9
+
10
+ import cl from './Dialog.module.scss';
11
+
12
+
13
+ export { cl as DialogClassNames };
14
+
15
+ /*
16
+ const useClickOutside = <E extends HTMLElement>(ref: React.RefObject<E>, callback: () => void) => {
17
+ const handleEvent = React.useCallback((event: React.PointerEvent<E>) => {
18
+ if (ref && ref.current) {
19
+ if (ref.current.contains(event.target as Node)) {
20
+ React.setState({ hasClickedOutside: false });
21
+ } else {
22
+ React.setState({ hasClickedOutside: true });
23
+ }
24
+ }
25
+ }, [ref]);
26
+
27
+ React.useEffect(() => {
28
+ if (!window.PointerEvent) { return; }
29
+
30
+ document.addEventListener('pointerdown', handleEvent);
31
+
32
+ return () => {
33
+ if (window.PointerEvent) {
34
+ document.removeEventListener('pointerdown', handleEvent);
35
+ } else {
36
+ document.removeEventListener('mousedown', handleEvent);
37
+ document.removeEventListener('touchstart', handleEvent);
38
+ }
39
+ }
40
+ }, []);
41
+
42
+ return [ref, hasClickedOutside];
43
+ };
44
+ */
45
+
46
+
47
+ export type DialogProps = React.PropsWithChildren<{
48
+ unstyled?: boolean,
49
+ active: boolean,
50
+ className?: ClassNameArgument,
51
+ onClose: () => void,
52
+ }>;
53
+
54
+ /**
55
+ * Dialog component.
56
+ */
57
+ export const Dialog = ({ children, unstyled, className, active, onClose }: DialogProps) => {
58
+ const dialogRef = React.useRef<HTMLDialogElement>(null);
59
+
60
+ /*
61
+ // Sync the `active` flag with the DOM dialog
62
+ React.useEffect(() => {
63
+ const dialog = dialogRef.current;
64
+ if (dialog === null) { return; }
65
+
66
+ if (active && !dialog.open) {
67
+ dialog.showDialog();
68
+ } else if (!active && dialog.open) {
69
+ dialog.close();
70
+ }
71
+ }, [active]);
72
+ */
73
+
74
+ // Sync the dialog close event with the `active` flag
75
+ const handleCloseEvent = React.useCallback((event: Event): void => {
76
+ const dialog = dialogRef.current;
77
+ if (dialog === null) { return; }
78
+
79
+ if (active && event.target === dialog) {
80
+ onClose();
81
+ }
82
+ }, [active, onClose]);
83
+ React.useEffect(() => {
84
+ const dialog = dialogRef.current;
85
+ if (dialog === null) { return; }
86
+
87
+ dialog.addEventListener('close', handleCloseEvent);
88
+ return () => { dialog.removeEventListener('close', handleCloseEvent); };
89
+ }, [handleCloseEvent]);
90
+
91
+ const close = React.useCallback(() => {
92
+ onClose();
93
+ }, [onClose]);
94
+
95
+ const handleDialogClick = React.useCallback((event: React.MouseEvent) => {
96
+ const dialog = dialogRef.current;
97
+ if (dialog !== null && event.target === dialog) {
98
+ // Note: clicking the backdrop just results in an event where the target is the `<dialog>` element. In order to
99
+ // distinguish between the backdrop and the dialog content, we assume that the `<dialog>` is fully covered by
100
+ // another element. In our case, `bk-dialog__content` must cover the whole `<dialog>` otherwise this will not work.
101
+ close();
102
+ }
103
+ }, [close]);
104
+
105
+ return (
106
+ <dialog
107
+ open
108
+ ref={dialogRef}
109
+ className={cx({
110
+ bk: true,
111
+ [cl['bk-dialog']]: !unstyled,
112
+ }, className)}
113
+ onClick={handleDialogClick}
114
+ >
115
+ <header className={cl['bk-dialog__header']}>
116
+ <h1>Title</h1>
117
+ {/* <button autoFocus className="action" onClick={close}>✕</button> */}
118
+ </header>
119
+
120
+ <section className={cx(cl['bk-dialog__content'], 'body-text')}>
121
+ {children}
122
+ </section>
123
+
124
+ <footer className={cx(cl['bk-dialog__actions'])}>
125
+ <Button autoFocus variant="secondary" label="Cancel"/>
126
+ <Button variant="primary" label="Submit"/>
127
+ </footer>
128
+ </dialog>
129
+ );
130
+ };
@@ -0,0 +1,32 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ @use '../../../styling/defs.scss' as bk;
6
+
7
+ @mixin bk-panel($name: bk-panel) {
8
+ --bk-panel-background-color: #{bk.$theme-card-background-default};
9
+ --bk-panel-border-color: #{bk.$theme-card-border-default};
10
+
11
+ overflow: hidden;
12
+
13
+ min-height: 4rem;
14
+ padding: 22px 26px;
15
+ background: var(--bk-panel-background-color);
16
+ border: 1px solid var(--bk-panel-border-color);
17
+ border-radius: 6px;
18
+ }
19
+
20
+
21
+ @layer baklava.components {
22
+ .bk-panel {
23
+ @include bk.component-base(bk-panel);
24
+ @include bk-panel;
25
+
26
+ .bk-panel__heading {
27
+ margin-bottom: 0.8lh;
28
+ text-wrap: nowrap;
29
+ text-overflow: ellipsis;
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,46 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+
7
+ import type { Meta, StoryObj } from '@storybook/react';
8
+
9
+ import { Alert } from '../Alert/Alert.tsx';
10
+
11
+ import { Panel } from './Panel.tsx';
12
+
13
+
14
+ type PanelArgs = React.ComponentProps<typeof Panel>;
15
+ type Story = StoryObj<typeof Panel>;
16
+
17
+ export default {
18
+ component: Panel,
19
+ parameters: {
20
+ layout: 'padded',
21
+ design: { type: 'figma', url: 'https://www.figma.com/embed?embed_host=share&url=https%3A%2F%2Fwww.figma.com%2Fdesign%2FnOF5w9LfPiJabQD5yPzCEp%2F2024-Design-System-UX%3Fnode-id%3D41%253A4484%26t%3DaJEqUzt6fUeABwmK-1' },
22
+ },
23
+ tags: ['autodocs'],
24
+ argTypes: {},
25
+ args: {
26
+ unstyled: false,
27
+ children: <Panel.Heading>Panel</Panel.Heading>,
28
+ },
29
+ render: (args) => <Panel {...args}/>,
30
+ } satisfies Meta<PanelArgs>;
31
+
32
+
33
+ export const Standard: Story = {};
34
+
35
+ /** Multiple panels stacked. */
36
+ export const Stacked: Story = {
37
+ render: (args) => (
38
+ <div style={{ display: 'flex', flexFlow: 'column', gap: '1.2rem' }}>
39
+ <Alert kind="info">
40
+ Panels have no margin by default. Use a flex/grid container to space the panels.
41
+ </Alert>
42
+ <Panel {...args}><Panel.Heading>Panel 1</Panel.Heading></Panel>
43
+ <Panel {...args}><Panel.Heading>Panel 2</Panel.Heading></Panel>
44
+ </div>
45
+ ),
46
+ };
@@ -0,0 +1,48 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as React from 'react';
6
+ import { classNames as cx, type ComponentProps } from '../../../util/componentUtil.ts';
7
+
8
+ import { H4 } from '../../../typography/Heading/Heading.tsx';
9
+
10
+ import cl from './Panel.module.scss';
11
+
12
+
13
+ export { cl as PanelClassNames };
14
+
15
+
16
+ export type PanelHeadingProps = React.PropsWithChildren<ComponentProps<typeof H4>>;
17
+ export const PanelHeading = (props: PanelHeadingProps) => {
18
+ return <H4 {...props} className={cx(cl['bk-panel__heading'], props.className)}/>;
19
+ };
20
+
21
+ export type PanelProps = React.PropsWithChildren<ComponentProps<'section'> & {
22
+ /** Whether this component should be unstyled. */
23
+ unstyled?: undefined | boolean,
24
+ }>;
25
+ /**
26
+ * Panel component.
27
+ */
28
+ export const Panel = Object.assign(
29
+ (props: PanelProps) => {
30
+ const { children, unstyled = false, ...propsRest } = props;
31
+
32
+ return (
33
+ <section
34
+ {...propsRest}
35
+ className={cx(
36
+ 'bk',
37
+ { [cl['bk-panel']]: !unstyled },
38
+ propsRest.className,
39
+ )}
40
+ >
41
+ {children}
42
+ </section>
43
+ );
44
+ },
45
+ {
46
+ Heading: PanelHeading,
47
+ },
48
+ );
@@ -0,0 +1,11 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ @use '../../../../styling/defs.scss' as bk;
6
+
7
+ @layer baklava.components {
8
+ .bk-form {
9
+ @include bk.component-base(bk-form);
10
+ }
11
+ }
@@ -0,0 +1,99 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ import type { Meta, StoryObj } from '@storybook/react';
6
+
7
+ import * as React from 'react';
8
+ import { useFormStatus } from 'react-dom';
9
+
10
+ import { Panel } from '../../../containers/Panel/Panel.tsx';
11
+ import { InputField } from '../../fields/InputField/InputField.tsx';
12
+ import { SubmitButton } from '../SubmitButton/SubmitButton.tsx';
13
+ import { FormLayout } from '../../../../layouts/FormLayout/FormLayout.tsx';
14
+
15
+ import { useFormContext, Form } from './Form.tsx';
16
+
17
+
18
+ type FormArgs = React.ComponentProps<typeof Form>;
19
+ type Story = StoryObj<FormArgs>;
20
+
21
+ const FormWithState = (props: React.ComponentProps<typeof Form>) => {
22
+ const action = async (previousState: unknown, formData: FormData) => {
23
+ if (typeof props.action === 'function') {
24
+ return props.action?.(formData);
25
+ }
26
+ return null;
27
+ };
28
+
29
+ const [state, formAction] = React.useActionState(action, null);
30
+
31
+ // const formDataCached = React.useRef<null | FormData>(null);
32
+ // React.useEffect(() => {
33
+ // if (formStatus.data !== null) {
34
+ // formDataCached.current = formStatus.data;
35
+ // }
36
+ // }, [formStatus.data]);
37
+
38
+ return (
39
+ <Form {...props} action={formAction}>
40
+ {state &&
41
+ <Panel className="bk-body-text">
42
+ Submitted data:
43
+ {' '}
44
+ <pre>{JSON.stringify(state, null, 2)}</pre>
45
+ </Panel>
46
+ }
47
+ {props.children}
48
+ </Form>
49
+ );
50
+ };
51
+
52
+ export default {
53
+ component: Form,
54
+ parameters: {
55
+ layout: 'centered',
56
+ },
57
+ tags: ['autodocs'],
58
+ argTypes: {
59
+ },
60
+ args: {
61
+ children: 'Example',
62
+ },
63
+ render: (args) => (
64
+ <FormWithState {...args}>
65
+ <FormLayout>
66
+ {args.children}
67
+ </FormLayout>
68
+ </FormWithState>
69
+ ),
70
+ } satisfies Meta<FormArgs>;
71
+
72
+
73
+ export const Standard: Story = {
74
+ name: 'Form',
75
+ args: {
76
+ //nestable: true,
77
+ //onSubmit: (event) => { event.preventDefault(); console.log('submit', event); },
78
+ action: (formData) => {
79
+ //console.log('action', formData.get('field-1'));
80
+ return [...formData.entries()].reduce(
81
+ (acc, [fieldKey, field]) => {
82
+ if (Object.hasOwn(acc, fieldKey)) {
83
+ console.warn(`Found duplicate entries for key ${fieldKey}`);
84
+ }
85
+ acc[fieldKey] = field;
86
+ return acc;
87
+ },
88
+ {} as Record<string, unknown>,
89
+ );
90
+ },
91
+ children: (
92
+ <>
93
+ <InputField label="Field 1" name="field-1" placeholder="Example"/>
94
+ <InputField label="Field 2" name="field-2" placeholder="Example"/>
95
+ <SubmitButton/>
96
+ </>
97
+ ),
98
+ },
99
+ };
@@ -0,0 +1,106 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ import { classNames as cx, type ComponentProps } from '../../../../util/componentUtil.ts';
6
+ import * as React from 'react';
7
+ import { createPortal } from 'react-dom';
8
+
9
+ import cl from './Form.module.scss';
10
+
11
+
12
+ export { cl as FormClassNames };
13
+
14
+
15
+ export type FormContext = {
16
+ formId: string,
17
+ };
18
+ export const FormContext = React.createContext<null | FormContext>(null);
19
+ export const useFormContext = (): FormContext => {
20
+ const formContext = React.use(FormContext);
21
+ if (formContext === null) { throw new Error(`Missing FormContext provider`); }
22
+ return formContext;
23
+ };
24
+
25
+
26
+ export type FormProps = React.PropsWithChildren<ComponentProps<'form'> & {
27
+ /** Whether this component should be unstyled. */
28
+ unstyled?: undefined | boolean,
29
+
30
+ /** Whether this form should be nestable (i.e. can contain other `<form>` elements). */
31
+ nestable?: undefined | boolean,
32
+ }>;
33
+ /**
34
+ * Top-level form wrapper component.
35
+ */
36
+ export const Form = (props: FormProps) => {
37
+ const { unstyled = false, nestable, children, className, ...propsRest } = props;
38
+
39
+ const formId = React.useId();
40
+ const [wrapperRef, setWrapperRef] = React.useState<null | React.ComponentRef<'div'>>(null);
41
+
42
+ // Memoize to keep a stable reference
43
+ const context: FormContext = React.useMemo(() => ({ formId }), [formId]);
44
+
45
+ const renderForm = ({ children }: { children: React.ReactNode }) => {
46
+ return (
47
+ <form
48
+ // Use POST by default to prevent (potentially sensitive) parameters from being leaked through GET params.
49
+ // Note: if `action` is a function, then React overrides `method` anyway (and React complains if it's set).
50
+ method={typeof propsRest.action === 'function' ? undefined : 'post'}
51
+ {...propsRest}
52
+ id={formId} // Do not allow override of `id` (breaks functionality)
53
+ onSubmit={(event) => {
54
+ // We support client only at the moment, so we want to always prevent default browser form submit behavior.
55
+ event.preventDefault();
56
+
57
+ propsRest.onSubmit?.(event);
58
+
59
+ React.startTransition(async () => {
60
+ // Optionally, we can clear the form for uncontrolled components, like default browser behavior. See:
61
+ // https://github.com/facebook/react/pull/29019
62
+ // https://github.com/facebook/react/issues/29034
63
+ //React.requestFormReset(event.target);
64
+
65
+ if (typeof propsRest.action === 'function') {
66
+ // Call the user-provided action
67
+ const formData = new FormData(event.target as HTMLFormElement);
68
+ await propsRest.action(formData);
69
+ }
70
+ });
71
+ }}
72
+ {...nestable
73
+ ? { hidden: true }
74
+ : {
75
+ className: cx({
76
+ bk: true,
77
+ [cl['bk-form']]: !unstyled,
78
+ }, className)
79
+ }
80
+ }
81
+ >
82
+ <FormContext.Provider value={context}>
83
+ {children}
84
+ </FormContext.Provider>
85
+ </form>
86
+ );
87
+ };
88
+
89
+ if (nestable) {
90
+ return (
91
+ <div
92
+ ref={setWrapperRef}
93
+ className={cx({
94
+ bk: true,
95
+ [cl['bk-form']]: !unstyled,
96
+ }, className)}
97
+ >
98
+ {wrapperRef &&
99
+ renderForm({ children: createPortal(children, wrapperRef) })
100
+ }
101
+ </div>
102
+ );
103
+ }
104
+
105
+ return renderForm({ children });
106
+ };
@@ -0,0 +1,109 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ import * as O from 'optics-ts';
6
+
7
+ import { classNames as cx, type ComponentProps } from '../../../../util/componentUtil.ts';
8
+ import * as React from 'react';
9
+ import { createPortal } from 'react-dom';
10
+
11
+ import cl from './Form.module.scss';
12
+
13
+
14
+ export { cl as FormClassNames };
15
+
16
+
17
+ export type FormContext<T> = {
18
+ formId: string,
19
+ accessor: O.OpticFor<T>,
20
+ };
21
+ export const FormContext = React.createContext<null | FormContext<unknown>>(null);
22
+ export const useFormContext = <T,>(): FormContext<T> => {
23
+ const formContext = React.use(FormContext);
24
+ if (formContext === null) { throw new Error(`Missing FormContext provider`); }
25
+ return formContext as FormContext<T>;
26
+ };
27
+
28
+
29
+ export type FormProps = React.PropsWithChildren<ComponentProps<'form'> & {
30
+ /** Whether this component should be unstyled. */
31
+ unstyled?: undefined | boolean,
32
+
33
+ /** Whether this form should be nestable (i.e. can contain other `<form>` elements). */
34
+ nestable?: undefined | boolean,
35
+ }>;
36
+ /**
37
+ * Top-level form wrapper component.
38
+ */
39
+ export const Form = (props: FormProps) => {
40
+ const { unstyled = false, nestable, children, className, ...propsRest } = props;
41
+
42
+ const formId = React.useId();
43
+ const [wrapperRef, setWrapperRef] = React.useState<null | React.ComponentRef<'div'>>(null);
44
+
45
+ // Memoize to keep a stable reference
46
+ const context: FormContext = React.useMemo(() => ({ formId }), [formId]);
47
+
48
+ const renderForm = ({ children }: { children: React.ReactNode }) => {
49
+ return (
50
+ <form
51
+ // Use POST by default to prevent (potentially sensitive) parameters from being leaked through GET params.
52
+ // Note: if `action` is a function, then React overrides `method` anyway (and React complains if it's set).
53
+ method={typeof propsRest.action === 'function' ? undefined : 'post'}
54
+ {...propsRest}
55
+ id={formId} // Do not allow override of `id` (breaks functionality)
56
+ onSubmit={(event) => {
57
+ // We support client only at the moment, so we want to always prevent default browser form submit behavior.
58
+ event.preventDefault();
59
+
60
+ propsRest.onSubmit?.(event);
61
+
62
+ React.startTransition(async () => {
63
+ // Optionally, we can clear the form for uncontrolled components, like default browser behavior. See:
64
+ // https://github.com/facebook/react/pull/29019
65
+ // https://github.com/facebook/react/issues/29034
66
+ //React.requestFormReset(event.target);
67
+
68
+ if (typeof propsRest.action === 'function') {
69
+ // Call the user-provided action
70
+ const formData = new FormData(event.target as HTMLFormElement);
71
+ await propsRest.action(formData);
72
+ }
73
+ });
74
+ }}
75
+ {...nestable
76
+ ? { hidden: true }
77
+ : {
78
+ className: cx({
79
+ bk: true,
80
+ [cl['bk-form']]: !unstyled,
81
+ }, className)
82
+ }
83
+ }
84
+ >
85
+ <FormContext.Provider value={context}>
86
+ {children}
87
+ </FormContext.Provider>
88
+ </form>
89
+ );
90
+ };
91
+
92
+ if (nestable) {
93
+ return (
94
+ <div
95
+ ref={setWrapperRef}
96
+ className={cx({
97
+ bk: true,
98
+ [cl['bk-form']]: !unstyled,
99
+ }, className)}
100
+ >
101
+ {wrapperRef &&
102
+ renderForm({ children: createPortal(children, wrapperRef) })
103
+ }
104
+ </div>
105
+ );
106
+ }
107
+
108
+ return renderForm({ children });
109
+ };
@@ -0,0 +1,9 @@
1
+ /* Copyright (c) Fortanix, Inc.
2
+ |* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
3
+ |* the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
+
5
+ @use '../../../../styling/defs.scss' as bk;
6
+
7
+ @layer baklava.components {
8
+ /* empty */
9
+ }