@protobase/ui 0.25.2 → 0.25.4

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 (271) hide show
  1. package/dist/account/account-pages.js +3 -2
  2. package/dist/account/account-section.js +1 -1
  3. package/dist/account/account-security-page.js +9 -4
  4. package/dist/account/backup-codes.js +7 -6
  5. package/dist/account/messages.js +214 -0
  6. package/dist/account/passkeys-section.js +23 -22
  7. package/dist/account/password-dialog.js +4 -3
  8. package/dist/account/sign-in-policy-form.js +14 -13
  9. package/dist/account/sign-in-policy-labels.js +30 -29
  10. package/dist/account/sign-in-policy-page.js +11 -6
  11. package/dist/account/sign-in-providers-section.js +6 -5
  12. package/dist/account/staff-sign-in-log.js +11 -10
  13. package/dist/account/totp-qr.js +2 -1
  14. package/dist/account/two-factor-section.js +24 -23
  15. package/dist/account/two-factor-setup.js +19 -18
  16. package/dist/action-card/action-card.js +2 -1
  17. package/dist/action-card/field-list.js +1 -1
  18. package/dist/action-card/messages.js +8 -0
  19. package/dist/activity-chart/activity-chart.js +3 -2
  20. package/dist/activity-chart/messages.js +14 -0
  21. package/dist/app/app.d.ts +1 -1
  22. package/dist/app/app.js +20 -21
  23. package/dist/app/assistant-shell.js +2 -1
  24. package/dist/app/batch-failure.js +2 -1
  25. package/dist/app/breadcrumb-for.js +4 -3
  26. package/dist/app/charts/chart-groups.js +3 -2
  27. package/dist/app/charts/chart-view.js +3 -2
  28. package/dist/app/charts/group-bars.js +2 -1
  29. package/dist/app/charts/messages.js +26 -0
  30. package/dist/app/charts/period-chart.js +3 -2
  31. package/dist/app/charts/split-points.js +2 -1
  32. package/dist/app/comments/comment-composer.js +19 -18
  33. package/dist/app/comments/comments-section.js +4 -3
  34. package/dist/app/comments/messages.js +26 -0
  35. package/dist/app/create/create-page.js +11 -18
  36. package/dist/app/custom-section.js +4 -6
  37. package/dist/app/displays/board-column.js +7 -6
  38. package/dist/app/displays/board-columns.js +3 -2
  39. package/dist/app/displays/board-display.js +13 -15
  40. package/dist/app/displays/calendar-controls.js +3 -2
  41. package/dist/app/displays/calendar-display.js +12 -17
  42. package/dist/app/displays/card-carousel.js +4 -3
  43. package/dist/app/displays/cards-display.js +2 -1
  44. package/dist/app/displays/custom-display.js +4 -6
  45. package/dist/app/displays/display-frame.js +3 -2
  46. package/dist/app/displays/list-cards.js +5 -8
  47. package/dist/app/displays/list-displays.js +3 -3
  48. package/dist/app/displays/map-display.js +15 -14
  49. package/dist/app/displays/messages.js +128 -2
  50. package/dist/app/displays/period-controls.js +4 -3
  51. package/dist/app/displays/record-card.js +7 -6
  52. package/dist/app/displays/timeline-display.js +17 -26
  53. package/dist/app/displays/timeline-range.js +2 -1
  54. package/dist/app/displays/timeline-row.js +1 -1
  55. package/dist/app/displays/use-board-move.js +2 -2
  56. package/dist/app/displays/use-calendar-move.js +2 -1
  57. package/dist/app/document-title.js +2 -1
  58. package/dist/app/error-banner.js +1 -1
  59. package/dist/app/export/builder-port.js +2 -1
  60. package/dist/app/export/export-dialog.js +39 -43
  61. package/dist/app/export/export-worker.js +2 -0
  62. package/dist/app/export/messages.js +78 -0
  63. package/dist/app/export/run-export.js +5 -2
  64. package/dist/app/export/sink.js +4 -3
  65. package/dist/app/export/use-export-flow.js +4 -3
  66. package/dist/app/field-editor.js +4 -3
  67. package/dist/app/field-types/messages.js +8 -0
  68. package/dist/app/field-types/widget-part.js +2 -1
  69. package/dist/app/file-field.js +11 -14
  70. package/dist/app/gallery/gallery-section.js +4 -3
  71. package/dist/app/gallery/lightbox.js +5 -4
  72. package/dist/app/gallery/messages.js +30 -0
  73. package/dist/app/gallery/photo-details.js +3 -2
  74. package/dist/app/hand-order/hand-sorted-list.js +3 -6
  75. package/dist/app/hand-order/messages.js +4 -2
  76. package/dist/app/history/describe-change.js +3 -8
  77. package/dist/app/history/messages.js +32 -0
  78. package/dist/app/import/convert.js +20 -19
  79. package/dist/app/import/failed-rows.js +3 -2
  80. package/dist/app/import/import-button.js +2 -1
  81. package/dist/app/import/import-check-step.js +21 -37
  82. package/dist/app/import/import-dialog.js +13 -17
  83. package/dist/app/import/import-file-step.js +5 -9
  84. package/dist/app/import/import-mapping-step.js +32 -35
  85. package/dist/app/import/import-result-step.js +13 -12
  86. package/dist/app/import/messages.js +200 -0
  87. package/dist/app/import/parse-worker.js +2 -0
  88. package/dist/app/import/prepare-rows.js +5 -4
  89. package/dist/app/import/sheet-cell.js +2 -1
  90. package/dist/app/import/sheet-file.js +3 -2
  91. package/dist/app/import/sheet-source.js +7 -3
  92. package/dist/app/import/xlsx-reader.js +4 -3
  93. package/dist/app/import/xlsx-xml.js +2 -1
  94. package/dist/app/import/zip-reader.js +4 -3
  95. package/dist/app/list-edit/use-list-edits.js +1 -1
  96. package/dist/app/list-group-chart.js +2 -1
  97. package/dist/app/list-page.js +1 -1
  98. package/dist/app/map/map-layer-switch.js +3 -2
  99. package/dist/app/map/messages.js +14 -0
  100. package/dist/app/messages.js +116 -2
  101. package/dist/app/meta-gate.js +1 -1
  102. package/dist/app/nav-from-meta.js +11 -10
  103. package/dist/app/pages/action-inputs/action-inputs-dialog.js +3 -2
  104. package/dist/app/pages/action-inputs/input-answers.js +6 -5
  105. package/dist/app/pages/blocks/card-row.js +3 -2
  106. package/dist/app/pages/blocks/field.js +1 -1
  107. package/dist/app/pages/blocks/modal-form.js +5 -4
  108. package/dist/app/pages/blocks/progress.js +1 -1
  109. package/dist/app/pages/blocks/record-card.js +3 -2
  110. package/dist/app/pages/blocks/stat.js +2 -1
  111. package/dist/app/pages/composed-page.js +6 -8
  112. package/dist/app/pages/confirm-action.js +2 -1
  113. package/dist/app/pages/custom-boundary.js +4 -2
  114. package/dist/app/pages/messages.js +64 -0
  115. package/dist/app/pages/render-node.js +5 -7
  116. package/dist/app/pages/use-run-action.js +11 -10
  117. package/dist/app/record-page.js +1 -1
  118. package/dist/app/record-row/messages.js +26 -0
  119. package/dist/app/record-row/record-row-body.js +12 -7
  120. package/dist/app/record-row/record-row.js +4 -3
  121. package/dist/app/record-row/saved-record-row.js +3 -2
  122. package/dist/app/related-dots/dots-summary.js +2 -1
  123. package/dist/app/related-dots/messages.js +8 -0
  124. package/dist/app/relation-picker.js +9 -8
  125. package/dist/app/router.js +5 -4
  126. package/dist/app/runtime/messages.js +58 -0
  127. package/dist/app/runtime/runtime-status.js +10 -23
  128. package/dist/app/runtime/runtime-update-dialog.js +7 -6
  129. package/dist/app/runtime/runtime-update.js +4 -3
  130. package/dist/app/saved/favorite-button.js +2 -1
  131. package/dist/app/saved/messages.js +22 -0
  132. package/dist/app/saved/saved-list.js +4 -7
  133. package/dist/app/saved/use-favorite.js +3 -2
  134. package/dist/app/search/messages.js +6 -2
  135. package/dist/app/search/navigation-hits.js +9 -7
  136. package/dist/app/searches/filter-chip-list.js +2 -1
  137. package/dist/app/searches/messages.js +96 -0
  138. package/dist/app/searches/save-search-button.js +5 -4
  139. package/dist/app/searches/saved-search-rows.js +3 -2
  140. package/dist/app/searches/saved-search-section.js +6 -5
  141. package/dist/app/searches/saved-search.js +4 -3
  142. package/dist/app/searches/saved-searches.js +15 -25
  143. package/dist/app/searches/search-controls.js +5 -4
  144. package/dist/app/searches/search-diff.js +4 -2
  145. package/dist/app/searches/search-name-dialog.js +4 -3
  146. package/dist/app/searches/update-search-dialog.js +15 -30
  147. package/dist/app/searches/use-save-search.js +8 -7
  148. package/dist/app/searches/use-search-row.js +4 -3
  149. package/dist/app/sensitive-field.js +5 -4
  150. package/dist/app/source-notice.js +13 -8
  151. package/dist/app/staff-banner.js +13 -20
  152. package/dist/app-shell/global-search.js +2 -2
  153. package/dist/app-shell/messages.js +4 -2
  154. package/dist/app-shell/sidebar-group.js +1 -1
  155. package/dist/app-shell/sidebar-item.js +1 -1
  156. package/dist/app-shell/sidebar.js +1 -1
  157. package/dist/assistant-dock/assistant-dock.js +6 -6
  158. package/dist/assistant-dock/messages.js +26 -0
  159. package/dist/assistant-dock/use-assistant.js +2 -1
  160. package/dist/assistant-dock/use-backend-data.js +2 -1
  161. package/dist/assistant-dock/widget-view.js +3 -2
  162. package/dist/auth/auth-gate.js +10 -5
  163. package/dist/auth/auth-locale.js +14 -0
  164. package/dist/auth/auth-messages.js +122 -43
  165. package/dist/auth/auth-provider.js +6 -1
  166. package/dist/auth/code-form.js +4 -3
  167. package/dist/auth/email-code-form.js +11 -13
  168. package/dist/auth/email-code-page.js +2 -1
  169. package/dist/auth/first-run-page.js +6 -5
  170. package/dist/auth/forgot-password-form.js +15 -17
  171. package/dist/auth/forgot-password-page.js +2 -1
  172. package/dist/auth/messages.js +200 -0
  173. package/dist/auth/provider-sign-in-page.js +5 -5
  174. package/dist/auth/resend-code-button.js +2 -1
  175. package/dist/auth/reset-password-form.js +12 -11
  176. package/dist/auth/reset-password-page.js +4 -3
  177. package/dist/auth/setup-required-form.js +8 -10
  178. package/dist/auth/setup-required-page.js +7 -2
  179. package/dist/auth/sign-in-form.js +18 -21
  180. package/dist/auth/sign-in-prompt.js +4 -3
  181. package/dist/auth/sign-up-code-form.js +11 -13
  182. package/dist/auth/sign-up-details-form.js +15 -22
  183. package/dist/auth/sign-up-email-form.js +9 -8
  184. package/dist/auth/sign-up-page.js +2 -1
  185. package/dist/auth/staff-sign-in-form.js +16 -19
  186. package/dist/auth/two-factor-form.js +19 -18
  187. package/dist/auth/user-to-shell.js +2 -1
  188. package/dist/chat/composer.js +8 -7
  189. package/dist/chat/messages.js +14 -0
  190. package/dist/compact-table/compact-table.js +4 -8
  191. package/dist/compact-table/messages.js +18 -0
  192. package/dist/data/meta-data.d.ts +1 -1
  193. package/dist/data/use-update-record.js +1 -1
  194. package/dist/data-grid/grid-header.js +1 -1
  195. package/dist/filter-panel/date-presets.js +1 -1
  196. package/dist/forms/public-form-page.js +1 -1
  197. package/dist/inline-child-table/inline-child-table.js +12 -12
  198. package/dist/inline-child-table/line-row.js +10 -9
  199. package/dist/inline-child-table/messages.js +52 -0
  200. package/dist/inline-child-table/totals-footer.js +5 -8
  201. package/dist/invitations/invite-form.js +3 -2
  202. package/dist/invitations/link-notice.js +6 -4
  203. package/dist/invitations/messages.js +24 -0
  204. package/dist/invitations/pending-invitation-row.js +4 -3
  205. package/dist/lists/messages.js +8 -0
  206. package/dist/lists/paged-search-list.js +2 -1
  207. package/dist/locale/slotted.js +14 -0
  208. package/dist/markdown/markdown-editor.js +6 -5
  209. package/dist/markdown/messages.js +16 -0
  210. package/dist/organizations/all-organizations.js +6 -5
  211. package/dist/organizations/app-roles-picker.js +2 -1
  212. package/dist/organizations/invitation-page.js +41 -51
  213. package/dist/organizations/invitations-page.js +11 -10
  214. package/dist/organizations/members-page.js +16 -11
  215. package/dist/organizations/messages.js +180 -0
  216. package/dist/organizations/organization-page.js +27 -26
  217. package/dist/organizations/organization-paths.js +16 -13
  218. package/dist/organizations/organization-row.js +3 -2
  219. package/dist/organizations/organizations-page.js +17 -16
  220. package/dist/organizations/use-organizations.js +2 -1
  221. package/dist/package.js +1 -1
  222. package/dist/plugins/before-sign-in.js +6 -1
  223. package/dist/plugins/load-plugin.d.ts +1 -1
  224. package/dist/plugins/load-plugin.js +3 -2
  225. package/dist/plugins/messages.js +36 -0
  226. package/dist/plugins/plugin-gate.js +6 -1
  227. package/dist/plugins/plugin-manifest.js +8 -7
  228. package/dist/plugins/plugin-notice.js +8 -12
  229. package/dist/primitives/button.js +1 -1
  230. package/dist/primitives/messages.js +16 -0
  231. package/dist/primitives/segmented.js +1 -1
  232. package/dist/primitives/sheet.js +2 -1
  233. package/dist/primitives/spinner.js +2 -1
  234. package/dist/primitives/token.js +2 -1
  235. package/dist/record-view/field.js +2 -2
  236. package/dist/record-view/messages.js +4 -2
  237. package/dist/record-view/record-tabs.js +2 -1
  238. package/dist/roles/messages.js +14 -0
  239. package/dist/roles/use-active-role.js +3 -2
  240. package/dist/shell/assets/app-yCMYvqMX.js +69 -0
  241. package/dist/shell/assets/cn-Bi0ZEjD9.js +1 -0
  242. package/dist/shell/assets/export-worker-ClACk00b.js +2 -0
  243. package/dist/shell/assets/{index-BRkDA5KD.css → index-Bkc7w8I4.css} +1 -1
  244. package/dist/shell/assets/{index-xY0Mvv6V.js → index-HkjqX_O-.js} +2 -2
  245. package/dist/shell/assets/maplibre-DUTS_eJM.js +814 -0
  246. package/dist/shell/assets/{markdown-content-ukDTCu6u.js → markdown-content-CtGUP4W6.js} +1 -1
  247. package/dist/shell/assets/parse-worker-UhbwEjS0.js +5 -0
  248. package/dist/shell/assets/preload-helper-BZ3hrQDD.js +1 -0
  249. package/dist/shell/assets/{record-map-BJmYZ7kQ.js → record-map-DFy7sJEU.js} +1 -1
  250. package/dist/shell/assets/records-map-MfQEuiFB.js +1 -0
  251. package/dist/shell/assets/shared-protobase-ui-Bfa59vx6.js +1 -0
  252. package/dist/shell/index.html +6 -4
  253. package/dist/shell/protobase.shell.json +1 -1
  254. package/dist/shell/protobase.sw.js +2 -2
  255. package/dist/side-panel/messages.js +8 -0
  256. package/dist/side-panel/side-panel.js +2 -1
  257. package/dist/toasts/messages.js +8 -0
  258. package/dist/toasts/toast.js +2 -1
  259. package/dist/users/app-invitations.js +5 -4
  260. package/dist/users/create-user-form.js +9 -8
  261. package/dist/users/messages.js +52 -0
  262. package/dist/users/use-user-roles.js +2 -1
  263. package/dist/users/user-list.js +6 -5
  264. package/dist/users/user-row.js +5 -4
  265. package/package.json +4 -4
  266. package/dist/shell/assets/app-C-OLrsRR.js +0 -69
  267. package/dist/shell/assets/export-worker-Bz57Pf5g.js +0 -2
  268. package/dist/shell/assets/maplibre-Dov6nhPX.js +0 -814
  269. package/dist/shell/assets/parse-worker-BtcY0dQw.js +0 -5
  270. package/dist/shell/assets/records-map-C1_gDKHR.js +0 -1
  271. package/dist/shell/assets/shared-protobase-ui-CFYJAbMR.js +0 -1
