@bigbluebutton/tldraw 2.0.0-alpha.24 → 2.0.0-alpha.26

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 (90) hide show
  1. package/dist-cjs/index.d.ts +9 -1
  2. package/dist-cjs/lib/defaultShapeUtils.js +3 -1
  3. package/dist-cjs/lib/defaultShapeUtils.js.map +2 -2
  4. package/dist-cjs/lib/shapes/arrow/ArrowShapeUtil.js.map +2 -2
  5. package/dist-cjs/lib/shapes/poll/PollShapeTool.js +30 -0
  6. package/dist-cjs/lib/shapes/poll/PollShapeTool.js.map +7 -0
  7. package/dist-cjs/lib/shapes/poll/PollShapeUtil.js +121 -0
  8. package/dist-cjs/lib/shapes/poll/PollShapeUtil.js.map +7 -0
  9. package/dist-cjs/lib/shapes/poll/components/poll-content.js +101 -0
  10. package/dist-cjs/lib/shapes/poll/components/poll-content.js.map +7 -0
  11. package/dist-cjs/lib/shapes/poll/components/styles.js +53 -0
  12. package/dist-cjs/lib/shapes/poll/components/styles.js.map +7 -0
  13. package/dist-cjs/lib/shapes/poll/poll-shape-migrations.js +45 -0
  14. package/dist-cjs/lib/shapes/poll/poll-shape-migrations.js.map +7 -0
  15. package/dist-cjs/lib/shapes/poll/poll-shape-props.js +39 -0
  16. package/dist-cjs/lib/shapes/poll/poll-shape-props.js.map +7 -0
  17. package/dist-cjs/lib/shapes/poll/poll-shape-types.js +17 -0
  18. package/dist-cjs/lib/shapes/poll/poll-shape-types.js.map +7 -0
  19. package/dist-cjs/lib/tools/HandTool/HandTool.js +3 -3
  20. package/dist-cjs/lib/tools/HandTool/HandTool.js.map +2 -2
  21. package/dist-cjs/lib/ui/components/ContextMenu.js +0 -1
  22. package/dist-cjs/lib/ui/components/ContextMenu.js.map +2 -2
  23. package/dist-cjs/lib/ui/components/MenuZone.js +1 -23
  24. package/dist-cjs/lib/ui/components/MenuZone.js.map +2 -2
  25. package/dist-cjs/lib/ui/components/Toolbar/Toolbar.js +3 -15
  26. package/dist-cjs/lib/ui/components/Toolbar/Toolbar.js.map +2 -2
  27. package/dist-cjs/lib/ui/hooks/useTranslation/TLUiTranslationKey.js.map +1 -1
  28. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js +6 -1
  29. package/dist-cjs/lib/ui/hooks/useTranslation/defaultTranslation.js.map +2 -2
  30. package/dist-esm/index.d.mts +9 -1
  31. package/dist-esm/lib/defaultShapeUtils.mjs +3 -1
  32. package/dist-esm/lib/defaultShapeUtils.mjs.map +2 -2
  33. package/dist-esm/lib/shapes/arrow/ArrowShapeUtil.mjs.map +2 -2
  34. package/dist-esm/lib/shapes/poll/PollShapeTool.mjs +10 -0
  35. package/dist-esm/lib/shapes/poll/PollShapeTool.mjs.map +7 -0
  36. package/dist-esm/lib/shapes/poll/PollShapeUtil.mjs +97 -0
  37. package/dist-esm/lib/shapes/poll/PollShapeUtil.mjs.map +7 -0
  38. package/dist-esm/lib/shapes/poll/components/poll-content.mjs +71 -0
  39. package/dist-esm/lib/shapes/poll/components/poll-content.mjs.map +7 -0
  40. package/dist-esm/lib/shapes/poll/components/styles.mjs +23 -0
  41. package/dist-esm/lib/shapes/poll/components/styles.mjs.map +7 -0
  42. package/dist-esm/lib/shapes/poll/poll-shape-migrations.mjs +25 -0
  43. package/dist-esm/lib/shapes/poll/poll-shape-migrations.mjs.map +7 -0
  44. package/dist-esm/lib/shapes/poll/poll-shape-props.mjs +19 -0
  45. package/dist-esm/lib/shapes/poll/poll-shape-props.mjs.map +7 -0
  46. package/dist-esm/lib/shapes/poll/poll-shape-types.mjs +1 -0
  47. package/dist-esm/lib/shapes/poll/poll-shape-types.mjs.map +7 -0
  48. package/dist-esm/lib/tools/HandTool/HandTool.mjs +3 -3
  49. package/dist-esm/lib/tools/HandTool/HandTool.mjs.map +2 -2
  50. package/dist-esm/lib/ui/components/ContextMenu.mjs +0 -1
  51. package/dist-esm/lib/ui/components/ContextMenu.mjs.map +2 -2
  52. package/dist-esm/lib/ui/components/MenuZone.mjs +3 -25
  53. package/dist-esm/lib/ui/components/MenuZone.mjs.map +2 -2
  54. package/dist-esm/lib/ui/components/Toolbar/Toolbar.mjs +3 -15
  55. package/dist-esm/lib/ui/components/Toolbar/Toolbar.mjs.map +2 -2
  56. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs +6 -1
  57. package/dist-esm/lib/ui/hooks/useTranslation/defaultTranslation.mjs.map +2 -2
  58. package/package.json +4 -3
  59. package/src/lib/Tldraw.test.tsx +9 -13
  60. package/src/lib/defaultShapeUtils.ts +2 -0
  61. package/src/lib/shapes/arrow/ArrowShapeUtil.tsx +1 -1
  62. package/src/lib/shapes/line/__snapshots__/LineShapeUtil.test.ts.snap +6 -6
  63. package/src/lib/shapes/poll/PollShapeTool.tsx +7 -0
  64. package/src/lib/shapes/poll/PollShapeUtil.tsx +108 -0
  65. package/src/lib/shapes/poll/components/poll-content.tsx +100 -0
  66. package/src/lib/shapes/poll/components/styles.ts +21 -0
  67. package/src/lib/shapes/poll/poll-shape-migrations.ts +23 -0
  68. package/src/lib/shapes/poll/poll-shape-props.ts +17 -0
  69. package/src/lib/shapes/poll/poll-shape-types.ts +21 -0
  70. package/src/lib/tools/HandTool/HandTool.ts +4 -5
  71. package/src/lib/ui/components/ContextMenu.tsx +1 -1
  72. package/src/lib/ui/components/MenuZone.tsx +8 -15
  73. package/src/lib/ui/components/Toolbar/Toolbar.tsx +3 -6
  74. package/src/lib/ui/hooks/useTranslation/TLUiTranslationKey.ts +5 -0
  75. package/src/lib/ui/hooks/useTranslation/defaultTranslation.ts +5 -0
  76. package/src/test/Editor.test.tsx +2 -2
  77. package/src/test/HandTool.test.ts +55 -56
  78. package/src/test/TLSessionStateSnapshot.test.ts +5 -5
  79. package/src/test/TestEditor.ts +4 -1
  80. package/src/test/TldrawEditor.test.tsx +28 -30
  81. package/src/test/__snapshots__/resizing.test.ts.snap +8 -8
  82. package/src/test/commands/__snapshots__/packShapes.test.ts.snap +20 -20
  83. package/src/test/commands/__snapshots__/zoomToFit.test.ts.snap +2 -2
  84. package/src/test/commands/createShapes.test.ts +1 -1
  85. package/src/test/commands/putContent.test.ts +4 -4
  86. package/src/test/commands/updateShapes.test.ts +1 -1
  87. package/src/test/resizing.test.ts +203 -203
  88. package/src/test/selection-omnibus.test.ts +41 -41
  89. package/src/test/test-jsx.tsx +7 -3
  90. package/src/test/translating.test.ts +42 -42
