@bitvea/feedback-toolbar 0.0.1

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 (176) hide show
  1. package/README.md +262 -0
  2. package/dist/FeedbackPanel.d.ts +117 -0
  3. package/dist/FeedbackPanel.d.ts.map +1 -0
  4. package/dist/FeedbackPanel.js +622 -0
  5. package/dist/FeedbackPanel.js.map +1 -0
  6. package/dist/FeedbackToolbar.d.ts +54 -0
  7. package/dist/FeedbackToolbar.d.ts.map +1 -0
  8. package/dist/FeedbackToolbar.js +1149 -0
  9. package/dist/FeedbackToolbar.js.map +1 -0
  10. package/dist/InboxSheet.d.ts +80 -0
  11. package/dist/InboxSheet.d.ts.map +1 -0
  12. package/dist/InboxSheet.js +580 -0
  13. package/dist/InboxSheet.js.map +1 -0
  14. package/dist/PinLayer.d.ts +59 -0
  15. package/dist/PinLayer.d.ts.map +1 -0
  16. package/dist/PinLayer.js +1702 -0
  17. package/dist/PinLayer.js.map +1 -0
  18. package/dist/RichText.d.ts +6 -0
  19. package/dist/RichText.d.ts.map +1 -0
  20. package/dist/RichText.js +135 -0
  21. package/dist/RichText.js.map +1 -0
  22. package/dist/browser/entry.d.ts +3 -0
  23. package/dist/browser/entry.d.ts.map +1 -0
  24. package/dist/browser/entry.js +13 -0
  25. package/dist/browser/entry.js.map +1 -0
  26. package/dist/browser/mount.d.ts +37 -0
  27. package/dist/browser/mount.d.ts.map +1 -0
  28. package/dist/browser/mount.js +150 -0
  29. package/dist/browser/mount.js.map +1 -0
  30. package/dist/browser/toolbar.js +38 -0
  31. package/dist/browser/toolbar.js.map +7 -0
  32. package/dist/capture.d.ts +58 -0
  33. package/dist/capture.d.ts.map +1 -0
  34. package/dist/capture.js +98 -0
  35. package/dist/capture.js.map +1 -0
  36. package/dist/cli/bin.d.ts +3 -0
  37. package/dist/cli/bin.d.ts.map +1 -0
  38. package/dist/cli/bin.js +196 -0
  39. package/dist/cli/bin.js.map +1 -0
  40. package/dist/cli/fs.d.ts +16 -0
  41. package/dist/cli/fs.d.ts.map +1 -0
  42. package/dist/cli/fs.js +33 -0
  43. package/dist/cli/fs.js.map +1 -0
  44. package/dist/cli/init.d.ts +75 -0
  45. package/dist/cli/init.d.ts.map +1 -0
  46. package/dist/cli/init.js +266 -0
  47. package/dist/cli/init.js.map +1 -0
  48. package/dist/cli/register.d.ts +55 -0
  49. package/dist/cli/register.d.ts.map +1 -0
  50. package/dist/cli/register.js +84 -0
  51. package/dist/cli/register.js.map +1 -0
  52. package/dist/cli/registration.d.ts +37 -0
  53. package/dist/cli/registration.d.ts.map +1 -0
  54. package/dist/cli/registration.js +69 -0
  55. package/dist/cli/registration.js.map +1 -0
  56. package/dist/cli/strategies.d.ts +98 -0
  57. package/dist/cli/strategies.d.ts.map +1 -0
  58. package/dist/cli/strategies.js +198 -0
  59. package/dist/cli/strategies.js.map +1 -0
  60. package/dist/client.d.ts +59 -0
  61. package/dist/client.d.ts.map +1 -0
  62. package/dist/client.js +113 -0
  63. package/dist/client.js.map +1 -0
  64. package/dist/config.d.ts +92 -0
  65. package/dist/config.d.ts.map +1 -0
  66. package/dist/config.js +65 -0
  67. package/dist/config.js.map +1 -0
  68. package/dist/deepLink.d.ts +86 -0
  69. package/dist/deepLink.d.ts.map +1 -0
  70. package/dist/deepLink.js +185 -0
  71. package/dist/deepLink.js.map +1 -0
  72. package/dist/fontFace.d.ts +70 -0
  73. package/dist/fontFace.d.ts.map +1 -0
  74. package/dist/fontFace.js +88 -0
  75. package/dist/fontFace.js.map +1 -0
  76. package/dist/gating.d.ts +32 -0
  77. package/dist/gating.d.ts.map +1 -0
  78. package/dist/gating.js +49 -0
  79. package/dist/gating.js.map +1 -0
  80. package/dist/icons.d.ts +68 -0
  81. package/dist/icons.d.ts.map +1 -0
  82. package/dist/icons.js +97 -0
  83. package/dist/icons.js.map +1 -0
  84. package/dist/index.d.ts +14 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +68 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/markdown.d.ts +59 -0
  89. package/dist/markdown.d.ts.map +1 -0
  90. package/dist/markdown.js +130 -0
  91. package/dist/markdown.js.map +1 -0
  92. package/dist/motion.d.ts +178 -0
  93. package/dist/motion.d.ts.map +1 -0
  94. package/dist/motion.js +302 -0
  95. package/dist/motion.js.map +1 -0
  96. package/dist/preferences.d.ts +71 -0
  97. package/dist/preferences.d.ts.map +1 -0
  98. package/dist/preferences.js +195 -0
  99. package/dist/preferences.js.map +1 -0
  100. package/dist/rasterise.d.ts +45 -0
  101. package/dist/rasterise.d.ts.map +1 -0
  102. package/dist/rasterise.js +490 -0
  103. package/dist/rasterise.js.map +1 -0
  104. package/dist/selector.d.ts +19 -0
  105. package/dist/selector.d.ts.map +1 -0
  106. package/dist/selector.js +142 -0
  107. package/dist/selector.js.map +1 -0
  108. package/dist/session.d.ts +19 -0
  109. package/dist/session.d.ts.map +1 -0
  110. package/dist/session.js +36 -0
  111. package/dist/session.js.map +1 -0
  112. package/dist/shortcut.d.ts +88 -0
  113. package/dist/shortcut.d.ts.map +1 -0
  114. package/dist/shortcut.js +149 -0
  115. package/dist/shortcut.js.map +1 -0
  116. package/dist/tokens.d.ts +709 -0
  117. package/dist/tokens.d.ts.map +1 -0
  118. package/dist/tokens.js +749 -0
  119. package/dist/tokens.js.map +1 -0
  120. package/dist/vendor/types/account.d.ts +26 -0
  121. package/dist/vendor/types/account.d.ts.map +1 -0
  122. package/dist/vendor/types/account.js +23 -0
  123. package/dist/vendor/types/account.js.map +1 -0
  124. package/dist/vendor/types/apiKey.d.ts +38 -0
  125. package/dist/vendor/types/apiKey.d.ts.map +1 -0
  126. package/dist/vendor/types/apiKey.js +36 -0
  127. package/dist/vendor/types/apiKey.js.map +1 -0
  128. package/dist/vendor/types/auth.d.ts +10 -0
  129. package/dist/vendor/types/auth.d.ts.map +1 -0
  130. package/dist/vendor/types/auth.js +15 -0
  131. package/dist/vendor/types/auth.js.map +1 -0
  132. package/dist/vendor/types/entity.d.ts +74 -0
  133. package/dist/vendor/types/entity.d.ts.map +1 -0
  134. package/dist/vendor/types/entity.js +111 -0
  135. package/dist/vendor/types/entity.js.map +1 -0
  136. package/dist/vendor/types/feedback.d.ts +285 -0
  137. package/dist/vendor/types/feedback.d.ts.map +1 -0
  138. package/dist/vendor/types/feedback.js +286 -0
  139. package/dist/vendor/types/feedback.js.map +1 -0
  140. package/dist/vendor/types/index.d.ts +14 -0
  141. package/dist/vendor/types/index.d.ts.map +1 -0
  142. package/dist/vendor/types/index.js +16 -0
  143. package/dist/vendor/types/index.js.map +1 -0
  144. package/dist/vendor/types/invite.d.ts +42 -0
  145. package/dist/vendor/types/invite.d.ts.map +1 -0
  146. package/dist/vendor/types/invite.js +30 -0
  147. package/dist/vendor/types/invite.js.map +1 -0
  148. package/dist/vendor/types/mcpToken.d.ts +38 -0
  149. package/dist/vendor/types/mcpToken.d.ts.map +1 -0
  150. package/dist/vendor/types/mcpToken.js +39 -0
  151. package/dist/vendor/types/mcpToken.js.map +1 -0
  152. package/dist/vendor/types/organization.d.ts +13 -0
  153. package/dist/vendor/types/organization.d.ts.map +1 -0
  154. package/dist/vendor/types/organization.js +12 -0
  155. package/dist/vendor/types/organization.js.map +1 -0
  156. package/dist/vendor/types/project.d.ts +73 -0
  157. package/dist/vendor/types/project.d.ts.map +1 -0
  158. package/dist/vendor/types/project.js +117 -0
  159. package/dist/vendor/types/project.js.map +1 -0
  160. package/dist/vendor/types/role.d.ts +12 -0
  161. package/dist/vendor/types/role.d.ts.map +1 -0
  162. package/dist/vendor/types/role.js +20 -0
  163. package/dist/vendor/types/role.js.map +1 -0
  164. package/dist/vendor/types/roleDefinition.d.ts +61 -0
  165. package/dist/vendor/types/roleDefinition.d.ts.map +1 -0
  166. package/dist/vendor/types/roleDefinition.js +45 -0
  167. package/dist/vendor/types/roleDefinition.js.map +1 -0
  168. package/dist/vendor/types/team.d.ts +25 -0
  169. package/dist/vendor/types/team.d.ts.map +1 -0
  170. package/dist/vendor/types/team.js +17 -0
  171. package/dist/vendor/types/team.js.map +1 -0
  172. package/dist/vendor/types/util.d.ts +39 -0
  173. package/dist/vendor/types/util.d.ts.map +1 -0
  174. package/dist/vendor/types/util.js +31 -0
  175. package/dist/vendor/types/util.js.map +1 -0
  176. package/package.json +59 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,WAAW,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,cAAc,EACd,KAAK,mBAAmB,GACzB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAU/D,OAAO,EACL,UAAU,EACV,cAAc,EACd,yBAAyB,EACzB,eAAe,EACf,KAAK,YAAY,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AA+B1D,OAAO,EACL,MAAM,EACN,SAAS,EACT,YAAY,EACZ,OAAO,EACP,KAAK,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,KAAK,EACL,oBAAoB,EACpB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,aAAa,EACb,UAAU,EACV,SAAS,EACT,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,gBAAgB,GACtB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,eAAe,EACf,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,EACf,KAAK,aAAa,EAClB,KAAK,sBAAsB,GAC5B,MAAM,UAAU,CAAC;AAQlB,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,KAAK,kBAAkB,EACvB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,OAAO,EACP,aAAa,EACb,KAAK,SAAS,GACf,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,68 @@
