@q9labsai/chalk-react-native 4.1.11 → 4.1.13

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 (103) hide show
  1. package/dist/android.js +4 -2
  2. package/dist/{chunk-MMBE2BVK.js → chunk-4NLA35HE.js} +649 -407
  3. package/dist/{chunk-LZ67SXGB.js → chunk-MK6OO4V7.js} +6 -0
  4. package/dist/client.js +1 -1
  5. package/dist/components/Entrance.d.ts.map +1 -1
  6. package/dist/components/logo/Logo.d.ts +11 -0
  7. package/dist/components/logo/Logo.d.ts.map +1 -0
  8. package/dist/components/native-space-view/SpaceTopBar.android.d.ts.map +1 -1
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +4 -2
  12. package/dist/ios-pad.js +4 -2
  13. package/dist/ios-phone.js +4 -2
  14. package/dist/ios.js +4 -2
  15. package/dist/macos.js +4 -2
  16. package/package.json +4 -4
  17. package/src/callkit/callkit.test.ts +12 -10
  18. package/src/components/Entrance.tsx +2 -1
  19. package/src/components/logo/Logo.tsx +309 -0
  20. package/src/components/native-space-view/SpaceTopBar.android.tsx +2 -1
  21. package/src/index.ts +2 -0
  22. package/src/space-client/create-native-space-client.ts +8 -0
  23. package/dist/components/LogoElements.d.ts +0 -6
  24. package/dist/components/LogoElements.d.ts.map +0 -1
  25. package/dist/test-support/test-renderer.d.ts +0 -20
  26. package/dist/test-support/test-renderer.d.ts.map +0 -1
  27. package/src/android/connection-service.test.ts +0 -114
  28. package/src/callkit/resolve-space-callkit-options.test.ts +0 -68
  29. package/src/client.test.ts +0 -12
  30. package/src/clipboard.test.ts +0 -79
  31. package/src/components/Chalk.test.tsx +0 -223
  32. package/src/components/EmbeddedWhiteboard.test.tsx +0 -92
  33. package/src/components/Entrance.test.tsx +0 -19
  34. package/src/components/EntranceView.android.test.tsx +0 -100
  35. package/src/components/EntranceView.ios-pad.test.tsx +0 -160
  36. package/src/components/EntranceView.ios-phone.test.tsx +0 -137
  37. package/src/components/EntranceView.test.tsx +0 -15
  38. package/src/components/LogoElements.test.tsx +0 -60
  39. package/src/components/LogoElements.tsx +0 -119
  40. package/src/components/ReactionPicker.test.tsx +0 -19
  41. package/src/components/RtcVideoView.test.tsx +0 -12
  42. package/src/components/SpaceView.android.test.tsx +0 -11
  43. package/src/components/SpaceView.ios-pad.test.tsx +0 -11
  44. package/src/components/SpaceView.ios-phone.test.tsx +0 -11
  45. package/src/components/SpaceView.macos.test.tsx +0 -11
  46. package/src/components/SpaceView.shared.test.tsx +0 -116
  47. package/src/components/SpaceView.test.tsx +0 -15
  48. package/src/components/android-connection-service-controller.test.ts +0 -80
  49. package/src/components/episode-diagnostic-render-observer.test.ts +0 -24
  50. package/src/components/native-animation-controller.test.ts +0 -47
  51. package/src/components/native-chat.test.ts +0 -22
  52. package/src/components/native-entrance/entrance-controller-store.test.ts +0 -75
  53. package/src/components/native-media-visibility.test.ts +0 -77
  54. package/src/components/native-space-callkit-controller.test.ts +0 -62
  55. package/src/components/native-space-view/AppearanceSettings.test.tsx +0 -56
  56. package/src/components/native-space-view/ParticipantActionSheet.test.tsx +0 -18
  57. package/src/components/native-space-view/SettingsSheet.test.tsx +0 -17
  58. package/src/components/native-space-view/SpaceActionMenu.test.tsx +0 -126
  59. package/src/components/native-space-view/SpaceBottomDock.android.test.tsx +0 -61
  60. package/src/components/native-space-view/SpaceChatSheet.test.tsx +0 -18
  61. package/src/components/native-space-view/SpaceMoreSheet.test.tsx +0 -15
  62. package/src/components/native-space-view/SpacePanelSheet.test.tsx +0 -15
  63. package/src/components/native-space-view/SpacePeopleSheet.test.tsx +0 -13
  64. package/src/components/native-space-view/SpaceSurfacePrimitives.test.tsx +0 -12
  65. package/src/components/native-space-view/SpaceTopBar.android.test.tsx +0 -43
  66. package/src/components/native-space-view/SpaceWhiteboardSurface.test.tsx +0 -85
  67. package/src/components/native-space-view/diagnostics.test.ts +0 -31
  68. package/src/components/native-space-view/format-space-duration.test.ts +0 -13
  69. package/src/components/native-space-view/native-space-grid-keys.test.ts +0 -11
  70. package/src/components/native-space-view/native-space-page-store.test.ts +0 -23
  71. package/src/components/native-space-view/space-chat-attachments.test.ts +0 -33
  72. package/src/components/native-space-view/space-progressive-surface-helpers.test.ts +0 -24
  73. package/src/components/native-space-view/useSpaceViewController.contract.test.ts +0 -10
  74. package/src/components/native-space-view/useSpaceViewController.test.ts +0 -106
  75. package/src/components/native-space-view/useSpaceViewDerived.test.ts +0 -58
  76. package/src/components/native-space-view/useSpaceViewPanels.controlled.test.ts +0 -40
  77. package/src/components/native-space-view/useSpaceViewPanels.test.ts +0 -73
  78. package/src/components/space-lifecycle.test.ts +0 -19
  79. package/src/context/space-client-context.test.tsx +0 -10
  80. package/src/diagnostics.test.ts +0 -29
  81. package/src/hooks/entrance-preview-store.test.ts +0 -79
  82. package/src/hooks/space-hooks.test.ts +0 -76
  83. package/src/hooks/useLayout.test.ts +0 -16
  84. package/src/invites.test.ts +0 -51
  85. package/src/public-surface.test.ts +0 -26
  86. package/src/runtime.test.ts +0 -83
  87. package/src/space-client/cloudflare-rtk-native.test.ts +0 -118
  88. package/src/space-client/create-native-space-client.test.ts +0 -300
  89. package/src/telemetry.test.ts +0 -143
  90. package/src/test-support/test-renderer.test.ts +0 -9
  91. package/src/test-support/test-renderer.ts +0 -28
  92. package/src/ui/appearance.test.ts +0 -61
  93. package/src/ui/native-appearance-context.controlled.test.tsx +0 -41
  94. package/src/ui/native-appearance-context.test.tsx +0 -14
  95. package/src/ui/native-theme.test.ts +0 -34
  96. package/src/ui/native-theme.test.tsx +0 -14
  97. package/src/ui/participant-avatar.test.ts +0 -29
  98. package/src/ui/theme-tokens.test.ts +0 -14
  99. package/src/ui/theme.test.ts +0 -36
  100. package/src/utils/build-chalk-invite-link.test.ts +0 -12
  101. package/src/utils/ios-simulator.test.ts +0 -96
  102. package/src/utils/native-space-layout.test.ts +0 -170
  103. package/src/whiteboard/embedded-whiteboard-assets.test.ts +0 -31