@@ -1,5 +1,6 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { Input } from "../primitives/input.js";
3
+ import { text } from "./messages.js";
3
4
  import { Button } from "../primitives/button.js";
4
5
  import { AuthLayout } from "./auth-layout.js";
5
6
  import { useState } from "react";
@@ -11,22 +12,22 @@ const StaffSignInForm = ({ operator, email: givenEmail = "", reason: givenReason
11
12
  const [email, setEmail] = useState(givenEmail);
12
13
  const [reason, setReason] = useState(givenReason);
13
14
  if (!operator) return /* @__PURE__ */ jsxs(AuthLayout, {
14
- title: "Staff sign-in",
15
- description: "Staff of the team that runs this app cannot sign in as people here.",
15
+ title: text("staffTitle"),
16
+ description: text("staffUnavailable"),
16
17
  children: [error && /* @__PURE__ */ jsx("p", {
17
18
  role: "alert",
18
- className: "mb-4 text-xs font-medium text-danger-text",
19
+ className: "mb-4 text-body font-medium text-danger-text",
19
20
  children: error
20
21
  }), /* @__PURE__ */ jsx(Button, {
21
22
  variant: "primary",
22
23
  className: "min-h-10 w-full",
23
24
  onClick: onBack,
24
- children: "Back to sign in"
25
+ children: text("backToSignIn")
25
26
  })]
26
27
  });
27
28
  return /* @__PURE__ */ jsx(AuthLayout, {
28
- title: "Sign in as a person",
29
- description: `For staff of ${operator}, to help someone with this app.`,
29
+ title: text("signInAsPerson"),
30
+ description: text("forStaffOf", operator),
30
31
  children: /* @__PURE__ */ jsxs("form", {
31
32
  className: "flex flex-col gap-4",
32
33
  onSubmit: (event) => {
@@ -36,7 +37,7 @@ const StaffSignInForm = ({ operator, email: givenEmail = "", reason: givenReason
36
37
  children: [
37
38
  /* @__PURE__ */ jsxs("label", {
38
39
  className: "flex flex-col gap-1.5 font-medium",
39
- children: ["Their email", /* @__PURE__ */ jsx(Input, {
40
+ children: [text("theirEmail"), /* @__PURE__ */ jsx(Input, {
40
41
  type: "email",
41
42
  name: "email",
42
43
  required: true,
@@ -48,42 +49,38 @@ const StaffSignInForm = ({ operator, email: givenEmail = "", reason: givenReason
48
49
  }),
49
50
  /* @__PURE__ */ jsxs("label", {
50
51
  className: "flex flex-col gap-1.5 font-medium",
51
- children: ["Reason", /* @__PURE__ */ jsx("textarea", {
52
+ children: [text("reason"), /* @__PURE__ */ jsx("textarea", {
52
53
  name: "reason",
53
54
  required: true,
54
55
  minLength: minimumReason,
55
56
  rows: 3,
56
57
  value: reason,
57
- placeholder: "Ticket 4211: the invoice totals look wrong",
58
+ placeholder: text("reasonExample"),
58
59
  onChange: (event) => setReason(event.target.value),
59
60
  className: cn("resize-y rounded-md border bg-background px-2.5 py-1.5 font-normal shadow-sm outline-none placeholder:text-faint-foreground focus:border-primary focus:ring-2 focus:ring-primary/20", error ? "border-danger" : "border-border-strong")
60
61
  })]
61
62
  }),
62
- /* @__PURE__ */ jsxs("p", {
63
+ /* @__PURE__ */ jsx("p", {
63
64
  className: "text-xs text-muted-foreground",
64
- children: [
65
- "You sign in at ",
66
- operator,
67
- " with a passkey or a second step. The session is short, shows a banner, and cannot change their sign-in. The app's admins see who signed in as whom, and why."
68
- ]
65
+ children: text("staffExplanation", operator)
69
66
  }),
70
67
  error && /* @__PURE__ */ jsx("p", {
71
68
  role: "alert",
72
- className: "text-xs font-medium text-danger-text",
69
+ className: "text-body font-medium text-danger-text",
73
70
  children: error
74
71
  }),
75
- /* @__PURE__ */ jsxs(Button, {
72
+ /* @__PURE__ */ jsx(Button, {
76
73
  variant: "primary",
77
74
  type: "submit",
78
75
  loading: busy,
79
76
  className: "min-h-10",
80
- children: ["Continue with ", operator]
77
+ children: text("continueWith", operator)
81
78
  }),
82
79
  /* @__PURE__ */ jsx(Button, {
83
80
  variant: "ghost",
84
81
  onClick: onBack,
85
82
  className: "min-h-10",
86
- children: "Back to sign in"
83
+ children: text("backToSignIn")
87
84
  })
88
85
  ]
89
86
  })
@@ -1,4 +1,5 @@
1
1
  import { Input } from "../primitives/input.js";
2
+ import { text } from "./messages.js";
2
3
  import { Button } from "../primitives/button.js";
3
4
  import { OtpInput } from "../primitives/otp-input.js";
4
5
  import { AuthLayout } from "./auth-layout.js";
@@ -7,9 +8,9 @@ import { useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
8
9
  //#region src/auth/two-factor-form.tsx
9
10
  const instructions = {
10
- totp: "Enter the 6-digit code from your authenticator app.",
11
- otp: "Enter the 6-digit code we emailed you. It works for 5 minutes.",
12
- backup: "Enter one of the backup codes you saved when you set up the authenticator app. Each works once."
11
+ totp: "totpInstruction",
12
+ otp: "otpInstruction",
13
+ backup: "backupInstruction"
13
14
  };
14
15
  /** The second step of a sign-in, for an account with two-factor authentication. */
15
16
  const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, codeSent, initialStep }) => {
@@ -23,18 +24,18 @@ const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, cod
23
24
  if (next === "otp" && !codeSent) onSendCode();
24
25
  };
25
26
  return /* @__PURE__ */ jsxs(AuthLayout, {
26
- title: "Two-factor authentication",
27
- description: "One more step to sign in.",
27
+ title: text("twoFactorTitle"),
28
+ description: text("twoFactorDescription"),
28
29
  children: [waitingForEmail ? /* @__PURE__ */ jsxs("div", {
29
30
  className: "flex flex-col gap-4",
30
31
  children: [
31
32
  /* @__PURE__ */ jsx("p", {
32
33
  className: "text-muted-foreground",
33
- children: "We email you a code to finish signing in."
34
+ children: text("codeToFinish")
34
35
  }),
35
36
  error && /* @__PURE__ */ jsx("p", {
36
37
  role: "alert",
37
- className: "text-xs font-medium text-danger-text",
38
+ className: "text-body font-medium text-danger-text",
38
39
  children: error
39
40
  }),
40
41
  /* @__PURE__ */ jsx(Button, {
@@ -42,7 +43,7 @@ const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, cod
42
43
  loading: busy,
43
44
  onClick: onSendCode,
44
45
  className: "min-h-10",
45
- children: "Email me a code"
46
+ children: text("emailCode")
46
47
  })
47
48
  ]
48
49
  }) : /* @__PURE__ */ jsxs("form", {
@@ -58,11 +59,11 @@ const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, cod
58
59
  children: [
59
60
  /* @__PURE__ */ jsx("p", {
60
61
  className: "text-muted-foreground",
61
- children: instructions[step]
62
+ children: text(instructions[step])
62
63
  }),
63
64
  /* @__PURE__ */ jsxs("label", {
64
65
  className: "flex flex-col gap-1.5 font-medium",
65
- children: [step === "backup" ? "Backup code" : "Code", step === "backup" ? /* @__PURE__ */ jsx(Input, {
66
+ children: [step === "backup" ? text("backupCode") : text("code"), step === "backup" ? /* @__PURE__ */ jsx(Input, {
66
67
  name: "code",
67
68
  autoComplete: "off",
68
69
  spellCheck: false,
@@ -86,12 +87,12 @@ const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, cod
86
87
  children: [/* @__PURE__ */ jsx(Checkbox, {
87
88
  checked: trustDevice,
88
89
  onChange: setTrustDevice,
89
- label: "Trust this browser"
90
- }), "Don't ask again in this browser for 30 days"]
90
+ label: text("trustBrowser")
91
+ }), text("trustBrowserFor")]
91
92
  }),
92
93
  error && /* @__PURE__ */ jsx("p", {
93
94
  role: "alert",
94
- className: "text-xs font-medium text-danger-text",
95
+ className: "text-body font-medium text-danger-text",
95
96
  children: error
96
97
  }),
97
98
  /* @__PURE__ */ jsx(Button, {
@@ -99,7 +100,7 @@ const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, cod
99
100
  type: "submit",
100
101
  loading: busy,
101
102
  className: "min-h-10",
102
- children: "Verify"
103
+ children: text("verify")
103
104
  })
104
105
  ]
105
106
  }), /* @__PURE__ */ jsxs("div", {
@@ -109,25 +110,25 @@ const TwoFactorForm = ({ methods, onVerify, onSendCode, onBack, busy, error, cod
109
110
  type: "button",
110
111
  onClick: () => switchTo("totp"),
111
112
  className: "font-medium text-primary-text hover:underline",
112
- children: "Use the authenticator app"
113
+ children: text("useAuthenticator")
113
114
  }),
114
115
  step !== "otp" && methods.includes("otp") && /* @__PURE__ */ jsx("button", {
115
116
  type: "button",
116
117
  onClick: () => switchTo("otp"),
117
118
  className: "font-medium text-primary-text hover:underline",
118
- children: "Email me a code instead"
119
+ children: text("emailCodeInstead")
119
120
  }),
120
121
  step !== "backup" && methods.includes("totp") && /* @__PURE__ */ jsx("button", {
121
122
  type: "button",
122
123
  onClick: () => switchTo("backup"),
123
124
  className: "font-medium text-primary-text hover:underline",
124
- children: "Use a backup code"
125
+ children: text("useBackupCode")
125
126
  }),
126
127
  /* @__PURE__ */ jsx("button", {
127
128
  type: "button",
128
129
  onClick: onBack,
129
130
  className: "font-medium text-muted-foreground hover:underline",
130
- children: "Back to sign in"
131
+ children: text("backToSignIn")
131
132
  })
132
133
  ]
133
134
  })]
@@ -1,3 +1,4 @@
1
+ import { text } from "./messages.js";
1
2
  //#region src/auth/user-to-shell.ts
2
3
  /** The hue of someone's avatar, the same for the same id. */
3
4
  const hueOf = (text) => [...text].reduce((sum, char) => (sum * 31 + char.charCodeAt(0)) % 360, 7);
@@ -15,7 +16,7 @@ const userToShell = (user) => {
15
16
  email: user.email,
16
17
  initials: initialsOf(user.name || user.email) || "?",
17
18
  hue: hueOf(user.id || user.email),
18
- role: admin ? "Admin" : (roles[0] ?? "user").replace(/^./, (char) => char.toUpperCase()),
19
+ role: admin ? text("admin") : (roles[0] ?? "user").replace(/^./, (char) => char.toUpperCase()),
19
20
  roleTone: admin ? "violet" : "blue"
20
21
  };
21
22
  };
@@ -1,17 +1,18 @@
1
1
  import { Input } from "../primitives/input.js";
2
2
  import { Button } from "../primitives/button.js";
3
+ import { text } from "./messages.js";
3
4
  import { useState } from "react";
4
5
  import { SendHorizontal } from "lucide-react";
5
6
  import { jsx, jsxs } from "react/jsx-runtime";
6
7
  //#region src/chat/composer.tsx
7
8
  /** The text box under a chat. Enter or the button sends the trimmed text and clears the box. */
8
9
  const Composer = ({ onSend, busy, placeholder, inputRef }) => {
9
- const [text, setText] = useState("");
10
- const message = text.trim();
10
+ const [draft, setDraft] = useState("");
11
+ const message = draft.trim();
11
12
  const send = () => {
12
13
  if (!message || busy) return;
13
14
  onSend?.(message);
14
- setText("");
15
+ setDraft("");
15
16
  };
16
17
  return /* @__PURE__ */ jsxs("form", {
17
18
  className: "flex gap-2",
@@ -21,16 +22,16 @@ const Composer = ({ onSend, busy, placeholder, inputRef }) => {
21
22
  },
22
23
  children: [/* @__PURE__ */ jsx(Input, {
23
24
  ref: inputRef,
24
- "aria-label": "Message",
25
+ "aria-label": text("message"),
25
26
  placeholder,
26
- value: text,
27
- onChange: (event) => setText(event.target.value),
27
+ value: draft,
28
+ onChange: (event) => setDraft(event.target.value),
28
29
  wrapperClassName: "flex-1"
29
30
  }), /* @__PURE__ */ jsx(Button, {
30
31
  type: "submit",
31
32
  variant: "primary",
32
33
  className: "w-8 px-0",
33
- "aria-label": "Send",
34
+ "aria-label": text("send"),
34
35
  disabled: !message || busy,
35
36
  children: /* @__PURE__ */ jsx(SendHorizontal, { className: "size-4" })
36
37
  })]
@@ -0,0 +1,14 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/chat/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ message: "Message",
6
+ send: "Send"
7
+ },
8
+ nl: {
9
+ message: "Bericht",
10
+ send: "Versturen"
11
+ }
12
+ });
13
+ //#endregion
14
+ export { text };
@@ -1,10 +1,11 @@
1
1
  import { cn } from "../lib/cn.js";
2
2
  import { formatCell } from "./format-cell.js";
3
+ import { text } from "./messages.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/compact-table/compact-table.tsx
5
6
  /** A small read-only table of raw values with a row count, for narrow places such as a side panel. */
6
7
  const CompactTable = ({ columns, rows, caption, truncated, className }) => /* @__PURE__ */ jsxs("section", {
7
- "aria-label": caption ?? "Table",
8
+ "aria-label": caption ?? text("table"),
8
9
  className: cn("shrink-0 overflow-hidden rounded-lg border border-border-strong bg-background shadow-sm", className),
9
10
  children: [
10
11
  caption && /* @__PURE__ */ jsx("code", {
@@ -13,7 +14,7 @@ const CompactTable = ({ columns, rows, caption, truncated, className }) => /* @_
13
14
  }),
14
15
  rows.length === 0 ? /* @__PURE__ */ jsx("p", {
15
16
  className: "px-3 py-2 text-xs text-muted-foreground",
16
- children: "No rows."
17
+ children: text("noRows")
17
18
  }) : /* @__PURE__ */ jsx("div", {
18
19
  className: "max-h-64 overflow-auto",
19
20
  children: /* @__PURE__ */ jsxs("table", {
@@ -36,12 +37,7 @@ const CompactTable = ({ columns, rows, caption, truncated, className }) => /* @_
36
37
  }),
37
38
  /* @__PURE__ */ jsxs("footer", {
38
39
  className: "border-t border-border px-3 py-1.5 text-[11px] text-muted-foreground",
39
- children: [
40
- rows.length,
41
- " ",
42
- rows.length === 1 ? "row" : "rows",
43
- truncated && ", cut off at the limit"
44
- ]
40
+ children: [text("rows", rows.length), truncated && text("cutOff")]
45
41
  })
46
42
  ]
47
43
  });
@@ -0,0 +1,18 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/compact-table/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ table: "Table",
6
+ noRows: "No rows.",
7
+ rows: (count) => `${count} ${count === 1 ? "row" : "rows"}`,
8
+ cutOff: ", cut off at the limit"
9
+ },
10
+ nl: {
11
+ table: "Tabel",
12
+ noRows: "Geen rijen.",
13
+ rows: (count) => `${count} ${count === 1 ? "rij" : "rijen"}`,
14
+ cutOff: ", afgekapt bij de limiet"
15
+ }
16
+ });
17
+ //#endregion
18
+ export { text };
@@ -1,5 +1,5 @@
1
- import { MapLayerModel, PluginRef, ResourcePermissions, SourceRef } from "@protobase/client";
2
1
  import { Locale } from "@protobase/schema/internal";
2
+ import { MapLayerModel, PluginRef, ResourcePermissions, SourceRef } from "@protobase/client";
3
3
  import { BottomBarModel, ResourceModel, SignInViewModel, UserMenuModel, ViewModel } from "@protobase/schema";
4
4
  import { PageModel } from "@protobase/layout";
5
5
  //#region src/data/meta-data.d.ts
@@ -1,7 +1,7 @@
1
1
  import { keys } from "./query-keys.js";
2
2
  import { useClient } from "./api-provider.js";
3
- import { PreconditionFailedError } from "@protobase/client";
4
3
  import { encodeKey } from "@protobase/schema/internal";
4
+ import { PreconditionFailedError } from "@protobase/client";
5
5
  import { useMutation, useQueryClient } from "@tanstack/react-query";
6
6
  //#region src/data/use-update-record.ts
7
7
  /**
@@ -20,7 +20,7 @@ const HeaderLabel = ({ spec }) => /* @__PURE__ */ jsxs(Fragment, { children: [/*
20
20
  children: text("new")
21
21
  })] });
22
22
  const GridHeader = ({ cells, specs, gutter, selectedCount, selectable, trailing, minScale, pins = {}, lastPinned, scrolled, onTogglePin, onClearSelection }) => /* @__PURE__ */ jsxs("div", {
23
- className: "grid h-8 shrink-0 items-center border-b bg-surface text-xs font-medium text-muted-foreground",
23
+ className: "grid h-8 shrink-0 items-center border-b bg-surface text-body font-medium text-muted-foreground",
24
24
  style: { gridTemplateColumns: gridTemplate(specs, gutter, trailing, minScale) },
25
25
  role: "row",
26
26
  children: [
@@ -12,7 +12,7 @@ const DatePresets = ({ value, presets = defaultDatePresets, onChange }) => /* @_
12
12
  disabled: !label,
13
13
  title: label ? void 0 : text("unknownPreset", id),
14
14
  onClick: () => onChange(value === id ? void 0 : id),
15
- className: cn("h-7 rounded-md border px-2.5 text-xs font-medium transition-colors", !label && "border-dashed text-danger-text", value === id ? "border-primary-border bg-primary-soft text-primary-text" : "border-border-strong bg-background text-muted-foreground hover:bg-muted"),
15
+ className: cn("h-7 rounded-md border px-2.5 text-body font-medium transition-colors", !label && "border-dashed text-danger-text", value === id ? "border-primary-border bg-primary-soft text-primary-text" : "border-border-strong bg-background text-muted-foreground hover:bg-muted"),
16
16
  children: label ?? text("unsupported", id)
17
17
  }, id);
18
18
  })
@@ -70,7 +70,7 @@ const LoadedForm = ({ form }) => {
70
70
  size: "md",
71
71
  children: /* @__PURE__ */ jsx("p", {
72
72
  role: "status",
73
- className: "rounded-md bg-success-soft px-3 py-2 text-xs font-medium text-success-text",
73
+ className: "rounded-md bg-success-soft px-3 py-2 text-body font-medium text-success-text",
74
74
  children: form.thanks
75
75
  })
76
76
  });
@@ -1,6 +1,7 @@
1
1
  import { Button } from "../primitives/button.js";
2
2
  import { productAt } from "../mocks/products.js";
3
3
  import { lineGrid } from "./columns.js";
4
+ import { text } from "./messages.js";
4
5
  import { LineRow } from "./line-row.js";
5
6
  import { reorder } from "./reorder.js";
6
7
  import { TotalsFooter } from "./totals-footer.js";
@@ -10,15 +11,14 @@ import { DndContext, KeyboardSensor, MouseSensor, TouchSensor, closestCenter, us
10
11
  import { SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from "@dnd-kit/sortable";
11
12
  //#region src/inline-child-table/inline-child-table.tsx
12
13
  const headerCell = "px-2 text-[11px] font-medium uppercase tracking-wide text-muted-foreground";
13
- const instructions = "To pick up a line, press space or enter on its drag handle. Use the up and down arrow keys to move it, space or enter to drop it, and escape to cancel. The row menu also has Move up and Move down.";
14
14
  const announcementsFor = (lines) => {
15
- const name = (id) => lines.find((line) => line.id === id)?.description ?? "line";
15
+ const name = (id) => lines.find((line) => line.id === id)?.description ?? text("line");
16
16
  const place = (id) => lines.findIndex((line) => line.id === id) + 1;
17
17
  return {
18
- onDragStart: ({ active }) => `Picked up ${name(active.id)}, line ${place(active.id)} of ${lines.length}.`,
19
- onDragOver: ({ active, over }) => over ? `${name(active.id)} is over line ${place(over.id)} of ${lines.length}.` : void 0,
20
- onDragEnd: ({ active, over }) => over ? `${name(active.id)} was dropped at line ${place(over.id)} of ${lines.length}.` : `${name(active.id)} was dropped where it started.`,
21
- onDragCancel: ({ active }) => `Moving ${name(active.id)} was cancelled. It is back at line ${place(active.id)}.`
18
+ onDragStart: ({ active }) => text("pickedUp", name(active.id), place(active.id), lines.length),
19
+ onDragOver: ({ active, over }) => over ? text("over", name(active.id), place(over.id), lines.length) : void 0,
20
+ onDragEnd: ({ active, over }) => over ? text("dropped", name(active.id), place(over.id), lines.length) : text("droppedAtStart", name(active.id)),
21
+ onDragCancel: ({ active }) => text("cancelled", name(active.id), place(active.id))
22
22
  };
23
23
  };
24
24
  const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly, reorderable = !readOnly }) => {
@@ -58,19 +58,19 @@ const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly,
58
58
  /* @__PURE__ */ jsx("span", {}),
59
59
  /* @__PURE__ */ jsx("span", {
60
60
  className: headerCell,
61
- children: "Item"
61
+ children: text("item")
62
62
  }),
63
63
  /* @__PURE__ */ jsx("span", {
64
64
  className: `${headerCell} text-right`,
65
- children: "Qty"
65
+ children: text("qty")
66
66
  }),
67
67
  /* @__PURE__ */ jsx("span", {
68
68
  className: `${headerCell} text-right`,
69
- children: "Unit price"
69
+ children: text("unitPrice")
70
70
  }),
71
71
  /* @__PURE__ */ jsx("span", {
72
72
  className: `${headerCell} text-right`,
73
- children: "Line total"
73
+ children: text("lineTotal")
74
74
  }),
75
75
  /* @__PURE__ */ jsx("span", {})
76
76
  ]
@@ -81,7 +81,7 @@ const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly,
81
81
  onDragEnd,
82
82
  accessibility: {
83
83
  announcements: announcementsFor(lines),
84
- screenReaderInstructions: { draggable: instructions }
84
+ screenReaderInstructions: { draggable: text("instructions") }
85
85
  },
86
86
  children: /* @__PURE__ */ jsx(SortableContext, {
87
87
  items: lines.map((line) => line.id),
@@ -107,7 +107,7 @@ const InlineChildTable = ({ lines, onChange, onReorder, vatRate = .21, readOnly,
107
107
  variant: "ghost",
108
108
  size: "sm",
109
109
  onClick: addLine,
110
- children: [/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }), "Add line"]
110
+ children: [/* @__PURE__ */ jsx(Plus, { className: "size-3.5" }), text("addLine")]
111
111
  })
112
112
  })
113
113
  ]
@@ -4,26 +4,27 @@ import { lineTotalCents } from "../mocks/invoices.js";
4
4
  import { lineGrid } from "./columns.js";
5
5
  import { LineMenu } from "./line-menu.js";
6
6
  import { NumberCell } from "./number-cell.js";
7
+ import { text } from "./messages.js";
7
8
  import { GripVertical } from "lucide-react";
8
9
  import { jsx, jsxs } from "react/jsx-runtime";
9
10
  import { useSortable } from "@dnd-kit/sortable";
10
11
  //#region src/inline-child-table/line-row.tsx
11
- const parseEuros = (text) => Math.round(Number(text.replace(",", ".").replace(/[^0-9.]/g, "")) * 100);
12
+ const parseEuros = (typed) => Math.round(Number(typed.replace(",", ".").replace(/[^0-9.]/g, "")) * 100);
12
13
  const LineRow = ({ line, position, count, reorderable, editable, onChange, onRemove, onMove }) => {
13
14
  const { attributes, listeners, setNodeRef, setActivatorNodeRef, transform, transition, isDragging } = useSortable({
14
15
  id: line.id,
15
16
  disabled: !reorderable
16
17
  });
17
18
  const menu = [...reorderable ? [{
18
- label: "Move up",
19
+ label: text("moveUp"),
19
20
  disabled: position === 0,
20
21
  onSelect: () => onMove(position - 1)
21
22
  }, {
22
- label: "Move down",
23
+ label: text("moveDown"),
23
24
  disabled: position === count - 1,
24
25
  onSelect: () => onMove(position + 1)
25
26
  }] : [], ...editable ? [{
26
- label: "Remove line",
27
+ label: text("removeLine"),
27
28
  destructive: true,
28
29
  onSelect: onRemove
29
30
  }] : []];
@@ -39,7 +40,7 @@ const LineRow = ({ line, position, count, reorderable, editable, onChange, onRem
39
40
  reorderable ? /* @__PURE__ */ jsx("button", {
40
41
  ref: setActivatorNodeRef,
41
42
  type: "button",
42
- "aria-label": `Drag to reorder ${line.description}`,
43
+ "aria-label": text("dragToReorder", line.description),
43
44
  ...attributes,
44
45
  ...listeners,
45
46
  style: { touchAction: "none" },
@@ -57,17 +58,17 @@ const LineRow = ({ line, position, count, reorderable, editable, onChange, onRem
57
58
  })]
58
59
  }),
59
60
  editable ? /* @__PURE__ */ jsx(NumberCell, {
60
- label: "Quantity",
61
+ label: text("quantity"),
61
62
  value: line.quantity,
62
63
  format: String,
63
- parse: (text) => Math.round(Number(text)),
64
+ parse: (typed) => Math.round(Number(typed)),
64
65
  onCommit: (quantity) => onChange({ quantity })
65
66
  }) : /* @__PURE__ */ jsx("span", {
66
67
  className: "px-2 text-right tabular-nums",
67
68
  children: line.quantity
68
69
  }),
69
70
  editable ? /* @__PURE__ */ jsx(NumberCell, {
70
- label: "Unit price",
71
+ label: text("unitPrice"),
71
72
  value: line.unitPriceCents,
72
73
  format: (cents) => (cents / 100).toFixed(2),
73
74
  parse: parseEuros,
@@ -81,7 +82,7 @@ const LineRow = ({ line, position, count, reorderable, editable, onChange, onRem
81
82
  children: formatMoney(lineTotalCents(line))
82
83
  }),
83
84
  menu.length > 0 ? /* @__PURE__ */ jsx(LineMenu, {
84
- label: `Actions for ${line.description}`,
85
+ label: text("actionsFor", line.description),
85
86
  items: menu
86
87
  }) : /* @__PURE__ */ jsx("span", {})
87
88
  ]
@@ -0,0 +1,52 @@
1
+ import { defineMessages } from "../locale/messages.js";
2
+ //#region src/inline-child-table/messages.ts
3
+ const text = defineMessages({
4
+ en: {
5
+ instructions: "To pick up a line, press space or enter on its drag handle. Use the up and down arrow keys to move it, space or enter to drop it, and escape to cancel. The row menu also has Move up and Move down.",
6
+ line: "line",
7
+ pickedUp: (name, place, count) => `Picked up ${name}, line ${place} of ${count}.`,
8
+ over: (name, place, count) => `${name} is over line ${place} of ${count}.`,
9
+ dropped: (name, place, count) => `${name} was dropped at line ${place} of ${count}.`,
10
+ droppedAtStart: (name) => `${name} was dropped where it started.`,
11
+ cancelled: (name, place) => `Moving ${name} was cancelled. It is back at line ${place}.`,
12
+ item: "Item",
13
+ qty: "Qty",
14
+ quantity: "Quantity",
15
+ unitPrice: "Unit price",
16
+ lineTotal: "Line total",
17
+ addLine: "Add line",
18
+ moveUp: "Move up",
19
+ moveDown: "Move down",
20
+ removeLine: "Remove line",
21
+ dragToReorder: (name) => `Drag to reorder ${name}`,
22
+ actionsFor: (name) => `Actions for ${name}`,
23
+ subtotal: "Subtotal",
24
+ vat: (percent) => `VAT ${percent}%`,
25
+ total: "Total"
26
+ },
27
+ nl: {
28
+ instructions: "Druk op spatie of enter op de sleepgreep om een regel op te pakken. Verplaats hem met de pijltjestoetsen omhoog en omlaag, zet hem neer met spatie of enter, en annuleer met escape. Het regelmenu heeft ook Omhoog en Omlaag.",
29
+ line: "regel",
30
+ pickedUp: (name, place, count) => `${name} opgepakt, regel ${place} van ${count}.`,
31
+ over: (name, place, count) => `${name} is boven regel ${place} van ${count}.`,
32
+ dropped: (name, place, count) => `${name} is neergezet op regel ${place} van ${count}.`,
33
+ droppedAtStart: (name) => `${name} is neergezet waar hij begon.`,
34
+ cancelled: (name, place) => `Verplaatsen van ${name} is geannuleerd. Hij staat weer op regel ${place}.`,
35
+ item: "Artikel",
36
+ qty: "Aantal",
37
+ quantity: "Aantal",
38
+ unitPrice: "Stukprijs",
39
+ lineTotal: "Regeltotaal",
40
+ addLine: "Regel toevoegen",
41
+ moveUp: "Omhoog",
42
+ moveDown: "Omlaag",
43
+ removeLine: "Regel verwijderen",
44
+ dragToReorder: (name) => `Sleep om ${name} te verplaatsen`,
45
+ actionsFor: (name) => `Acties voor ${name}`,
46
+ subtotal: "Subtotaal",
47
+ vat: (percent) => `Btw ${percent}%`,
48
+ total: "Totaal"
49
+ }
50
+ });
51
+ //#endregion
52
+ export { text };
@@ -1,5 +1,6 @@
1
1
  import { formatMoney } from "../format/money.js";
2
2
  import { invoiceTotals } from "../mocks/invoices.js";
3
+ import { text } from "./messages.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/inline-child-table/totals-footer.tsx
5
6
  const TotalsFooter = ({ lines, vatRate }) => {
@@ -9,19 +10,15 @@ const TotalsFooter = ({ lines, vatRate }) => {
9
10
  children: [
10
11
  /* @__PURE__ */ jsx("dt", {
11
12
  className: "text-muted-foreground",
12
- children: "Subtotal"
13
+ children: text("subtotal")
13
14
  }),
14
15
  /* @__PURE__ */ jsx("dd", {
15
16
  className: "text-right text-foreground",
16
17
  children: formatMoney(totals.subtotalCents)
17
18
  }),
18
- /* @__PURE__ */ jsxs("dt", {
19
+ /* @__PURE__ */ jsx("dt", {
19
20
  className: "text-muted-foreground",
20
- children: [
21
- "VAT ",
22
- Math.round(vatRate * 100),
23
- "%"
24
- ]
21
+ children: text("vat", Math.round(vatRate * 100))
25
22
  }),
26
23
  /* @__PURE__ */ jsx("dd", {
27
24
  className: "text-right text-foreground",
@@ -29,7 +26,7 @@ const TotalsFooter = ({ lines, vatRate }) => {
29
26
  }),
30
27
  /* @__PURE__ */ jsx("dt", {
31
28
  className: "mt-1 border-t border-border pt-2 font-semibold text-foreground",
32
- children: "Total"
29
+ children: text("total")
33
30
  }),
34
31
  /* @__PURE__ */ jsx("dd", {
35
32
  className: "mt-1 border-t border-border pt-2 text-right text-[16px] font-semibold text-foreground",
@@ -2,6 +2,7 @@ import { Input } from "../primitives/input.js";
2
2
  import { Button } from "../primitives/button.js";
3
3
  import { AccountSection, SectionError } from "../account/account-section.js";
4
4
  import { useAction } from "../organizations/use-action.js";
5
+ import { text } from "./messages.js";
5
6
  import { LinkNotice } from "./link-notice.js";
6
7
  import { useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -30,7 +31,7 @@ const InviteForm = ({ title, description, onInvite, beside, children, incomplete
30
31
  className: "flex flex-col gap-2 sm:flex-row",
31
32
  children: [
32
33
  /* @__PURE__ */ jsx(Input, {
33
- "aria-label": "Email",
34
+ "aria-label": text("email"),
34
35
  type: "email",
35
36
  placeholder: "name@example.com",
36
37
  value: email,
@@ -43,7 +44,7 @@ const InviteForm = ({ title, description, onInvite, beside, children, incomplete
43
44
  variant: "primary",
44
45
  loading: busy,
45
46
  disabled: !email.trim() || incomplete,
46
- children: "Invite"
47
+ children: text("invite")
47
48
  })
48
49
  ]
49
50
  }), children]