@@ -0,0 +1,108 @@
1
+ import {
2
+ HTMLContainer,
3
+ Rectangle2d,
4
+ ShapeUtil,
5
+ TLOnResizeHandler,
6
+ getDefaultColorTheme,
7
+ resizeBox,
8
+ } from '@bigbluebutton/editor'
9
+
10
+ import ChatPollContent from './components/poll-content'
11
+ import { pollShapeMigrations } from './poll-shape-migrations'
12
+ import { pollShapeProps } from './poll-shape-props'
13
+ import { IPollShape } from './poll-shape-types'
14
+
15
+ export class PollShapeUtil extends ShapeUtil<IPollShape> {
16
+ static override type = 'poll' as const
17
+
18
+ static override props = pollShapeProps
19
+
20
+ static override migrations = pollShapeMigrations
21
+
22
+ override isAspectRatioLocked = (_shape: IPollShape) => false
23
+
24
+ override canResize = (_shape: IPollShape) => true
25
+
26
+ override canBind = (_shape: IPollShape) => true
27
+
28
+ getDefaultProps(): IPollShape['props'] {
29
+ return {
30
+ w: 300,
31
+ h: 300,
32
+ color: 'black',
33
+ fill: 'white',
34
+ question: '',
35
+ numRespondents: 0,
36
+ numResponders: 0,
37
+ questionText: '',
38
+ questionType: '',
39
+ answers: [],
40
+ }
41
+ }
42
+
43
+ getGeometry(shape: IPollShape) {
44
+ return new Rectangle2d({
45
+ width: shape.props.w,
46
+ height: shape.props.h,
47
+ isFilled: true,
48
+ })
49
+ }
50
+
51
+ component(shape: IPollShape) {
52
+ const { bounds } = this.editor.getShapeGeometry(shape)
53
+ const theme = getDefaultColorTheme({
54
+ isDarkMode: this.editor.user.getIsDarkMode(),
55
+ })
56
+
57
+ // const contentRef = React.useRef<HTMLDivElement>(null)
58
+ const pollMetadata = JSON.stringify({
59
+ id: shape.id,
60
+ question: shape.props.question,
61
+ numRespondents: shape.props.numRespondents,
62
+ numResponders: shape.props.numResponders,
63
+ questionText: shape.props.questionText,
64
+ questionType: shape.props.questionType,
65
+ answers: shape.props.answers,
66
+ })
67
+
68
+ const adjustedHeight = shape.props.questionText.length > 0 ? bounds.height - 75 : bounds.height
69
+
70
+ return (
71
+ <HTMLContainer
72
+ id={shape.id}
73
+ style={{
74
+ border: '1px solid #8B9AA8',
75
+ borderRadius: '4px',
76
+ boxShadow: '0px 0px 4px 0px rgba(0, 0, 0, 0.20)',
77
+ display: 'flex',
78
+ flexDirection: 'column',
79
+ alignItems: 'center',
80
+ justifyContent: 'center',
81
+ pointerEvents: 'all',
82
+ backgroundColor: theme[shape.props.color].semi,
83
+ color: theme[shape.props.color].solid,
84
+ }}
85
+ >
86
+ <div
87
+ style={{
88
+ width: `${bounds.width}px`,
89
+ overflow: 'hidden',
90
+ position: 'relative',
91
+ }}
92
+ >
93
+ <ChatPollContent metadata={pollMetadata} height={adjustedHeight} />
94
+ </div>
95
+ </HTMLContainer>
96
+ )
97
+ }
98
+
99
+ indicator(shape: IPollShape) {
100
+ return <rect width={shape.props.w} height={shape.props.h} />
101
+ }
102
+
103
+ override onResize: TLOnResizeHandler<IPollShape> = (shape, info) => {
104
+ return resizeBox(shape, info)
105
+ }
106
+ }
107
+
108
+ export default PollShapeUtil
@@ -0,0 +1,100 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import React from 'react'
3
+ import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis } from 'recharts'
4
+ import { TLUiTranslationKey } from '../../../ui/hooks/useTranslation/TLUiTranslationKey'
5
+ import Styled from './styles'
6
+
7
+ const caseInsensitiveReducer = (acc: any[], item: { key: string; numVotes: number }) => {
8
+ const index = acc.findIndex((ans) => ans.key.toLowerCase() === item.key.toLowerCase())
9
+ if (index !== -1) {
10
+ if (acc[index].numVotes >= item.numVotes) acc[index].numVotes += item.numVotes
11
+ else {
12
+ const tempVotes = acc[index].numVotes
13
+ acc[index] = item
14
+ acc[index].numVotes += tempVotes
15
+ }
16
+ } else {
17
+ acc.push(item)
18
+ }
19
+ return acc
20
+ }
21
+
22
+ interface ChatPollContentProps {
23
+ metadata: string
24
+ height?: number
25
+ }
26
+
27
+ interface Metadata {
28
+ id: string
29
+ question: string
30
+ numRespondents: number
31
+ numResponders: number
32
+ questionText: string
33
+ questionType: string
34
+ answers: Array<Answers>
35
+ }
36
+
37
+ interface Answers {
38
+ key: string
39
+ numVotes: number
40
+ id: number
41
+ }
42
+
43
+ function assertAsMetadata(metadata: unknown): asserts metadata is Metadata {
44
+ if (typeof metadata !== 'object' || metadata === null) {
45
+ throw new Error('metadata is not an object')
46
+ }
47
+ if (typeof (metadata as Metadata).id !== 'string') {
48
+ throw new Error('metadata.id is not a string')
49
+ }
50
+ if (typeof (metadata as Metadata).numRespondents !== 'number') {
51
+ throw new Error('metadata.numRespondents is not a number')
52
+ }
53
+ if (typeof (metadata as Metadata).numResponders !== 'number') {
54
+ throw new Error('metadata.numResponders is not a number')
55
+ }
56
+ if (typeof (metadata as Metadata).questionText !== 'string') {
57
+ throw new Error('metadata.questionText is not a string')
58
+ }
59
+ if (typeof (metadata as Metadata).questionType !== 'string') {
60
+ throw new Error('metadata.questionType is not a string')
61
+ }
62
+ if (!Array.isArray((metadata as Metadata).answers)) {
63
+ throw new Error('metadata.answers is not an array')
64
+ }
65
+ }
66
+
67
+ const ChatPollContent: React.FC<ChatPollContentProps> = ({
68
+ metadata: string,
69
+ height = undefined,
70
+ }) => {
71
+ const pollData = JSON.parse(string) as unknown
72
+ assertAsMetadata(pollData)
73
+
74
+ const answers = pollData.answers.reduce(caseInsensitiveReducer, [])
75
+
76
+ const translatedAnswers = answers.map((answer: Answers) => {
77
+ const translationKey = answer.key as TLUiTranslationKey
78
+ const pollAnswer = translationKey ? translationKey : answer.key
79
+ return {
80
+ ...answer,
81
+ pollAnswer,
82
+ }
83
+ })
84
+
85
+ const useHeight = height || translatedAnswers.length * 50
86
+ return (
87
+ <Styled.PollWrapper data-test="chatPollMessageText">
88
+ <Styled.PollText>{pollData.questionText}</Styled.PollText>
89
+ <ResponsiveContainer width="90%" height={useHeight}>
90
+ <BarChart data={translatedAnswers} layout="vertical">
91
+ <XAxis type="number" allowDecimals={false} />
92
+ <YAxis width={80} type="category" dataKey="pollAnswer" />
93
+ <Bar dataKey="numVotes" fill="#0C57A7" />
94
+ </BarChart>
95
+ </ResponsiveContainer>
96
+ </Styled.PollWrapper>
97
+ )
98
+ }
99
+
100
+ export default ChatPollContent
@@ -0,0 +1,21 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
2
+ import styled from 'styled-components'
3
+
4
+ export const PollText = styled.div`
5
+ margin-top: 0.5rem;
6
+ margin-bottom: 0.5rem;
7
+ font-size: 1.25rem;
8
+ font-weight: 500;
9
+ margin-left: 2.75rem;
10
+ color: var(--color-text, var(--color-gray, #4e5a66));
11
+ word-break: break-word;
12
+ `
13
+
14
+ export const PollWrapper = styled.div`
15
+ width: 100%;
16
+ `
17
+
18
+ export default {
19
+ PollText,
20
+ PollWrapper,
21
+ }
@@ -0,0 +1,23 @@
1
+ import { defineMigrations } from '@bigbluebutton/editor'
2
+
3
+ // Migrations for the custom poll shape (optional but very helpful)
4
+ export const pollShapeMigrations = defineMigrations({
5
+ currentVersion: 1,
6
+ migrators: {
7
+ 1: {
8
+ // example, removing a property from the shape
9
+ up(shape) {
10
+ const migratedUpShape = { ...shape }
11
+ delete migratedUpShape.somePropertyToRemove
12
+ return migratedUpShape
13
+ },
14
+ down(shape) {
15
+ const migratedDownShape = { ...shape }
16
+ migratedDownShape.somePropertyToRemove = 'some value'
17
+ return migratedDownShape
18
+ },
19
+ },
20
+ },
21
+ })
22
+
23
+ export default pollShapeMigrations
@@ -0,0 +1,17 @@
1
+ import { DefaultColorStyle, ShapeProps, T } from '@bigbluebutton/editor'
2
+ import { IPollShape } from './poll-shape-types'
3
+
4
+ export const pollShapeProps: ShapeProps<IPollShape> = {
5
+ w: T.number,
6
+ h: T.number,
7
+ color: DefaultColorStyle,
8
+ fill: T.string,
9
+ question: T.string,
10
+ numRespondents: T.number,
11
+ numResponders: T.number,
12
+ questionText: T.string,
13
+ questionType: T.string,
14
+ answers: T.any,
15
+ }
16
+
17
+ export default pollShapeProps
@@ -0,0 +1,21 @@
1
+ import { TLBaseShape, TLDefaultColorStyle } from '@bigbluebutton/editor'
2
+
3
+ export type IPollShape = TLBaseShape<
4
+ 'poll',
5
+ {
6
+ w: number
7
+ h: number
8
+ color: TLDefaultColorStyle
9
+ fill: string
10
+ question: string
11
+ numRespondents: number
12
+ numResponders: number
13
+ questionText: string
14
+ questionType: string
15
+ answers: Array<{
16
+ id: number
17
+ key: string
18
+ numVotes: number
19
+ }>
20
+ }
21
+ >
@@ -1,4 +1,4 @@
1
- import { EASINGS, StateNode, TLClickEvent } from '@bigbluebutton/editor'
1
+ import { StateNode, TLClickEvent } from '@bigbluebutton/editor'
2
2
  import { Dragging } from './childStates/Dragging'