@@ -362,6 +362,7 @@ function createMediaClient(apiBaseURL, input, fetch, observePeerConnection, jour
362
362
  });
363
363
  return createRTKConnectionMediaClient(client2);
364
364
  }
365
+ const replaceMediaConnection = input.replaceMediaConnection;
365
366
  const client = new CloudflareSFUClient({
366
367
  bootstrap: input.access.media.clientPayload,
367
368
  participantId: subject.participantId,
@@ -374,6 +375,11 @@ function createMediaClient(apiBaseURL, input, fetch, observePeerConnection, jour
374
375
  participantId: subject.participantId,
375
376
  fetch
376
377
  }),
378
+ replaceMediaConnection: replaceMediaConnection ? async () => {
379
+ const replacement = await replaceMediaConnection();
380
+ if (replacement.provider !== "cloudflare_sfu") throw new TypeError("The Cloudflare SFU adapter requires a Cloudflare SFU access grant");
381
+ return replacement.clientPayload;
382
+ } : void 0,
377
383
  peerConnectionFactory: (configuration) => {
378
384
  const connection = new RTCPeerConnection(configuration);
379
385
  observePeerConnection?.(connection);
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createNativeSpaceClient
3
- } from "./chunk-LZ67SXGB.js";
3
+ } from "./chunk-MK6OO4V7.js";
4
4
  export {
5
5
  createNativeSpaceClient
6
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Entrance.d.ts","sourceRoot":"","sources":["../../src/components/Entrance.tsx"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAczJ"}
1
+ {"version":3,"file":"Entrance.d.ts","sourceRoot":"","sources":["../../src/components/Entrance.tsx"],"names":[],"mappings":"AAIA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAe,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAczJ"}
@@ -0,0 +1,11 @@
1
+ export type LogoMotion = "orbit-burst" | "none";
2
+ export type LogoVariant = "mark" | "wordmark";
3
+ export interface LogoProps {
4
+ readonly accessibilityLabel?: string | null;
5
+ readonly color?: string;
6
+ readonly height?: number;
7
+ readonly motion?: LogoMotion;
8
+ readonly variant?: LogoVariant;
9
+ }
10
+ export declare function Logo({ accessibilityLabel, color, height, motion, variant }: LogoProps): React.JSX.Element;
11
+ //# sourceMappingURL=Logo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logo.d.ts","sourceRoot":"","sources":["../../../src/components/logo/Logo.tsx"],"names":[],"mappings":"AAMA,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,MAAM,CAAC;AAChD,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;AAE9C,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC;CAChC;AAoLD,wBAAgB,IAAI,CAAC,EAAE,kBAA4B,EAAE,KAAqB,EAAE,MAAuB,EAAE,MAAuB,EAAE,OAAyB,EAAE,EAAE,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAiHvL"}
@@ -1 +1 @@
1
- {"version":3,"file":"SpaceTopBar.android.d.ts","sourceRoot":"","sources":["../../../src/components/native-space-view/SpaceTopBar.android.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAoBnI;AAED,OAAO,EAAE,kBAAkB,IAAI,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"SpaceTopBar.android.d.ts","sourceRoot":"","sources":["../../../src/components/native-space-view/SpaceTopBar.android.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,OAAO,EAAE,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CAoBnI;AAED,OAAO,EAAE,kBAAkB,IAAI,WAAW,EAAE,CAAC"}
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { Chalk } from "./components/Chalk";
2
2
  export type { ChalkFeatures, ChalkProps, ChalkTheme, ChalkThemeTokens, SpaceLayout } from "./components/Chalk";
3
3
  export { Entrance } from "./components/Entrance";
4
4
  export type { EntranceProps, EntranceSettings } from "./components/Entrance";
5
+ export { Logo } from "./components/logo/Logo";
6
+ export type { LogoMotion, LogoProps, LogoVariant } from "./components/logo/Logo";
5
7
  export { ChalkProvider, useSpaceClient } from "./context/space-client-context";
6
8
  export type { ChalkProviderProps } from "./context/space-client-context";
7
9
  export { useCan, useChat, useConnection, useMedia, useParticipants, useReactions, useSelf, useWhiteboard } from "./hooks/space-hooks";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC/E,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtI,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC3G,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5H,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC/E,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtI,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC3G,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC5H,YAAY,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,eAAe,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  Chalk,
3
3
  ChalkProvider,
4
4
  Entrance,
5
+ Logo,
5
6
  buildChalkInviteLink,
6
7
  useCan,
7
8
  useChat,
@@ -12,7 +13,7 @@ import {
12
13
  useSelf,
13
14
  useSpaceClient,
14
15
  useWhiteboard
15
- } from "./chunk-MMBE2BVK.js";
16
+ } from "./chunk-4NLA35HE.js";
16
17
  import {
17
18
  THEME_PALETTES,
18
19
  THEME_TEXTURES,
@@ -24,7 +25,7 @@ import {
24
25
  Theme,
25
26
  createNativeTheme
26
27
  } from "./chunk-JB4LNWVP.js";
27
- import "./chunk-LZ67SXGB.js";
28
+ import "./chunk-MK6OO4V7.js";
28
29
  import {
29
30
  extractSpaceInviteFromLink,
30
31
  getClipboardInviteSuggestion,
@@ -34,6 +35,7 @@ export {
34
35
  Chalk,
35
36
  ChalkProvider,
36
37
  Entrance,
38
+ Logo,
37
39
  THEME_PALETTES,
38
40
  THEME_TEXTURES,
39
41
  Theme,
package/dist/ios-pad.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  Chalk,
3
3
  ChalkProvider,
4
4
  Entrance,
5
+ Logo,
5
6
  buildChalkInviteLink,
6
7
  useCan,
7
8
  useChat,
@@ -12,7 +13,7 @@ import {
12
13
  useSelf,
13
14
  useSpaceClient,
14
15
  useWhiteboard
15
- } from "./chunk-MMBE2BVK.js";
16
+ } from "./chunk-4NLA35HE.js";
16
17
  import {
17
18
  THEME_PALETTES,
18
19
  THEME_TEXTURES,
@@ -24,7 +25,7 @@ import {
24
25
  Theme,
25
26
  createNativeTheme
26
27
  } from "./chunk-JB4LNWVP.js";
27
- import "./chunk-LZ67SXGB.js";
28
+ import "./chunk-MK6OO4V7.js";
28
29
  import {
29
30
  extractSpaceInviteFromLink,
30
31
  getClipboardInviteSuggestion,
@@ -34,6 +35,7 @@ export {
34
35
  Chalk,
35
36
  ChalkProvider,
36
37
  Entrance,
38
+ Logo,
37
39
  THEME_PALETTES,
38
40
  THEME_TEXTURES,
39
41
  Theme,
package/dist/ios-phone.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  Chalk,
3
3
  ChalkProvider,
4
4
  Entrance,
5
+ Logo,
5
6
  buildChalkInviteLink,
6
7
  useCan,
7
8
  useChat,
@@ -12,7 +13,7 @@ import {
12
13
  useSelf,
13
14
  useSpaceClient,
14
15
  useWhiteboard
15
- } from "./chunk-MMBE2BVK.js";
16
+ } from "./chunk-4NLA35HE.js";
16
17
  import {
17
18
  THEME_PALETTES,
18
19
  THEME_TEXTURES,
@@ -24,7 +25,7 @@ import {
24
25
  Theme,
25
26
  createNativeTheme
26
27
  } from "./chunk-JB4LNWVP.js";
27
- import "./chunk-LZ67SXGB.js";
28
+ import "./chunk-MK6OO4V7.js";
28
29
  import {
29
30
  extractSpaceInviteFromLink,
30
31
  getClipboardInviteSuggestion,
@@ -34,6 +35,7 @@ export {
34
35
  Chalk,
35
36
  ChalkProvider,
36
37
  Entrance,
38
+ Logo,
37
39
  THEME_PALETTES,
38
40
  THEME_TEXTURES,
39
41
  Theme,
package/dist/ios.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  Chalk,
3
3
  ChalkProvider,
4
4
  Entrance,
5
+ Logo,
5
6
  buildChalkInviteLink,
6
7
  useCan,
7
8
  useChat,
@@ -12,7 +13,7 @@ import {
12
13
  useSelf,
13
14
  useSpaceClient,
14
15
  useWhiteboard
15
- } from "./chunk-MMBE2BVK.js";
16
+ } from "./chunk-4NLA35HE.js";
16
17
  import {
17
18
  THEME_PALETTES,
18
19
  THEME_TEXTURES,
@@ -24,7 +25,7 @@ import {
24
25
  Theme,
25
26
  createNativeTheme
26
27
  } from "./chunk-JB4LNWVP.js";
27
- import "./chunk-LZ67SXGB.js";
28
+ import "./chunk-MK6OO4V7.js";
28
29
  import {
29
30
  extractSpaceInviteFromLink,
30
31
  getClipboardInviteSuggestion,
@@ -34,6 +35,7 @@ export {
34
35
  Chalk,
35
36
  ChalkProvider,
36
37
  Entrance,
38
+ Logo,
37
39
  THEME_PALETTES,
38
40
  THEME_TEXTURES,
39
41
  Theme,
package/dist/macos.js CHANGED
@@ -2,6 +2,7 @@ import {
2
2
  Chalk,
3
3
  ChalkProvider,
4
4
  Entrance,
5
+ Logo,
5
6
  buildChalkInviteLink,
6
7
  useCan,
7
8
  useChat,
@@ -12,7 +13,7 @@ import {
12
13
  useSelf,
13
14
  useSpaceClient,
14
15
  useWhiteboard
15
- } from "./chunk-MMBE2BVK.js";
16
+ } from "./chunk-4NLA35HE.js";
16
17
  import {
17
18
  THEME_PALETTES,
18
19
  THEME_TEXTURES,
@@ -24,7 +25,7 @@ import {
24
25
  Theme,
25
26
  createNativeTheme
26
27
  } from "./chunk-JB4LNWVP.js";
27
- import "./chunk-LZ67SXGB.js";
28
+ import "./chunk-MK6OO4V7.js";
28
29
  import {
29
30
  extractSpaceInviteFromLink,
30
31
  getClipboardInviteSuggestion,
@@ -34,6 +35,7 @@ export {
34
35
  Chalk,
35
36
  ChalkProvider,
36
37
  Entrance,
38
+ Logo,
37
39
  THEME_PALETTES,
38
40
  THEME_TEXTURES,
39
41
  Theme,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@q9labsai/chalk-react-native",
3
- "version": "4.1.11",
3
+ "version": "4.1.13",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -150,9 +150,9 @@
150
150
  "registry": "https://registry.npmjs.org/"
151
151
  },
152
152
  "dependencies": {
153
- "@q9labsai/chalk-client": "^4.1.11",
154
- "@q9labsai/chalk-whiteboard": "^4.1.11",
155
- "@q9labsai/facehash": "^4.1.11"
153
+ "@q9labsai/chalk-client": "^4.1.13",
154
+ "@q9labsai/chalk-whiteboard": "^4.1.13",
155
+ "@q9labsai/facehash": "^4.1.13"
156
156
  },
157
157
  "devDependencies": {
158
158
  "@types/node": "^26.2.0",
@@ -2,23 +2,17 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
2
2
 
3
3
  const addListener = vi.fn();
4
4
  const configure = vi.fn(async () => ({ isSupported: true }));
5
- const endAllCalls = vi.fn(async () => undefined);
6
5
  const endCall = vi.fn(async () => undefined);
7
6
  const reportConnected = vi.fn(async () => undefined);
8
- const reportIncomingCall = vi.fn(async () => ({ callUUID: "incoming-uuid" }));
9
7
  const startCall = vi.fn(async () => ({ callUUID: "outgoing-uuid" }));
10
- const updateCall = vi.fn(async () => undefined);
11
8
 
12
9
  const nativeModule = {
13
10
  configure,
14
- endAllCalls,
15
11
  endCall,
16
12
  eventName: "ChalkCallKitEvent",
17
13
  isSupported: true,
18
14
  reportConnected,
19
- reportIncomingCall,
20
15
  startCall,
21
- updateCall,
22
16
  };
23
17
 
24
18
  const eventEmitter = {
@@ -45,12 +39,9 @@ describe("callKit", () => {
45
39
  nativeModule.isSupported = true;
46
40
  addListener.mockReset();
47
41
  configure.mockClear();
48
- endAllCalls.mockClear();
49
42
  endCall.mockClear();
50
43
  reportConnected.mockClear();
51
- reportIncomingCall.mockClear();
52
44
  startCall.mockClear();
53
- updateCall.mockClear();
54
45
  });
55
46
 
56
47
  it("uses the native event emitter when the iOS module is available", async () => {
@@ -79,17 +70,28 @@ describe("callKit", () => {
79
70
  expect(startCall).not.toHaveBeenCalled();
80
71
  });
81
72
 
82
- it("passes configuration through to the native bridge", async () => {
73
+ it("forwards controller-facing calls and preserves native failures", async () => {
83
74
  const { callKit } = await import("./callkit");
75
+ const callOptions = { callUUID: "call-uuid", displayName: "Space", handle: "space-123", hasVideo: true };
84
76
 
85
77
  await callKit.configure({
86
78
  appName: "Chalk",
87
79
  includesCallsInRecents: false,
88
80
  });
81
+ await expect(callKit.startCall(callOptions)).resolves.toEqual({ callUUID: "outgoing-uuid" });
82
+ await callKit.reportConnected({ callUUID: "outgoing-uuid" });
83
+ await callKit.endCall({ callUUID: "outgoing-uuid", reason: "remoteEnded" });
89
84
 
90
85
  expect(configure).toHaveBeenCalledWith({
91
86
  appName: "Chalk",
92
87
  includesCallsInRecents: false,
93
88
  });
89
+ expect(startCall).toHaveBeenCalledWith(callOptions);
90
+ expect(reportConnected).toHaveBeenCalledWith({ callUUID: "outgoing-uuid" });
91
+ expect(endCall).toHaveBeenCalledWith({ callUUID: "outgoing-uuid", reason: "remoteEnded" });
92
+
93
+ const nativeFailure = new Error("CallKit unavailable");
94
+ startCall.mockRejectedValueOnce(nativeFailure);
95
+ await expect(callKit.startCall(callOptions)).rejects.toBe(nativeFailure);
94
96
  });
95
97
  });
@@ -1,5 +1,6 @@
1
1
  import { EntranceView } from "./EntranceView";
2
2
  import { Image } from "react-native";
3
+ import { Logo } from "./logo/Logo";
3
4
 
4
5
  export type EntranceDefaults = {
5
6
  readonly microphone?: boolean;
@@ -31,7 +32,7 @@ export function Entrance({ spaceName, logoUrl, defaultDisplayName, defaults, err
31
32
  initialAudioEnabled={defaults?.microphone ?? true}
32
33
  initialVideoEnabled={defaults?.camera ?? true}
33
34
  joinDisabled={joining}
34
- logo={logoUrl ? <Image accessibilityLabel="Chalk" source={{ uri: logoUrl }} style={{ height: 32, width: 120 }} /> : undefined}
35
+ logo={logoUrl ? <Image accessibilityLabel="Chalk" source={{ uri: logoUrl }} style={{ height: 32, width: 120 }} /> : <Logo height={32} variant="wordmark" />}
35
36
  onCancel={onCancel}
36
37
  onJoin={({ displayName, microphoneEnabled, cameraEnabled }) => void onJoin({ displayName, microphone: microphoneEnabled, camera: cameraEnabled })}
37
38
  spaceName={spaceName}
@@ -0,0 +1,309 @@
1
+ import { useEffect, useId, useRef, useState } from "react";
2
+ import { AccessibilityInfo, Animated, Pressable } from "react-native";
3
+ import Svg, { Defs, Ellipse, G, LinearGradient, Path, Stop, Text as SvgText } from "react-native-svg";
4
+
5
+ const AnimatedG = Animated.createAnimatedComponent(G);
6
+
7
+ export type LogoMotion = "orbit-burst" | "none";
8
+ export type LogoVariant = "mark" | "wordmark";
9
+
10
+ export interface LogoProps {
11
+ readonly accessibilityLabel?: string | null;
12
+ readonly color?: string;
13
+ readonly height?: number;
14
+ readonly motion?: LogoMotion;
15
+ readonly variant?: LogoVariant;
16
+ }
17
+
18
+ interface InteractionState {
19
+ readonly focus: boolean;
20
+ readonly hover: boolean;
21
+ readonly press: boolean;
22
+ }
23
+
24
+ interface StickAnimationValues {
25
+ readonly rotation: Animated.Value;
26
+ readonly scaleX: Animated.Value;
27
+ readonly scaleY: Animated.Value;
28
+ readonly translateX: Animated.Value;
29
+ readonly translateY: Animated.Value;
30
+ }
31
+
32
+ type StickAnimationValuesTuple = readonly [StickAnimationValues, StickAnimationValues, StickAnimationValues, StickAnimationValues];
33
+
34
+ interface StickMotion {
35
+ readonly burstRotation: number;
36
+ readonly burstScale: number;
37
+ readonly burstSettleRotation: number;
38
+ readonly burstSettleScale: number;
39
+ readonly burstSettleX: number;
40
+ readonly burstSettleY: number;
41
+ readonly burstX: number;
42
+ readonly burstY: number;
43
+ readonly orbitRotation: readonly [number, number, number, number];
44
+ readonly orbitX: readonly [number, number, number, number];
45
+ readonly orbitY: readonly [number, number, number, number];
46
+ readonly originX: number;
47
+ readonly originY: number;
48
+ readonly transform: string;
49
+ }
50
+
51
+ const STICK_MOTIONS: readonly [StickMotion, StickMotion, StickMotion, StickMotion] = [
52
+ {
53
+ transform: "rotate(-15 20 60)",
54
+ originX: 15,
55
+ originY: 42,
56
+ orbitRotation: [0, -5, 0, 0],
57
+ orbitX: [0, -4, 0, 0],
58
+ orbitY: [0, 3, 0, 0],
59
+ burstRotation: -8,
60
+ burstScale: 1.14,
61
+ burstSettleRotation: 2,
62
+ burstSettleScale: 0.98,
63
+ burstSettleX: -2,
64
+ burstSettleY: 2,
65
+ burstX: -14,
66
+ burstY: -9,
67
+ },
68
+ {
69
+ transform: "rotate(-8 32 55)",
70
+ originX: 29,
71
+ originY: 38,
72
+ orbitRotation: [0, 4, 0, 0],
73
+ orbitX: [0, 3, 0, 0],
74
+ orbitY: [0, -4, 0, 0],
75
+ burstRotation: -4,
76
+ burstScale: 1.14,
77
+ burstSettleRotation: 1,
78
+ burstSettleScale: 0.98,
79
+ burstSettleX: 1,
80
+ burstSettleY: 1,
81
+ burstX: -4,
82
+ burstY: -14,
83
+ },
84
+ {
85
+ transform: "rotate(12 60 30)",
86
+ originX: 42,
87
+ originY: 32,
88
+ orbitRotation: [0, 5, 0, 0],
89
+ orbitX: [0, 5, 0, 0],
90
+ orbitY: [0, 2, 0, 0],
91
+ burstRotation: 8,
92
+ burstScale: 1.16,
93
+ burstSettleRotation: -2,
94
+ burstSettleScale: 0.98,
95
+ burstSettleX: 2,
96
+ burstSettleY: 1,
97
+ burstX: 14,
98
+ burstY: -6,
99
+ },
100
+ {
101
+ transform: "rotate(5 55 50)",
102
+ originX: 55,
103
+ originY: 50,
104
+ orbitRotation: [0, -4, 0, 0],
105
+ orbitX: [0, -3, 0, 0],
106
+ orbitY: [0, -3, 0, 0],
107
+ burstRotation: 7,
108
+ burstScale: 1.13,
109
+ burstSettleRotation: -1,
110
+ burstSettleScale: 0.98,
111
+ burstSettleX: 1,
112
+ burstSettleY: -1,
113
+ burstX: 11,
114
+ burstY: 12,
115
+ },
116
+ ];
117
+
118
+ const ORBIT_DURATION = 4800;
119
+ const BURST_DURATION = 1100;
120
+ const DEFAULT_COLOR = "#1A332B";
121
+ const DEFAULT_HEIGHT = 32;
122
+ const DEFAULT_MOTION: LogoMotion = "orbit-burst";
123
+ const DEFAULT_VARIANT: LogoVariant = "wordmark";
124
+ const WORDMARK_VIEW_BOX = "0 0 200 80";
125
+ const MARK_VIEW_BOX = "0 0 68 80";
126
+
127
+ function createStickAnimationValues(): StickAnimationValuesTuple {
128
+ return [
129
+ { rotation: new Animated.Value(0), scaleX: new Animated.Value(1), scaleY: new Animated.Value(1), translateX: new Animated.Value(0), translateY: new Animated.Value(0) },
130
+ { rotation: new Animated.Value(0), scaleX: new Animated.Value(1), scaleY: new Animated.Value(1), translateX: new Animated.Value(0), translateY: new Animated.Value(0) },
131
+ { rotation: new Animated.Value(0), scaleX: new Animated.Value(1), scaleY: new Animated.Value(1), translateX: new Animated.Value(0), translateY: new Animated.Value(0) },
132
+ { rotation: new Animated.Value(0), scaleX: new Animated.Value(1), scaleY: new Animated.Value(1), translateX: new Animated.Value(0), translateY: new Animated.Value(0) },
133
+ ];
134
+ }
135
+
136
+ function createOrbitAnimation(stick: StickAnimationValues, motion: StickMotion, index: number): Animated.CompositeAnimation {
137
+ const keyframes = [
138
+ Animated.parallel([
139
+ Animated.timing(stick.rotation, { duration: ORBIT_DURATION / 2, toValue: motion.orbitRotation[1], useNativeDriver: true }),
140
+ Animated.timing(stick.translateX, { duration: ORBIT_DURATION / 2, toValue: motion.orbitX[1], useNativeDriver: true }),
141
+ Animated.timing(stick.translateY, { duration: ORBIT_DURATION / 2, toValue: motion.orbitY[1], useNativeDriver: true }),
142
+ ]),
143
+ Animated.parallel([
144
+ Animated.timing(stick.rotation, { duration: ORBIT_DURATION / 2, toValue: motion.orbitRotation[2], useNativeDriver: true }),
145
+ Animated.timing(stick.translateX, { duration: ORBIT_DURATION / 2, toValue: motion.orbitX[2], useNativeDriver: true }),
146
+ Animated.timing(stick.translateY, { duration: ORBIT_DURATION / 2, toValue: motion.orbitY[2], useNativeDriver: true }),
147
+ ]),
148
+ ];
149
+
150
+ return Animated.sequence([Animated.delay(index * 90), Animated.loop(Animated.sequence(keyframes))]);
151
+ }
152
+
153
+ function createBurstAnimation(stick: StickAnimationValues, motion: StickMotion): Animated.CompositeAnimation {
154
+ return Animated.loop(
155
+ Animated.sequence([
156
+ Animated.parallel([
157
+ Animated.timing(stick.rotation, { duration: BURST_DURATION * 0.24, toValue: motion.burstRotation, useNativeDriver: true }),
158
+ Animated.timing(stick.scaleX, { duration: BURST_DURATION * 0.24, toValue: motion.burstScale, useNativeDriver: true }),
159
+ Animated.timing(stick.scaleY, { duration: BURST_DURATION * 0.24, toValue: motion.burstScale, useNativeDriver: true }),
160
+ Animated.timing(stick.translateX, { duration: BURST_DURATION * 0.24, toValue: motion.burstX, useNativeDriver: true }),
161
+ Animated.timing(stick.translateY, { duration: BURST_DURATION * 0.24, toValue: motion.burstY, useNativeDriver: true }),
162
+ ]),
163
+ Animated.parallel([
164
+ Animated.timing(stick.rotation, { duration: BURST_DURATION * 0.25, toValue: motion.burstSettleRotation, useNativeDriver: true }),
165
+ Animated.timing(stick.scaleX, { duration: BURST_DURATION * 0.25, toValue: motion.burstSettleScale, useNativeDriver: true }),
166
+ Animated.timing(stick.scaleY, { duration: BURST_DURATION * 0.25, toValue: motion.burstSettleScale, useNativeDriver: true }),
167
+ Animated.timing(stick.translateX, { duration: BURST_DURATION * 0.25, toValue: motion.burstSettleX, useNativeDriver: true }),
168
+ Animated.timing(stick.translateY, { duration: BURST_DURATION * 0.25, toValue: motion.burstSettleY, useNativeDriver: true }),
169
+ ]),
170
+ Animated.parallel([
171
+ Animated.timing(stick.rotation, { duration: BURST_DURATION * 0.33, toValue: 0, useNativeDriver: true }),
172
+ Animated.timing(stick.scaleX, { duration: BURST_DURATION * 0.33, toValue: 1, useNativeDriver: true }),
173
+ Animated.timing(stick.scaleY, { duration: BURST_DURATION * 0.33, toValue: 1, useNativeDriver: true }),
174
+ Animated.timing(stick.translateX, { duration: BURST_DURATION * 0.33, toValue: 0, useNativeDriver: true }),
175
+ Animated.timing(stick.translateY, { duration: BURST_DURATION * 0.33, toValue: 0, useNativeDriver: true }),
176
+ ]),
177
+ ]),
178
+ );
179
+ }
180
+
181
+ function resetStickAnimationValues(values: readonly StickAnimationValues[]): void {
182
+ for (const stick of values) {
183
+ stick.rotation.stopAnimation();
184
+ stick.scaleX.stopAnimation();
185
+ stick.scaleY.stopAnimation();
186
+ stick.translateX.stopAnimation();
187
+ stick.translateY.stopAnimation();
188
+ stick.rotation.setValue(0);
189
+ stick.scaleX.setValue(1);
190
+ stick.scaleY.setValue(1);
191
+ stick.translateX.setValue(0);
192
+ stick.translateY.setValue(0);
193
+ }
194
+ }
195
+
196
+ export function Logo({ accessibilityLabel = "Chalk", color = DEFAULT_COLOR, height = DEFAULT_HEIGHT, motion = DEFAULT_MOTION, variant = DEFAULT_VARIANT }: LogoProps): React.JSX.Element {
197
+ const [reducedMotion, setReducedMotion] = useState<boolean | null>(null);
198
+ const [interaction, setInteraction] = useState<InteractionState>({ focus: false, hover: false, press: false });
199
+ const idPrefix = `chalk-logo-${useId().replace(/[^a-zA-Z0-9_-]/gu, "")}`;
200
+ const animationValues = useRef<StickAnimationValuesTuple | null>(null);
201
+ if (animationValues.current === null) {
202
+ animationValues.current = createStickAnimationValues();
203
+ }
204
+
205
+ const sticks = animationValues.current;
206
+ const interactionActive = interaction.focus || interaction.hover || interaction.press;
207
+ const animate = motion === "orbit-burst" && reducedMotion === false;
208
+
209
+ useEffect(() => {
210
+ let cancelled = false;
211
+ const subscription = AccessibilityInfo.addEventListener("reduceMotionChanged", setReducedMotion);
212
+
213
+ void AccessibilityInfo.isReduceMotionEnabled().then((enabled) => {
214
+ if (!cancelled) {
215
+ setReducedMotion(enabled);
216
+ }
217
+ });
218
+
219
+ return () => {
220
+ cancelled = true;
221
+ subscription.remove();
222
+ };
223
+ }, []);
224
+
225
+ useEffect(() => {
226
+ if (!animate) {
227
+ resetStickAnimationValues(sticks);
228
+ return;
229
+ }
230
+
231
+ const animations = interactionActive
232
+ ? [createBurstAnimation(sticks[0], STICK_MOTIONS[0]), createBurstAnimation(sticks[1], STICK_MOTIONS[1]), createBurstAnimation(sticks[2], STICK_MOTIONS[2]), createBurstAnimation(sticks[3], STICK_MOTIONS[3])]
233
+ : [createOrbitAnimation(sticks[0], STICK_MOTIONS[0], 0), createOrbitAnimation(sticks[1], STICK_MOTIONS[1], 1), createOrbitAnimation(sticks[2], STICK_MOTIONS[2], 2), createOrbitAnimation(sticks[3], STICK_MOTIONS[3], 3)];
234
+ const animation = Animated.parallel(animations);
235
+ animation.start();
236
+
237
+ return () => {
238
+ animation.stop();
239
+ };
240
+ }, [animate, interactionActive, sticks]);
241
+
242
+ const setInteractionFlag = (key: keyof InteractionState, value: boolean): void => {
243
+ setInteraction((current) => (current[key] === value ? current : { ...current, [key]: value }));
244
+ };
245
+ const width = variant === "wordmark" ? height * 2.5 : height * (68 / 80);
246
+ const viewBox = variant === "wordmark" ? WORDMARK_VIEW_BOX : MARK_VIEW_BOX;
247
+ const accessible = accessibilityLabel !== null;
248
+
249
+ return (
250
+ <Pressable
251
+ accessible={false}
252
+ onBlur={() => setInteractionFlag("focus", false)}
253
+ onFocus={() => setInteractionFlag("focus", true)}
254
+ onHoverIn={() => setInteractionFlag("hover", true)}
255
+ onHoverOut={() => setInteractionFlag("hover", false)}
256
+ onPressIn={() => setInteractionFlag("press", true)}
257
+ onPressOut={() => setInteractionFlag("press", false)}
258
+ >
259
+ <Svg accessibilityLabel={accessible ? (accessibilityLabel ?? undefined) : undefined} accessible={accessible} color={color} fill="none" focusable={false} height={height} viewBox={viewBox} width={width}>
260
+ <Defs>
261
+ <LinearGradient id={`${idPrefix}-green`} x1="0%" x2="100%" y1="0%" y2="0%">
262
+ <Stop offset="0%" stopColor="#C5E5C0" />
263
+ <Stop offset="100%" stopColor="#80B879" />
264
+ </LinearGradient>
265
+ <LinearGradient id={`${idPrefix}-yellow`} x1="0%" x2="100%" y1="0%" y2="0%">
266
+ <Stop offset="0%" stopColor="#FCEAB3" />
267
+ <Stop offset="100%" stopColor="#D9B641" />
268
+ </LinearGradient>
269
+ <LinearGradient id={`${idPrefix}-blue`} x1="0%" x2="100%" y1="0%" y2="0%">
270
+ <Stop offset="0%" stopColor="#B2E0F0" />
271
+ <Stop offset="100%" stopColor="#55AAC9" />
272
+ </LinearGradient>
273
+ <LinearGradient id={`${idPrefix}-pink`} x1="0%" x2="100%" y1="0%" y2="0%">
274
+ <Stop offset="0%" stopColor="#F8CACA" />
275
+ <Stop offset="100%" stopColor="#D67B7B" />
276
+ </LinearGradient>
277
+ </Defs>
278
+
279
+ <G transform="translate(2, 2) scale(0.95)">
280
+ <AnimatedG originX={STICK_MOTIONS[0].originX} originY={STICK_MOTIONS[0].originY} rotation={sticks[0].rotation} scaleX={sticks[0].scaleX} scaleY={sticks[0].scaleY} transform={STICK_MOTIONS[0].transform} translateX={sticks[0].translateX} translateY={sticks[0].translateY}>
281
+ <Path d="M9,20 L21,20 L22,63 A7,7 0 0 1 8,63 Z" fill={`url(#${idPrefix}-green)`} />
282
+ <Ellipse cx="15" cy="20" fill="#D8ECD4" rx="6" ry="2.5" />
283
+ </AnimatedG>
284
+
285
+ <AnimatedG originX={STICK_MOTIONS[1].originX} originY={STICK_MOTIONS[1].originY} rotation={sticks[1].rotation} scaleX={sticks[1].scaleX} scaleY={sticks[1].scaleY} transform={STICK_MOTIONS[1].transform} translateX={sticks[1].translateX} translateY={sticks[1].translateY}>
286
+ <Path d="M23,15 L35,15 L36,60 A7,7 0 0 1 22,60 Z" fill={`url(#${idPrefix}-yellow)`} />
287
+ <Ellipse cx="29" cy="15" fill="#FEF3D1" rx="6" ry="2.5" />
288
+ </AnimatedG>
289
+
290
+ <AnimatedG originX={STICK_MOTIONS[2].originX} originY={STICK_MOTIONS[2].originY} rotation={sticks[2].rotation} scaleX={sticks[2].scaleX} scaleY={sticks[2].scaleY} transform={STICK_MOTIONS[2].transform} translateX={sticks[2].translateX} translateY={sticks[2].translateY}>
291
+ <Path d="M36,8 L48,8 L49,56 A7,7 0 0 1 35,56 Z" fill={`url(#${idPrefix}-blue)`} />
292
+ <Ellipse cx="42" cy="8" fill="#D0EDF8" rx="6" ry="2.5" />
293
+ </AnimatedG>
294
+
295
+ <AnimatedG originX={STICK_MOTIONS[3].originX} originY={STICK_MOTIONS[3].originY} rotation={sticks[3].rotation} scaleX={sticks[3].scaleX} scaleY={sticks[3].scaleY} transform={STICK_MOTIONS[3].transform} translateX={sticks[3].translateX} translateY={sticks[3].translateY}>
296
+ <Path d="M49,70 L61,70 L62,29 A7,7 0 0 0 48,29 Z" fill={`url(#${idPrefix}-pink)`} />
297
+ <Ellipse cx="55" cy="70" fill="#FBE4E4" rx="6" ry="2.5" />
298
+ </AnimatedG>
299
+ </G>
300
+
301
+ {variant === "wordmark" ? (
302
+ <SvgText fill="currentColor" fontFamily="system-ui, -apple-system, BlinkMacSystemFont, sans-serif" fontSize="38" fontWeight="600" letterSpacing="-0.02em" x="90" y="52">
303
+ chalk
304
+ </SvgText>
305
+ ) : null}
306
+ </Svg>
307
+ </Pressable>
308
+ );
309
+ }