1
+ // @bitvea/feedback-toolbar - the toolbar a BitVea app installs to collect
2
+ // review feedback from its preview deployments.
3
+ //
4
+ // Install with `npx @bitvea/feedback-toolbar init`, which adds the dependency,
5
+ // writes the env vars, and injects <FeedbackToolbar /> into the root layout.
6
+ export { FeedbackToolbar, } from "./FeedbackToolbar.js";
7
+ export { FeedbackPanel, AccountSurface, } from "./FeedbackPanel.js";
8
+ // The inbox sheet is the default inbox, so a host never needs to name it -
9
+ // but a host replacing it needs its props, and the preview route mounts it
10
+ // directly.
11
+ export { InboxSheet, INBOX_OPEN_STORAGE_KEY, } from "./InboxSheet.js";
12
+ // Deep-linking. The dashboard builds these links; the toolbar consumes them.
13
+ export { buildDeepLink, parseDeepLink, DEEP_LINK_PREFIX } from "./deepLink.js";
14
+ export { createToolbarClient, ToolbarApiError, } from "./client.js";
15
+ export { captureMetadata, captureScreenshot } from "./capture.js";
16
+ // The composer's formatting helpers, and the markdown SAFETY POLICY the
17
+ // dashboard renders by too. Shared rather than copied: the two surfaces style
18
+ // a comment differently and must decide what a comment IS identically, or the
19
+ // same text means two things and the copy nobody is looking at drifts.
20
+ //
21
+ // Rendering itself is react-markdown's job. The conditions that keep it safe
22
+ // on a customer's page are at the head of RichText.tsx - chiefly that
23
+ // `rehype-raw` is never added.
24
+ export { toggleMark, MARKDOWN_MARKS, MARKDOWN_ALLOWED_ELEMENTS, safeMarkdownUrl, } from "./markdown.js";
25
+ export { PinLayer } from "./PinLayer.js";
26
+ // The tokens the toolbar renders with, for a surface that has to sit beside
27
+ // it - the preview route's own chrome, for one - without re-deriving them.
28
+ // The type scale, spacing and radii are exported alongside the palettes for
29
+ // the same reason the palettes are: a neighbouring surface that re-derives
30
+ // them drifts, and the alternative to exporting them is a second set of
31
+ // literals somewhere nobody looks.
32
+ // `motion`, `transition` and `motionTransform` are in this list for exactly
33
+ // the reason the rest of it gives: a surface sitting beside the toolbar that
34
+ // hand-writes `120ms ease` is a surface that animates at a different speed
35
+ // from the thing it sits beside, and DESIGN.md's Motion section is the
36
+ // authority both are supposed to be reading. The two functions travel together
37
+ // because they are two halves of one rule - `transition` takes `transform` out
38
+ // of the property list under reduced motion and `motionTransform` takes out
39
+ // the value, and a consumer with only one of them can honour only half the
40
+ // preference. The hooks in motion.ts stay internal - they are how this package
41
+ // implements the vocabulary, not part of it - but `reduced` is a REQUIRED
42
+ // argument on both functions, so `REDUCED_MOTION_QUERY` has to travel with them
43
+ // or a consumer has no way to answer it except by retyping the media string,
44
+ // which is exactly the drift the palettes are exported to prevent. `exitFor`
45
+ // and `MotionDuration` come along for the same reason: the exit rule and the
46
+ // closed set of three steps are the parts of `transition`'s contract a caller
47
+ // outside this file would otherwise have to guess at.
48
+ // `ToolbarDock` and its two constants are exported ADDITIVELY, and that word is
49
+ // doing work: this is the one package here that publishes to npm, so the eight
50
+ // dock values are now part of a shipped type. A host that renders the account
51
+ // surface itself, or that wants to write the reviewer's dock from its own
52
+ // settings screen, needs the vocabulary - and it needs it as a type it cannot
53
+ // mistype rather than as eight strings copied out of a changelog. Nothing
54
+ // existing changed shape: no prop was added to `AccountSurfaceProps`, which is
55
+ // why the position control reads the preference store directly.
56
+ export { accent, darkTheme, DEFAULT_DOCK, exitFor, fonts, lightTheme, motion, motionTransform, radii, REDUCED_MOTION_QUERY, sizes, spacing, themeFor, TOOLBAR_DOCKS, transition, typeScale, } from "./tokens.js";
57
+ export { buildSelector, resolveSelector, offsetWithin, locatePin, } from "./selector.js";
58
+ export { resolveConfig, API_URL_ENV_VAR, VERCEL_ENV_VARS, } from "./config.js";
59
+ // The pinning chord. Exported because remapping or switching it off is a HOST
60
+ // decision - the toolbar claims the keys inside the host's own application -
61
+ // and a host cannot express either without the chord's type. `formatChord`
62
+ // travels with them for the same reason the palettes do: a host that renders
63
+ // its own hint and hand-writes "Cmd+Space+F" has written a second copy of a
64
+ // value this package can change, which is the drift the single definition
65
+ // exists to prevent.
66
+ export { DEFAULT_PIN_SHORTCUT, formatChord, isApplePlatform, } from "./shortcut.js";
67
+ export { isToolbarEnabled, isToolbarEnabledFromEnv, ENV_VAR, FORCE_ENV_VAR, } from "./gating.js";
68
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,gDAAgD;AAChD,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,OAAO,EACL,eAAe,GAIhB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,aAAa,EAEb,cAAc,GAEf,MAAM,iBAAiB,CAAC;AACzB,2EAA2E;AAC3E,2EAA2E;AAC3E,YAAY;AACZ,OAAO,EACL,UAAU,EAGV,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,6EAA6E;AAC7E,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,mBAAmB,EACnB,eAAe,GAGhB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE/D,wEAAwE;AACxE,8EAA8E;AAC9E,8EAA8E;AAC9E,uEAAuE;AACvE,EAAE;AACF,6EAA6E;AAC7E,sEAAsE;AACtE,+BAA+B;AAC/B,OAAO,EACL,UAAU,EACV,cAAc,EACd,yBAAyB,EACzB,eAAe,GAEhB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAsB,MAAM,YAAY,CAAC;AAC1D,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAC3E,wEAAwE;AACxE,mCAAmC;AACnC,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,uEAAuE;AACvE,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,2EAA2E;AAC3E,+EAA+E;AAC/E,0EAA0E;AAC1E,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAC7E,6EAA6E;AAC7E,8EAA8E;AAC9E,sDAAsD;AACtD,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAC9E,0EAA0E;AAC1E,+EAA+E;AAC/E,gEAAgE;AAChE,OAAO,EACL,MAAM,EACN,SAAS,EACT,YAAY,EACZ,OAAO,EACP,KAAK,EACL,UAAU,EACV,MAAM,EACN,eAAe,EACf,KAAK,EACL,oBAAoB,EACpB,KAAK,EACL,OAAO,EACP,QAAQ,EACR,aAAa,EACb,UAAU,EACV,SAAS,GASV,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,eAAe,EACf,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,aAAa,EACb,eAAe,EACf,eAAe,GAGhB,MAAM,UAAU,CAAC;AAClB,8EAA8E;AAC9E,6EAA6E;AAC7E,2EAA2E;AAC3E,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,qBAAqB;AACrB,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,eAAe,GAGhB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,OAAO,EACP,aAAa,GAEd,MAAM,UAAU,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The markers, and the only ones the bar writes. CommonMark, so what a
3
+ * reviewer types by hand and what the buttons produce are the same thing.
4
+ */
5
+ export declare const MARKDOWN_MARKS: {
6
+ readonly bold: "**";
7
+ readonly italic: "_";
8
+ readonly strike: "~~";
9
+ readonly code: "`";
10
+ };
11
+ export type MarkdownMark = keyof typeof MARKDOWN_MARKS;
12
+ /**
13
+ * react-markdown's `urlTransform`, as an ALLOWLIST.
14
+ *
15
+ * The library ships a default that strips known-dangerous protocols; this
16
+ * replaces it because the set of dangerous schemes is open-ended and the set
17
+ * of useful ones is three.
18
+ *
19
+ * Parsed with NO BASE, and that is the load-bearing detail. Resolving against
20
+ * one made every relative href PASS: `//evil.example/steal` became
21
+ * `https://evil.example/steal`, and `/settings` became a link to whatever
22
+ * origin the base named - while on a customer's page a relative href points at
23
+ * THEIR site, not ours. Without a base those throw, which is the right answer:
24
+ * a comment renders on the reviewed site AND on the dashboard, so a
25
+ * destination meaning "here" means two different places.
26
+ *
27
+ * Returns `""` rather than throwing: a refused destination renders as inert
28
+ * text with its label intact, so nothing a reviewer wrote disappears and
29
+ * nothing they wrote executes.
30
+ */
31
+ export declare function safeMarkdownUrl(url: string): string;
32
+ /**
33
+ * The elements a comment may render, on either surface.
34
+ *
35
+ * Shared rather than duplicated: the toolbar and the dashboard style comments
36
+ * differently and must decide what a comment IS identically, or the same text
37
+ * means two things. Anything outside this list is dropped with its text kept
38
+ * (`unwrapDisallowed`), so an unsupported construct reads as what the reviewer
39
+ * typed rather than vanishing.
40
+ *
41
+ * No `img`: it would let a comment fetch a remote URL from inside a customer's
42
+ * page - a tracking pixel the reviewed site appears to have requested - and a
43
+ * screenshot has its own field. No headings: they are noise in a 440px card.
44
+ */
45
+ export declare const MARKDOWN_ALLOWED_ELEMENTS: readonly ["p", "br", "strong", "em", "del", "code", "pre", "a", "ul", "ol", "li", "blockquote", "hr"];
46
+ /**
47
+ * Wrap or unwrap a selection, for the composer's formatting bar.
48
+ *
49
+ * Toggling rather than only wrapping: a reviewer who bolds the wrong word
50
+ * presses the same button to undo it, which is what every editor they have
51
+ * used does. Returns the new text and where the selection should land, because
52
+ * a formatting button that loses the cursor is one a reviewer stops using.
53
+ */
54
+ export declare function toggleMark(text: string, start: number, end: number, mark: MarkdownMark): {
55
+ text: string;
56
+ selectionStart: number;
57
+ selectionEnd: number;
58
+ };
59
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAeA;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;CAOjB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,cAAc,CAAC;AAWvD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,uGAc5B,CAAC;AAEX;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,YAAY,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAmChE"}
@@ -0,0 +1,130 @@
1
+ // The markers the composer's formatting bar writes.
2
+ //
3
+ // RENDERING is `react-markdown`'s job (see RichText.tsx); this is only the
4
+ // half that edits the source text. The two have to agree on the grammar, and
5
+ // they do because the grammar is CommonMark - these are the markers it
6
+ // defines, not a dialect of our own.
7
+ //
8
+ // There is no parser here any more. There was one, and the library replaced it
9
+ // for two reasons worth writing down: a hand-written parser covers four
10
+ // constructs and a maintained one covers the language, and the edge cases in
11
+ // markdown are endless enough that owning them is a standing cost. It was NOT
12
+ // replaced for safety - both build a React tree and neither produces HTML, and
13
+ // the conditions that keep react-markdown safe are listed at the head of
14
+ // RichText.tsx.
15
+ /**
16
+ * The markers, and the only ones the bar writes. CommonMark, so what a
17
+ * reviewer types by hand and what the buttons produce are the same thing.
18
+ */
19
+ export const MARKDOWN_MARKS = {
20
+ bold: "**",
21
+ italic: "_",
22
+ // GFM, which is why `remark-gfm` is loaded: CommonMark has no strikethrough.
23
+ // It renders to `del`, which the allowed element set carries.
24
+ strike: "~~",
25
+ code: "`",
26
+ };
27
+ /**
28
+ * Only these schemes may appear in a link.
29
+ *
30
+ * `javascript:` is the obvious one, but `data:` is the one that gets missed: a
31
+ * `data:text/html` href executes in the page's origin on click, which on a
32
+ * customer's site is THEIR origin, not ours.
33
+ */
34
+ const SAFE_SCHEMES = ["http:", "https:", "mailto:"];
35
+ /**
36
+ * react-markdown's `urlTransform`, as an ALLOWLIST.
37
+ *
38
+ * The library ships a default that strips known-dangerous protocols; this
39
+ * replaces it because the set of dangerous schemes is open-ended and the set
40
+ * of useful ones is three.
41
+ *
42
+ * Parsed with NO BASE, and that is the load-bearing detail. Resolving against
43
+ * one made every relative href PASS: `//evil.example/steal` became
44
+ * `https://evil.example/steal`, and `/settings` became a link to whatever
45
+ * origin the base named - while on a customer's page a relative href points at
46
+ * THEIR site, not ours. Without a base those throw, which is the right answer:
47
+ * a comment renders on the reviewed site AND on the dashboard, so a
48
+ * destination meaning "here" means two different places.
49
+ *
50
+ * Returns `""` rather than throwing: a refused destination renders as inert
51
+ * text with its label intact, so nothing a reviewer wrote disappears and
52
+ * nothing they wrote executes.
53
+ */
54
+ export function safeMarkdownUrl(url) {
55
+ try {
56
+ const parsed = new URL(url);
57
+ return SAFE_SCHEMES.includes(parsed.protocol) ? url : "";
58
+ }
59
+ catch {
60
+ return "";
61
+ }
62
+ }
63
+ /**
64
+ * The elements a comment may render, on either surface.
65
+ *
66
+ * Shared rather than duplicated: the toolbar and the dashboard style comments
67
+ * differently and must decide what a comment IS identically, or the same text
68
+ * means two things. Anything outside this list is dropped with its text kept
69
+ * (`unwrapDisallowed`), so an unsupported construct reads as what the reviewer
70
+ * typed rather than vanishing.
71
+ *
72
+ * No `img`: it would let a comment fetch a remote URL from inside a customer's
73
+ * page - a tracking pixel the reviewed site appears to have requested - and a
74
+ * screenshot has its own field. No headings: they are noise in a 440px card.
75
+ */
76
+ export const MARKDOWN_ALLOWED_ELEMENTS = [
77
+ "p",
78
+ "br",
79
+ "strong",
80
+ "em",
81
+ "del",
82
+ "code",
83
+ "pre",
84
+ "a",
85
+ "ul",
86
+ "ol",
87
+ "li",
88
+ "blockquote",
89
+ "hr",
90
+ ];
91
+ /**
92
+ * Wrap or unwrap a selection, for the composer's formatting bar.
93
+ *
94
+ * Toggling rather than only wrapping: a reviewer who bolds the wrong word
95
+ * presses the same button to undo it, which is what every editor they have
96
+ * used does. Returns the new text and where the selection should land, because
97
+ * a formatting button that loses the cursor is one a reviewer stops using.
98
+ */
99
+ export function toggleMark(text, start, end, mark) {
100
+ const marker = MARKDOWN_MARKS[mark];
101
+ const selected = text.slice(start, end);
102
+ const before = text.slice(0, start);
103
+ const after = text.slice(end);
104
+ // Already wrapped, either inside the selection or just outside it.
105
+ if (selected.startsWith(marker) &&
106
+ selected.endsWith(marker) &&
107
+ selected.length > marker.length * 2) {
108
+ const stripped = selected.slice(marker.length, -marker.length);
109
+ return {
110
+ text: before + stripped + after,
111
+ selectionStart: start,
112
+ selectionEnd: start + stripped.length,
113
+ };
114
+ }
115
+ if (before.endsWith(marker) && after.startsWith(marker)) {
116
+ return {
117
+ text: before.slice(0, -marker.length) + selected + after.slice(marker.length),
118
+ selectionStart: start - marker.length,
119
+ selectionEnd: end - marker.length,
120
+ };
121
+ }
122
+ // An empty selection inserts the pair and puts the cursor between them, so
123
+ // the button works before the words exist as well as after.
124
+ return {
125
+ text: `${before}${marker}${selected}${marker}${after}`,
126
+ selectionStart: start + marker.length,
127
+ selectionEnd: end + marker.length,
128
+ };
129
+ }
130
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,178 @@
1
+ import { type CSSProperties } from "react";
2
+ import { type MotionDuration } from "./tokens.js";
3
+ /**
4
+ * `prefers-reduced-motion: reduce`, read from the host document and kept live.
5
+ *
6
+ * A hook per animating component rather than a field on `ToolbarTheme`. The
7
+ * theme is a colour and elevation object that `themeFor` returns as one of two
8
+ * module constants; widening it to carry a motion preference would make it
9
+ * per-render, which is a real cost for a subscription that is free to
10
+ * duplicate.
11
+ */
12
+ export declare function usePrefersReducedMotion(): boolean;
13
+ /**
14
+ * False on the frame a surface mounts, true on the next one.
15
+ *
16
+ * This is the whole reason an inline `transition` is not enough on its own: a
17
+ * transition never runs on an element's FIRST style computation, so a surface
18
+ * that mounts already at `opacity: 1` has nothing to transition from. The
19
+ * `from` state has to be committed, painted, and only then replaced - which is
20
+ * one `requestAnimationFrame`.
21
+ *
22
+ * `requestAnimationFrame` rather than a layout effect that reads `offsetWidth`
23
+ * to force the same flush. Both work; the reflow version synchronously lays
24
+ * out the HOST page every time a reviewer opens a thread, and this package's
25
+ * standing rule is that it costs the page it is injected into as little as
26
+ * possible. Where there is no frame loop to wait for, the surface simply
27
+ * starts entered - a hard cut is the correct degradation.
28
+ *
29
+ * `settledAtMount` is DESIGN.md's first-mount rule for the one shape that
30
+ * cannot infer it. For a surface that MOUNTS when it opens, the mount is the
31
+ * reviewer's own click and there is nothing to distinguish - it enters, which
32
+ * is the default. For a surface mounted all session and toggled by a prop, an
33
+ * `active` that is already true on the first render is RESTORED STATE, not an
34
+ * action: the inbox sheet's open flag comes out of `localStorage`, so without
35
+ * this the sheet replayed its whole slide-in on every page the reviewer
36
+ * navigated to with it left open - "the toolbar animates itself in on every
37
+ * page load", which is the exact thing DESIGN.md forbids.
38
+ */
39
+ export declare function useEntered(active?: boolean, settledAtMount?: boolean): boolean;
40
+ /**
41
+ * The two-sided sibling of `useEntered`: false for one frame after `form`
42
+ * changes, true otherwise, and true on the very first render.
43
+ *
44
+ * For a surface that is REPLACED rather than opened. `useEntered` takes a
45
+ * boolean, so it can only re-arm in one direction - `active` going false means
46
+ * "this surface is gone" and its effect deliberately stops there. The bar's
47
+ * two forms (issue #22) are not open and closed: each of them is the current
48
+ * one, and whichever arrives has to enter, so the trigger is a value CHANGING
49
+ * rather than a flag going true.
50
+ *
51
+ * Settled on the first render, and here that is not an option a call site
52
+ * passes but the only correct answer: which form the bar is in comes out of
53
+ * `localStorage`, so a reviewer who collapsed it meets it collapsed on the
54
+ * next page - restored state, not an action - and a toolbar that replays its
55
+ * own collapse on every navigation is precisely what DESIGN.md's first-mount
56
+ * rule forbids. That is the bug `useEntered`'s `settledAtMount` was added for,
57
+ * one surface earlier.
58
+ *
59
+ * THE CALLER MUST REMOUNT THE ELEMENT IT STYLES - key it on the same `form`.
60
+ * Everything else in this file is used by a surface that mounts when it opens,
61
+ * which is why a transition can run on it at all: a transition never runs on
62
+ * an element's FIRST style computation, so the `from` state paints and the
63
+ * `to` state animates. A swap has no mount, so an element reused across it
64
+ * receives `opacity: 0` with the transition ALREADY declared, animates 1 -> 0,
65
+ * and gets reversed one frame later - a hard cut wearing a transition. This
66
+ * hook decides WHEN the from-state is committed; only a new element makes that
67
+ * commit instantaneous. See `BarContents` in FeedbackToolbar.tsx.
68
+ */
69
+ export declare function useSwapEntered(form: unknown): boolean;
70
+ /**
71
+ * "Was this one already here when the surface opened?", as a predicate.
72
+ *
73
+ * DESIGN.md's first-mount rule applied to a list: the replies already in a
74
+ * thread are pre-existing state and must not animate, or every reopen of an
75
+ * old thread replays the whole conversation arriving. Only the reply that
76
+ * lands while the reviewer is looking is new.
77
+ *
78
+ * The set is captured on the first render and never updated, which is the
79
+ * point - an id that arrives later stays "new" for as long as this surface is
80
+ * mounted, and the row it belongs to plays its enter exactly once because the
81
+ * row itself mounts exactly once.
82
+ */
83
+ export declare function useNewSinceMount(ids: readonly string[]): (id: string) => boolean;
84
+ export interface Presence {
85
+ /** Whether to render the surface at all. */
86
+ mounted: boolean;
87
+ /** Whether it is on its way out. */
88
+ leaving: boolean;
89
+ }
90
+ /**
91
+ * Keep a surface in the DOM for one exit duration after it closes, then take
92
+ * it out for real.
93
+ *
94
+ * The deferral is DOM REMOVAL ONLY. Whatever state change closed the surface
95
+ * has already been committed by the caller - `openPinId` is null, the sheet's
96
+ * store says closed - so nothing a reviewer did is waiting on an animation,
97
+ * which is DESIGN.md's "an exit never delays the action that triggered it".
98
+ *
99
+ * And the element really does leave. A surface parked at `opacity: 0` forever
100
+ * is markup in a host app's DOM that their own queries and audits trip over,
101
+ * and four e2e specs assert these surfaces reach zero elements - Playwright
102
+ * retries, so a deferred unmount passes and a permanent ghost does not.
103
+ *
104
+ * The latch is set during render rather than in an effect: "a prop changed, so
105
+ * derive some state from it" is React's own documented shape for this, it is
106
+ * what `PinLayer` already does for a focus request, and doing it in an effect
107
+ * would paint one frame of the closed surface still fully open.
108
+ *
109
+ * `exit` is the EXIT duration, and a caller that also drives `surfaceMotion`
110
+ * has to spell it the same way that helper does - `exitFor(<the enter step>)`
111
+ * - or the timer and the transition are two independent literals for the one
112
+ * value DESIGN.md calls "exactly the exit duration".
113
+ */
114
+ export declare function usePresence(open: boolean, exit: string): Presence;
115
+ /**
116
+ * True for one `instant` after `value` changes, and false on first mount.
117
+ *
118
+ * For acknowledging a number that moved rather than a surface that arrived:
119
+ * the unread badge, whose colours and position are identical before and after,
120
+ * so without this a count going 3 → 4 is a glyph swap nobody sees.
121
+ *
122
+ * A latch rather than an enter, and the difference matters: the element has
123
+ * been on screen for a while, so its resting state is already painted and a
124
+ * transition out of it runs immediately - no frame of `from` state to arrange,
125
+ * and therefore no `requestAnimationFrame`.
126
+ */
127
+ export declare function useJustChanged(value: unknown): boolean;
128
+ export interface SurfaceMotionOptions {
129
+ /** True once the surface has had its first frame. From `useEntered`. */
130
+ visible: boolean;
131
+ /** True while it is on its way out. From `usePresence`. */
132
+ leaving?: boolean;
133
+ /** From `usePrefersReducedMotion`. */
134
+ reduced: boolean;
135
+ /**
136
+ * `transform-origin`, relative to the surface's own box. Omitted means the
137
+ * default centre, which is right only for a surface with no anchor - see
138
+ * DESIGN.md: a surface opened by a click originates at the clicked pixel.
139
+ */
140
+ origin?: string;
141
+ /**
142
+ * Slide on this axis instead of scaling. `x` is a sheet coming in from the
143
+ * viewport's edge, `y` a message arriving from below.
144
+ */
145
+ slide?: "x" | "y";
146
+ /**
147
+ * The ENTER's duration, for the surface DESIGN.md's own duration table puts
148
+ * on a step other than `fast`. A token, never a literal - `MotionDuration`
149
+ * is the union of the three steps in `motion.duration`, so the only way to
150
+ * reach a value not in that object is to add it there first. It was declared
151
+ * `string`, which said the same thing in a comment and accepted `"140ms"`
152
+ * without complaint.
153
+ *
154
+ * Only the enter. "An exit is one step faster than its matching enter" is a
155
+ * rule from the same table and not a per-call-site decision, so there is
156
+ * deliberately no way to override the exit - it is DERIVED from this, by
157
+ * `exitFor` in tokens.ts. It used to be hard-coded `instant`, which was one
158
+ * step faster only for the surfaces already on `fast`; the moment issue #22
159
+ * put the bar's collapse on `settle`, the rule this comment states stopped
160
+ * being the rule the code applied.
161
+ */
162
+ duration?: MotionDuration;
163
+ }
164
+ /**
165
+ * Every entering and leaving surface in this package, styled from one place.
166
+ *
167
+ * A helper rather than five hand-written style fragments because "the same
168
+ * enter everywhere" is the point of having tokens at all, and because the
169
+ * three things easy to get wrong here - which properties are transitioned,
170
+ * which direction the easing runs, what reduced motion drops - are exactly the
171
+ * three a call site would restate slightly differently each time.
172
+ *
173
+ * Only `opacity` and `transform` appear. Both are handed to the compositor and
174
+ * reflow nothing, which is what lets this package animate at all over a host
175
+ * page nobody here wrote.
176
+ */
177
+ export declare function surfaceMotion({ visible, leaving, reduced, origin, slide, duration, }: SurfaceMotionOptions): CSSProperties;
178
+ //# sourceMappingURL=motion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion.d.ts","sourceRoot":"","sources":["../src/motion.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,OAAO,CAAC;AAEf,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,UAAU,CAAC;AAsClB;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAMjD;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CAAC,MAAM,UAAO,EAAE,cAAc,UAAQ,GAAG,OAAO,CA8BzE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAsBrD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,MAAM,EAAE,GACrB,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAMzB;AAID,MAAM,WAAW,QAAQ;IACvB,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAgBjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAkBtD;AAID,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;IACjB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,KAAK,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB;;;;;;;;;;;;;;;OAeG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,OAAe,EACf,OAAO,EACP,MAAM,EACN,KAAK,EACL,QAA+B,GAChC,EAAE,oBAAoB,GAAG,aAAa,CA6BtC"}