3
3
  import { Idle } from './childStates/Idle'
4
4
  import { Pointing } from './childStates/Pointing'
@@ -9,27 +9,26 @@ export class HandTool extends StateNode {
9
9
  static override initial = 'idle'
10
10
  static override children = () => [Idle, Pointing, Dragging]
11
11
 
12
- override onDoubleClick: TLClickEvent = (info) => {
12
+ override onDoubleClick: TLClickEvent = (_info) => {
13
13
  // if (info.phase === 'settle') {
14
14
  // const { currentScreenPoint } = this.editor.inputs
15
15
  // this.editor.zoomIn(currentScreenPoint, { duration: 220, easing: EASINGS.easeOutQuint })
16
16
  // }
17
17
  }
18
18
 
19
- override onTripleClick: TLClickEvent = (info) => {
19
+ override onTripleClick: TLClickEvent = (_info) => {
20
20
  // if (info.phase === 'settle') {
21
21
  // const { currentScreenPoint } = this.editor.inputs
22
22
  // this.editor.zoomOut(currentScreenPoint, { duration: 320, easing: EASINGS.easeOutQuint })
23
23
  // }
24
24
  }
25
25
 
26
- override onQuadrupleClick: TLClickEvent = (info) => {
26
+ override onQuadrupleClick: TLClickEvent = (_info) => {
27
27
  // if (info.phase === 'settle') {
28
28
  // const zoomLevel = this.editor.getZoomLevel()
29
29
  // const {
30
30
  // inputs: { currentScreenPoint },
31
31
  // } = this.editor
32
-
33
32
  // if (zoomLevel === 1) {
34
33
  // this.editor.zoomToFit({ duration: 400, easing: EASINGS.easeOutQuint })
35
34
  // } else {
@@ -65,7 +65,7 @@ export const ContextMenu = function ContextMenu({ children }: { children: any })
65
65
  [editor]
66
66
  )
67
67
 
68
- const container = useContainer()
68
+ // const container = useContainer()
69
69
 
70
70
  const [isOpen, handleOpenChange] = useMenuIsOpen('context menu', cb)
71
71
 
@@ -1,24 +1,17 @@
1
- import { track, useEditor } from '@bigbluebutton/editor'
2
- import { useBreakpoint } from '../hooks/useBreakpoint'
3
- import { useReadonly } from '../hooks/useReadonly'
4
- import { ActionsMenu } from './ActionsMenu'
5
- import { DuplicateButton } from './DuplicateButton'
6
- import { Menu } from './Menu'
7
- import { PageMenu } from './PageMenu/PageMenu'
8
- import { RedoButton } from './RedoButton'
9
- import { TrashButton } from './TrashButton'
10
- import { UndoButton } from './UndoButton'
1
+ import { track } from '@bigbluebutton/editor'
2
+ // import { useBreakpoint } from '../hooks/useBreakpoint'
3
+ // import { useReadonly } from '../hooks/useReadonly'
11
4
 
12
5
  export const MenuZone = track(function MenuZone() {
13
- const editor = useEditor()
6
+ // const editor = useEditor()
14
7
 
15
- const breakpoint = useBreakpoint()
16
- const isReadonly = useReadonly()
8
+ // const breakpoint = useBreakpoint()
9
+ // const isReadonly = useReadonly()
17
10
 
18
11
  return (
19
12
  <div className="tlui-menu-zone">
20
13
  <div className="tlui-buttons__horizontal">
21
- <Menu />
14
+ {/* <Menu />
22
15
  <PageMenu />
23
16
  {breakpoint >= 6 && !isReadonly && !editor.isInAny('hand', 'zoom') && (
24
17
  <>
@@ -28,7 +21,7 @@ export const MenuZone = track(function MenuZone() {
28
21
  <DuplicateButton />
29
22
  <ActionsMenu />
30
23
  </>
31
- )}
24
+ )} */}
32
25
  </div>
33
26
  </div>
34
27
  )
@@ -7,11 +7,7 @@ import { TLUiToolbarItem, useToolbarSchema } from '../../hooks/useToolbarSchema'
7
7
  import { TLUiToolItem } from '../../hooks/useTools'
8
8
  import { useTranslation } from '../../hooks/useTranslation/useTranslation'
9
9
  import { ActionsMenu } from '../ActionsMenu'
10
- import { DuplicateButton } from '../DuplicateButton'
11
10
  import { MobileStylePanel } from '../MobileStylePanel'
12
- import { RedoButton } from '../RedoButton'
13
- import { TrashButton } from '../TrashButton'
14
- import { UndoButton } from '../UndoButton'
15
11
  import { Button } from '../primitives/Button'
16
12
  import * as M from '../primitives/DropdownMenu'
17
13
  import { kbdStr } from '../primitives/shared'
@@ -112,7 +108,7 @@ export const Toolbar = memo(function Toolbar() {
112
108
  <div className="tlui-toolbar__left">
113
109
  {!isReadonly && (
114
110
  <div className="tlui-toolbar__extras">
115
- {breakpoint < 6 && !(activeToolId === 'hand' || activeToolId === 'zoom') && (
111
+ {/* {breakpoint < 6 && !(activeToolId === 'hand' || activeToolId === 'zoom') && (
116
112
  <div className="tlui-toolbar__extras__controls tlui-buttons__horizontal">
117
113
  <UndoButton />
118
114
  <RedoButton />
@@ -120,7 +116,7 @@ export const Toolbar = memo(function Toolbar() {
120
116
  <DuplicateButton />
121
117
  <ActionsMenu />
122
118
  </div>
123
- )}
119
+ )} */}
124
120
  <ToggleToolLockedButton activeToolId={activeToolId} />
125
121
  </div>
126
122
  )}
@@ -197,6 +193,7 @@ export const Toolbar = memo(function Toolbar() {
197
193
  <OverflowToolsContent toolbarItems={itemsInDropdown} />
198
194
  </M.Content>
199
195
  </M.Root>
196
+ <ActionsMenu />
200
197
  </>
201
198
  ) : null}
202
199
  </>
@@ -356,3 +356,8 @@ export type TLUiTranslationKey =
356
356
  | 'vscode.file-open.backup-failed'
357
357
  | 'vscode.file-open.dont-show-again'
358
358
  | 'cursor-chat.type-to-chat'
359
+ | 'app.poll.t'
360
+ | 'app.poll.f'
361
+ | 'app.poll.y'
362
+ | 'app.poll.n'
363
+ | 'app.poll.abstention'
@@ -366,4 +366,9 @@ export const DEFAULT_TRANSLATION = {
366
366
  'vscode.file-open.backup-failed': 'Backup failed: this is not a .tldr file.',
367
367
  'vscode.file-open.dont-show-again': "Don't ask again",
368
368
  'cursor-chat.type-to-chat': 'Type to chat...',
369
+ 'app.poll.t': 'True',
370
+ 'app.poll.f': 'False',
371
+ 'app.poll.y': 'Yes',
372
+ 'app.poll.n': 'No',
373
+ 'app.poll.abstention': 'Abstention',
369
374
  }
@@ -511,13 +511,13 @@ describe('getShapeUtil', () => {
511
511
  it('throws if that shape type isnt registered', () => {
512
512
  const myMissingShape = { type: 'missing' } as TLShape
513
513
  expect(() => editor.getShapeUtil(myMissingShape)).toThrowErrorMatchingInlineSnapshot(
514
- `"No shape util found for type \\"missing\\""`
514
+ `"No shape util found for type "missing""`
515
515
  )
516
516
  })
517
517
 
518
518
  it('throws if that type isnt registered', () => {
519
519
  expect(() => editor.getShapeUtil('missing')).toThrowErrorMatchingInlineSnapshot(
520
- `"No shape util found for type \\"missing\\""`
520
+ `"No shape util found for type "missing""`
521
521
  )
522
522
  })
523
523
  })
@@ -1,5 +1,4 @@
1
- import { HandTool } from '../lib/tools/HandTool/HandTool'
2
- import { TestEditor, createDefaultShapes } from './TestEditor'
1
+ import { TestEditor } from './TestEditor'
3
2
 
4
3
  let editor: TestEditor
5
4
 
@@ -16,60 +15,60 @@ afterEach(() => {
16
15
 
17
16
  jest.useFakeTimers()
18
17
 
19
- describe(HandTool, () => {
20
- it('Double taps to zoom in', () => {
21
- editor.setCurrentTool('hand')
22
- expect(editor.getZoomLevel()).toBe(1)
23
- editor.click()
24
- editor.click() // double click!
25
- jest.advanceTimersByTime(300)
26
- expect(editor.getZoomLevel()).not.toBe(1) // animating
27
- jest.advanceTimersByTime(300)
28
- expect(editor.getZoomLevel()).toBe(2) // all done
29
- })
30
-
31
- it('Triple taps to zoom out', () => {
32
- editor.setCurrentTool('hand')
33
- expect(editor.getZoomLevel()).toBe(1)
34
- editor.click()
35
- editor.click()
36
- editor.click() // triple click!
37
- jest.advanceTimersByTime(300)
38
- expect(editor.getZoomLevel()).not.toBe(1) // animating
39
- jest.advanceTimersByTime(300)
40
- expect(editor.getZoomLevel()).toBe(0.5) // all done
41
- })
42
-
43
- it('Quadruple taps to reset zoom', () => {
44
- editor.setCurrentTool('hand')
45
- editor.zoomIn() // zoom to 2
46
- expect(editor.getZoomLevel()).toBe(2)
47
- editor.click()
48
- editor.click()
49
- editor.click()
50
- editor.click() // quad click!
51
- jest.advanceTimersByTime(300)
52
- expect(editor.getZoomLevel()).not.toBe(2) // animating
53
- jest.advanceTimersByTime(300)
54
- expect(editor.getZoomLevel()).toBe(1) // all done
55
- })
56
-
57
- it('Quadruple taps from zoom=1 to zoom to fit', () => {
58
- editor.setCurrentTool('hand')
59
- expect(editor.getZoomLevel()).toBe(1)
60
- editor.createShapes(createDefaultShapes()) // makes some shapes
61
- editor.click()
62
- editor.click()
63
- editor.click()
64
- editor.click() // quad click!
65
- jest.advanceTimersByTime(300)
66
- expect(editor.getZoomLevel()).not.toBe(1) // animating
67
- jest.advanceTimersByTime(300)
68
- const z = editor.getZoomLevel()
69
- editor.zoomToFit() // call zoom to fit manually to compare
70
- expect(editor.getZoomLevel()).toBe(z) // zoom should not have changed
71
- })
72
- })
18
+ // describe(HandTool, () => {
19
+ // it('Double taps to zoom in', () => {
20
+ // editor.setCurrentTool('hand')
21
+ // expect(editor.getZoomLevel()).toBe(1)
22
+ // editor.click()
23
+ // editor.click() // double click!
24
+ // jest.advanceTimersByTime(300)
25
+ // expect(editor.getZoomLevel()).not.toBe(1) // animating
26
+ // jest.advanceTimersByTime(300)
27
+ // expect(editor.getZoomLevel()).toBe(2) // all done
28
+ // })
29
+
30
+ // it('Triple taps to zoom out', () => {
31
+ // editor.setCurrentTool('hand')
32
+ // expect(editor.getZoomLevel()).toBe(1)
33
+ // editor.click()
34
+ // editor.click()
35
+ // editor.click() // triple click!
36
+ // jest.advanceTimersByTime(300)
37
+ // expect(editor.getZoomLevel()).not.toBe(1) // animating
38
+ // jest.advanceTimersByTime(300)
39
+ // expect(editor.getZoomLevel()).toBe(0.5) // all done
40
+ // })
41
+
42
+ // it('Quadruple taps to reset zoom', () => {
43
+ // editor.setCurrentTool('hand')
44
+ // editor.zoomIn() // zoom to 2
45
+ // expect(editor.getZoomLevel()).toBe(2)
46
+ // editor.click()
47
+ // editor.click()
48
+ // editor.click()
49
+ // editor.click() // quad click!
50
+ // jest.advanceTimersByTime(300)
51
+ // expect(editor.getZoomLevel()).not.toBe(2) // animating
52
+ // jest.advanceTimersByTime(300)
53
+ // expect(editor.getZoomLevel()).toBe(1) // all done
54
+ // })
55
+
56
+ // it('Quadruple taps from zoom=1 to zoom to fit', () => {
57
+ // editor.setCurrentTool('hand')
58
+ // expect(editor.getZoomLevel()).toBe(1)
59
+ // editor.createShapes(createDefaultShapes()) // makes some shapes
60
+ // editor.click()
61
+ // editor.click()
62
+ // editor.click()
63
+ // editor.click() // quad click!
64
+ // jest.advanceTimersByTime(300)
65
+ // expect(editor.getZoomLevel()).not.toBe(1) // animating
66
+ // jest.advanceTimersByTime(300)
67
+ // const z = editor.getZoomLevel()
68
+ // editor.zoomToFit() // call zoom to fit manually to compare
69
+ // expect(editor.getZoomLevel()).toBe(z) // zoom should not have changed
70
+ // })
71
+ // })
73
72
 
74
73
  describe('When in the idle state', () => {
75
74
  it('Returns to select on cancel', () => {
@@ -124,23 +124,23 @@ describe(extractSessionStateFromLegacySnapshot, () => {
124
124
  }
125
125
 
126
126
  expect(extractSessionStateFromLegacySnapshot(oldSnapshot as any)).toMatchInlineSnapshot(`
127
- Object {
127
+ {
128
128
  "currentPageId": "page:whatever",
129
129
  "exportBackground": false,
130
130
  "isDebugMode": false,
131
131
  "isFocusMode": false,
132
132
  "isGridMode": false,
133
133
  "isToolLocked": false,
134
- "pageStates": Array [
135
- Object {
136
- "camera": Object {
134
+ "pageStates": [
135
+ {
136
+ "camera": {
137
137
  "x": 0,
138
138
  "y": 0,
139
139
  "z": 1,
140
140
  },
141
141
  "focusedGroupId": null,
142
142
  "pageId": "page:whatever",
143
- "selectedShapeIds": Array [
143
+ "selectedShapeIds": [
144
144
  "shape:whatever",
145
145
  ],
146
146
  },
@@ -24,6 +24,7 @@ import {
24
24
  createTLStore,
25
25
  rotateSelectionHandle,
26
26
  } from '@bigbluebutton/editor'
27
+ import React from 'react'
27
28
  import { defaultShapeTools } from '../lib/defaultShapeTools'
28
29
  import { defaultShapeUtils } from '../lib/defaultShapeUtils'
29
30
  import { defaultTools } from '../lib/defaultTools'
@@ -560,7 +561,9 @@ export class TestEditor extends Editor {
560
561
  return this
561
562
  }
562
563
 
563
- createShapesFromJsx(shapesJsx: JSX.Element | JSX.Element[]): Record<string, TLShapeId> {
564
+ createShapesFromJsx(
565
+ shapesJsx: React.JSX.Element | React.JSX.Element[]
566
+ ): Record<string, TLShapeId> {
564
567
  const { shapes, ids } = shapesFromJsx(shapesJsx)
565
568
  this.createShapes(shapes)
566
569
  return ids