@dxos/plugin-sheet 0.7.5-main.9d26e3a → 0.7.5-main.b19bfc8

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 (210) hide show
  1. package/dist/lib/browser/SheetContainer-IMHGS7Z4.mjs +370 -0
  2. package/dist/lib/browser/SheetContainer-IMHGS7Z4.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-A374JPWV.mjs → chunk-AT7F2WDW.mjs} +157 -391
  4. package/dist/lib/browser/chunk-AT7F2WDW.mjs.map +7 -0
  5. package/dist/lib/browser/chunk-FOO6NGBM.mjs +229 -0
  6. package/dist/lib/browser/chunk-FOO6NGBM.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-GAFHJBCU.mjs +18 -0
  8. package/dist/lib/browser/chunk-GAFHJBCU.mjs.map +7 -0
  9. package/dist/lib/browser/chunk-LXHRT3CC.mjs +15 -0
  10. package/dist/lib/browser/chunk-LXHRT3CC.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-Q4XS4YWF.mjs → chunk-OOSRC36N.mjs} +2 -2
  12. package/dist/lib/browser/chunk-OOSRC36N.mjs.map +7 -0
  13. package/dist/lib/browser/compute-graph-registry-EGPD4HEX.mjs +27 -0
  14. package/dist/lib/browser/compute-graph-registry-EGPD4HEX.mjs.map +7 -0
  15. package/dist/lib/browser/index.mjs +88 -218
  16. package/dist/lib/browser/index.mjs.map +4 -4
  17. package/dist/lib/browser/intent-resolver-6S2RMLQF.mjs +56 -0
  18. package/dist/lib/browser/intent-resolver-6S2RMLQF.mjs.map +7 -0
  19. package/dist/lib/browser/markdown-CFJIWHZX.mjs +26 -0
  20. package/dist/lib/browser/markdown-CFJIWHZX.mjs.map +7 -0
  21. package/dist/lib/browser/meta.json +1 -1
  22. package/dist/lib/browser/react-surface-PHKJZYFB.mjs +52 -0
  23. package/dist/lib/browser/react-surface-PHKJZYFB.mjs.map +7 -0
  24. package/dist/lib/browser/thread-7ZWW5EA7.mjs +17 -0
  25. package/dist/lib/browser/thread-7ZWW5EA7.mjs.map +7 -0
  26. package/dist/lib/browser/types/index.mjs +2 -2
  27. package/dist/lib/node/SheetContainer-NNIZN4AK.cjs +364 -0
  28. package/dist/lib/node/SheetContainer-NNIZN4AK.cjs.map +7 -0
  29. package/dist/lib/node/{chunk-FDEQ2PGJ.cjs → chunk-2KCZUH72.cjs} +198 -428
  30. package/dist/lib/node/chunk-2KCZUH72.cjs.map +7 -0
  31. package/dist/lib/node/{chunk-TQOJ7DG2.cjs → chunk-4LSYTNS4.cjs} +6 -6
  32. package/dist/lib/node/chunk-4LSYTNS4.cjs.map +7 -0
  33. package/dist/lib/node/{chunk-2ZVZI2KJ.cjs → chunk-MLU6KRQN.cjs} +12 -9
  34. package/dist/lib/node/chunk-MLU6KRQN.cjs.map +7 -0
  35. package/dist/lib/node/chunk-P4KSGZSS.cjs +251 -0
  36. package/dist/lib/node/chunk-P4KSGZSS.cjs.map +7 -0
  37. package/dist/lib/node/{meta.cjs → chunk-ZV2RS3QH.cjs} +12 -8
  38. package/dist/lib/node/chunk-ZV2RS3QH.cjs.map +7 -0
  39. package/dist/lib/node/compute-graph-registry-GJK5H264.cjs +53 -0
  40. package/dist/lib/node/compute-graph-registry-GJK5H264.cjs.map +7 -0
  41. package/dist/lib/node/index.cjs +89 -215
  42. package/dist/lib/node/index.cjs.map +4 -4
  43. package/dist/lib/node/intent-resolver-I25V7SBT.cjs +69 -0
  44. package/dist/lib/node/intent-resolver-I25V7SBT.cjs.map +7 -0
  45. package/dist/lib/node/markdown-YTCSW66K.cjs +40 -0
  46. package/dist/lib/node/markdown-YTCSW66K.cjs.map +7 -0
  47. package/dist/lib/node/meta.json +1 -1
  48. package/dist/lib/node/react-surface-HLE6CRA6.cjs +70 -0
  49. package/dist/lib/node/react-surface-HLE6CRA6.cjs.map +7 -0
  50. package/dist/lib/node/thread-DRNYTR6M.cjs +32 -0
  51. package/dist/lib/node/thread-DRNYTR6M.cjs.map +7 -0
  52. package/dist/lib/node/types/index.cjs +30 -30
  53. package/dist/lib/node/types/index.cjs.map +1 -1
  54. package/dist/lib/node-esm/SheetContainer-PGDJKGTZ.mjs +371 -0
  55. package/dist/lib/node-esm/SheetContainer-PGDJKGTZ.mjs.map +7 -0
  56. package/dist/lib/node-esm/{chunk-NYYIDVR7.mjs → chunk-HPAMZ6SP.mjs} +2 -2
  57. package/dist/lib/node-esm/chunk-HPAMZ6SP.mjs.map +7 -0
  58. package/dist/lib/node-esm/chunk-PTOI45NK.mjs +231 -0
  59. package/dist/lib/node-esm/chunk-PTOI45NK.mjs.map +7 -0
  60. package/dist/lib/node-esm/chunk-RTZXXOS2.mjs +20 -0
  61. package/dist/lib/node-esm/chunk-RTZXXOS2.mjs.map +7 -0
  62. package/dist/lib/node-esm/chunk-SX3S7UKU.mjs +16 -0
  63. package/dist/lib/node-esm/chunk-SX3S7UKU.mjs.map +7 -0
  64. package/dist/lib/node-esm/{chunk-L5PQHVTX.mjs → chunk-ZM7XLUGL.mjs} +157 -391
  65. package/dist/lib/node-esm/chunk-ZM7XLUGL.mjs.map +7 -0
  66. package/dist/lib/node-esm/compute-graph-registry-3F5JCYEN.mjs +28 -0
  67. package/dist/lib/node-esm/compute-graph-registry-3F5JCYEN.mjs.map +7 -0
  68. package/dist/lib/node-esm/index.mjs +88 -218
  69. package/dist/lib/node-esm/index.mjs.map +4 -4
  70. package/dist/lib/node-esm/intent-resolver-IPRSINII.mjs +57 -0
  71. package/dist/lib/node-esm/intent-resolver-IPRSINII.mjs.map +7 -0
  72. package/dist/lib/node-esm/markdown-CGSK44XJ.mjs +27 -0
  73. package/dist/lib/node-esm/markdown-CGSK44XJ.mjs.map +7 -0
  74. package/dist/lib/node-esm/meta.json +1 -1
  75. package/dist/lib/node-esm/react-surface-PFRJ7V5N.mjs +53 -0
  76. package/dist/lib/node-esm/react-surface-PFRJ7V5N.mjs.map +7 -0
  77. package/dist/lib/node-esm/thread-6T5VXPAF.mjs +18 -0
  78. package/dist/lib/node-esm/thread-6T5VXPAF.mjs.map +7 -0
  79. package/dist/lib/node-esm/types/index.mjs +2 -2
  80. package/dist/types/src/SheetPlugin.d.ts +1 -3
  81. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  82. package/dist/types/src/capabilities/capabilities.d.ts +5 -0
  83. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -0
  84. package/dist/types/src/capabilities/compute-graph-registry.d.ts +4 -0
  85. package/dist/types/src/capabilities/compute-graph-registry.d.ts.map +1 -0
  86. package/dist/types/src/capabilities/index.d.ts +12 -0
  87. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  88. package/dist/types/src/capabilities/intent-resolver.d.ts +4 -0
  89. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -0
  90. package/dist/types/src/capabilities/markdown.d.ts +6 -0
  91. package/dist/types/src/capabilities/markdown.d.ts.map +1 -0
  92. package/dist/types/src/capabilities/react-surface.d.ts +4 -0
  93. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  94. package/dist/types/src/capabilities/thread.d.ts +6 -0
  95. package/dist/types/src/capabilities/thread.d.ts.map +1 -0
  96. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +1 -1
  97. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -1
  98. package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts +1 -2
  99. package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts.map +1 -1
  100. package/dist/types/src/components/GridSheet/GridSheet.d.ts +1 -2
  101. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
  102. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +1 -2
  103. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -1
  104. package/dist/types/src/components/GridSheet/SheetCellEditor.stories.d.ts +1 -2
  105. package/dist/types/src/components/GridSheet/SheetCellEditor.stories.d.ts.map +1 -1
  106. package/dist/types/src/components/RangeList/RangeList.d.ts +1 -2
  107. package/dist/types/src/components/RangeList/RangeList.d.ts.map +1 -1
  108. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +1 -2
  109. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -1
  110. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts +2 -3
  111. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +1 -1
  112. package/dist/types/src/components/SheetContext/SheetContext.d.ts +2 -2
  113. package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -1
  114. package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts +7 -0
  115. package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts.map +1 -0
  116. package/dist/types/src/components/SheetToolbar/SheetToolbar.stories.d.ts +6 -0
  117. package/dist/types/src/components/SheetToolbar/SheetToolbar.stories.d.ts.map +1 -0
  118. package/dist/types/src/components/SheetToolbar/align.d.ts +28 -0
  119. package/dist/types/src/components/SheetToolbar/align.d.ts.map +1 -0
  120. package/dist/types/src/components/SheetToolbar/comment.d.ts +23 -0
  121. package/dist/types/src/components/SheetToolbar/comment.d.ts.map +1 -0
  122. package/dist/types/src/components/SheetToolbar/index.d.ts +2 -0
  123. package/dist/types/src/components/SheetToolbar/index.d.ts.map +1 -0
  124. package/dist/types/src/components/SheetToolbar/style.d.ts +26 -0
  125. package/dist/types/src/components/SheetToolbar/style.d.ts.map +1 -0
  126. package/dist/types/src/components/SheetToolbar/useToolbarAction.d.ts +8 -0
  127. package/dist/types/src/components/SheetToolbar/useToolbarAction.d.ts.map +1 -0
  128. package/dist/types/src/components/SheetToolbar/useToolbarState.d.ts +6 -0
  129. package/dist/types/src/components/SheetToolbar/useToolbarState.d.ts.map +1 -0
  130. package/dist/types/src/components/index.d.ts +3 -4
  131. package/dist/types/src/components/index.d.ts.map +1 -1
  132. package/dist/types/src/extensions/compute.stories.d.ts +2 -3
  133. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -1
  134. package/dist/types/src/index.d.ts +2 -3
  135. package/dist/types/src/index.d.ts.map +1 -1
  136. package/dist/types/src/integrations/thread-ranges.d.ts.map +1 -1
  137. package/dist/types/src/meta.d.ts +2 -2
  138. package/dist/types/src/meta.d.ts.map +1 -1
  139. package/dist/types/src/testing/testing.d.ts +1 -1
  140. package/dist/types/src/testing/testing.d.ts.map +1 -1
  141. package/dist/types/src/types/schema.d.ts +14 -14
  142. package/dist/types/src/types/schema.d.ts.map +1 -1
  143. package/dist/types/src/types/sheet-range-types.d.ts +1 -1
  144. package/dist/types/src/types/sheet-range-types.d.ts.map +1 -1
  145. package/dist/types/src/types/types.d.ts +0 -11
  146. package/dist/types/src/types/types.d.ts.map +1 -1
  147. package/dist/types/tsconfig.tsbuildinfo +1 -1
  148. package/package.json +46 -52
  149. package/src/SheetPlugin.tsx +68 -105
  150. package/src/capabilities/capabilities.ts +14 -0
  151. package/src/capabilities/compute-graph-registry.ts +25 -0
  152. package/src/capabilities/index.ts +13 -0
  153. package/src/capabilities/intent-resolver.ts +38 -0
  154. package/src/capabilities/markdown.ts +22 -0
  155. package/src/capabilities/react-surface.tsx +37 -0
  156. package/src/capabilities/thread.ts +14 -0
  157. package/src/components/GridSheet/GridSheet.stories.tsx +2 -0
  158. package/src/components/GridSheet/util.ts +1 -1
  159. package/src/components/SheetContainer/SheetContainer.stories.tsx +28 -22
  160. package/src/components/SheetContainer/SheetContainer.tsx +3 -8
  161. package/src/components/{Toolbar/Toolbar.stories.tsx → SheetToolbar/SheetToolbar.stories.tsx} +4 -8
  162. package/src/components/SheetToolbar/SheetToolbar.tsx +48 -0
  163. package/src/components/SheetToolbar/align.ts +68 -0
  164. package/src/components/SheetToolbar/comment.ts +56 -0
  165. package/src/components/{Toolbar → SheetToolbar}/index.ts +1 -1
  166. package/src/components/SheetToolbar/style.ts +72 -0
  167. package/src/components/SheetToolbar/useToolbarAction.ts +87 -0
  168. package/src/components/SheetToolbar/useToolbarState.ts +17 -0
  169. package/src/components/index.ts +0 -1
  170. package/src/extensions/compute.stories.tsx +2 -2
  171. package/src/index.ts +2 -5
  172. package/src/integrations/thread-ranges.ts +21 -10
  173. package/src/meta.ts +4 -2
  174. package/src/types/sheet-range-types.ts +1 -1
  175. package/src/types/types.ts +0 -26
  176. package/dist/lib/browser/SheetContainer-S4NCLUYL.mjs +0 -290
  177. package/dist/lib/browser/SheetContainer-S4NCLUYL.mjs.map +0 -7
  178. package/dist/lib/browser/chunk-A374JPWV.mjs.map +0 -7
  179. package/dist/lib/browser/chunk-Q4XS4YWF.mjs.map +0 -7
  180. package/dist/lib/browser/chunk-RABELMEQ.mjs +0 -15
  181. package/dist/lib/browser/chunk-RABELMEQ.mjs.map +0 -7
  182. package/dist/lib/browser/meta.mjs +0 -9
  183. package/dist/lib/browser/meta.mjs.map +0 -7
  184. package/dist/lib/node/SheetContainer-TP4GYXZB.cjs +0 -296
  185. package/dist/lib/node/SheetContainer-TP4GYXZB.cjs.map +0 -7
  186. package/dist/lib/node/chunk-2ZVZI2KJ.cjs.map +0 -7
  187. package/dist/lib/node/chunk-FDEQ2PGJ.cjs.map +0 -7
  188. package/dist/lib/node/chunk-TQOJ7DG2.cjs.map +0 -7
  189. package/dist/lib/node/meta.cjs.map +0 -7
  190. package/dist/lib/node-esm/SheetContainer-YB3JBVPZ.mjs +0 -291
  191. package/dist/lib/node-esm/SheetContainer-YB3JBVPZ.mjs.map +0 -7
  192. package/dist/lib/node-esm/chunk-BM2Q3FFC.mjs +0 -17
  193. package/dist/lib/node-esm/chunk-BM2Q3FFC.mjs.map +0 -7
  194. package/dist/lib/node-esm/chunk-L5PQHVTX.mjs.map +0 -7
  195. package/dist/lib/node-esm/chunk-NYYIDVR7.mjs.map +0 -7
  196. package/dist/lib/node-esm/meta.mjs +0 -10
  197. package/dist/lib/node-esm/meta.mjs.map +0 -7
  198. package/dist/types/src/components/SheetObjectSettings.d.ts +0 -7
  199. package/dist/types/src/components/SheetObjectSettings.d.ts.map +0 -1
  200. package/dist/types/src/components/Toolbar/Toolbar.d.ts +0 -48
  201. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +0 -1
  202. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +0 -7
  203. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +0 -1
  204. package/dist/types/src/components/Toolbar/index.d.ts +0 -2
  205. package/dist/types/src/components/Toolbar/index.d.ts.map +0 -1
  206. package/dist/types/src/testing/playwright/playwright.config.d.ts +0 -3
  207. package/dist/types/src/testing/playwright/playwright.config.d.ts.map +0 -1
  208. package/src/components/SheetObjectSettings.tsx +0 -38
  209. package/src/components/Toolbar/Toolbar.tsx +0 -344
  210. /package/src/testing/playwright/{playwright.config.ts → playwright.config.cts} +0 -0
@@ -1,344 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { createContext } from '@radix-ui/react-context';
6
- import React, { type PropsWithChildren, useCallback } from 'react';
7
-
8
- import { createIntent, useIntentDispatcher } from '@dxos/app-framework';
9
- import { inRange } from '@dxos/compute';
10
- import { RefArray } from '@dxos/live-object';
11
- import { ThreadAction } from '@dxos/plugin-thread/types';
12
- import {
13
- Icon,
14
- type ThemedClassName,
15
- Toolbar as NaturalToolbar,
16
- type ToolbarButtonProps as NaturalToolbarButtonProps,
17
- type ToolbarToggleGroupItemProps as NaturalToolbarToggleGroupItemProps,
18
- type ToolbarToggleProps as NaturalToolbarToggleProps,
19
- Tooltip,
20
- useTranslation,
21
- } from '@dxos/react-ui';
22
- import { useAttention } from '@dxos/react-ui-attention';
23
-
24
- import { completeCellRangeToThreadCursor } from '../../integrations';
25
- import { SHEET_PLUGIN } from '../../meta';
26
- import {
27
- alignKey,
28
- rangeFromIndex,
29
- rangeToIndex,
30
- styleKey,
31
- type AlignKey,
32
- type AlignValue,
33
- type CommentKey,
34
- type CommentValue,
35
- type StyleKey,
36
- type StyleValue,
37
- type SheetType,
38
- } from '../../types';
39
- import { useSheetContext } from '../SheetContext';
40
-
41
- //
42
- // Buttons
43
- //
44
-
45
- const buttonStyles = 'min-bs-0 p-2';
46
- const tooltipProps = { side: 'bottom' as const };
47
-
48
- const ToolbarSeparator = () => <div role='separator' className='grow' />;
49
-
50
- //
51
- // ToolbarItem
52
- //
53
-
54
- type ToolbarItemProps =
55
- | (NaturalToolbarButtonProps & { itemType: 'button'; icon: string })
56
- | (NaturalToolbarToggleGroupItemProps & { itemType: 'toggleGroupItem'; icon: string })
57
- | (NaturalToolbarToggleProps & { itemType: 'toggle'; icon: string });
58
-
59
- export const ToolbarItem = ({ itemType, icon, children, ...props }: ToolbarItemProps) => {
60
- const Invoker =
61
- itemType === 'toggleGroupItem'
62
- ? NaturalToolbar.ToggleGroupItem
63
- : itemType === 'toggle'
64
- ? NaturalToolbar.Toggle
65
- : NaturalToolbar.Button;
66
- return (
67
- <Tooltip.Root>
68
- <Tooltip.Trigger asChild>
69
- {/* TODO(thure): type the props spread better. */}
70
- <Invoker variant='ghost' {...(props as any)} classNames={buttonStyles}>
71
- <Icon icon={icon} size={5} />
72
- <span className='sr-only'>{children}</span>
73
- </Invoker>
74
- </Tooltip.Trigger>
75
- <Tooltip.Portal>
76
- <Tooltip.Content {...tooltipProps}>
77
- {children}
78
- <Tooltip.Arrow />
79
- </Tooltip.Content>
80
- </Tooltip.Portal>
81
- </Tooltip.Root>
82
- );
83
- };
84
-
85
- //
86
- // Root
87
- //
88
-
89
- type AlignAction = { key: AlignKey; value: AlignValue };
90
- type CommentAction = { key: CommentKey; value: CommentValue; cellContent?: string };
91
- type StyleAction = { key: StyleKey; value: StyleValue };
92
-
93
- export type ToolbarAction = StyleAction | AlignAction | CommentAction;
94
- export type ToolbarActionAnnotated = ToolbarAction & { unset?: boolean };
95
-
96
- export type ToolbarActionType = ToolbarAction['key'];
97
-
98
- export type ToolbarActionHandler = (action: ToolbarActionAnnotated) => void;
99
-
100
- export type ToolbarProps = ThemedClassName<
101
- PropsWithChildren<{
102
- role?: string;
103
- }>
104
- >;
105
-
106
- const [ToolbarContextProvider, useToolbarContext] = createContext<{
107
- onAction: (action: ToolbarActionAnnotated) => void;
108
- }>('Toolbar');
109
-
110
- type Range = SheetType['ranges'][number];
111
-
112
- const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
113
- const { id, model, cursorFallbackRange, cursor } = useSheetContext();
114
- const { hasAttention } = useAttention(id);
115
- const { dispatchPromise: dispatch } = useIntentDispatcher();
116
-
117
- // TODO(Zan): Externalize the toolbar action handler. E.g., Toolbar/keys should both fire events.
118
- const handleAction = useCallback(
119
- (action: ToolbarActionAnnotated) => {
120
- switch (action.key) {
121
- case 'alignment':
122
- if (cursorFallbackRange) {
123
- const index =
124
- model.sheet.ranges?.findIndex(
125
- (range) =>
126
- range.key === action.key &&
127
- inRange(rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),
128
- ) ?? -1;
129
- const nextRangeEntity = {
130
- range: rangeToIndex(model.sheet, cursorFallbackRange),
131
- key: action.key,
132
- value: action.value,
133
- };
134
- if (index < 0) {
135
- model.sheet.ranges?.push(nextRangeEntity);
136
- } else if (model.sheet.ranges![index].value === action.value) {
137
- model.sheet.ranges?.splice(index, 1);
138
- } else {
139
- model.sheet.ranges?.splice(index, 1, nextRangeEntity);
140
- }
141
- }
142
- break;
143
- case 'style':
144
- if (action.unset) {
145
- const index = model.sheet.ranges?.findIndex(
146
- (range) =>
147
- range.key === action.key &&
148
- cursorFallbackRange &&
149
- inRange(rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),
150
- );
151
- if (index >= 0) {
152
- model.sheet.ranges?.splice(index, 1);
153
- }
154
- } else if (cursorFallbackRange) {
155
- model.sheet.ranges?.push({
156
- range: rangeToIndex(model.sheet, cursorFallbackRange),
157
- key: action.key,
158
- value: action.value,
159
- });
160
- }
161
- break;
162
- case 'comment': {
163
- if (cursorFallbackRange) {
164
- void dispatch(
165
- createIntent(ThreadAction.Create, {
166
- cursor: completeCellRangeToThreadCursor(cursorFallbackRange),
167
- name: action.cellContent,
168
- subject: model.sheet,
169
- }),
170
- );
171
- }
172
- }
173
- }
174
- },
175
- [model.sheet, cursorFallbackRange, cursor, dispatch],
176
- );
177
-
178
- return (
179
- <ToolbarContextProvider onAction={handleAction}>
180
- <NaturalToolbar.Root classNames={['pli-0.5 attention-surface', !hasAttention && 'opacity-20', classNames]}>
181
- {children}
182
- </NaturalToolbar.Root>
183
- </ToolbarContextProvider>
184
- );
185
- };
186
-
187
- // TODO(burdon): Generalize.
188
- // TODO(burdon): Detect and display current state.
189
- type ButtonProps<T> = {
190
- value: T;
191
- icon: string;
192
- disabled?: (state: Range) => boolean;
193
- };
194
-
195
- //
196
- // Alignment
197
- //
198
-
199
- const alignmentOptions: ButtonProps<AlignValue>[] = [
200
- { value: 'start', icon: 'ph--text-align-left--regular' },
201
- { value: 'center', icon: 'ph--text-align-center--regular' },
202
- { value: 'end', icon: 'ph--text-align-right--regular' },
203
- ];
204
-
205
- const Alignment = () => {
206
- const { cursor, model } = useSheetContext();
207
- const { onAction } = useToolbarContext('Alignment');
208
- const { t } = useTranslation(SHEET_PLUGIN);
209
-
210
- // TODO(thure): Can this O(n) call be memoized?
211
- const value = cursor
212
- ? model.sheet.ranges?.findLast(
213
- ({ range, key }) => key === alignKey && inRange(rangeFromIndex(model.sheet, range), cursor),
214
- )?.value
215
- : undefined;
216
-
217
- return (
218
- <NaturalToolbar.ToggleGroup
219
- type='single'
220
- value={
221
- // TODO(thure): providing `undefined` leaves the last item active which was active rather than showing none.
222
- value ?? 'never'
223
- }
224
- onValueChange={(value: AlignValue) => onAction?.({ key: alignKey, value })}
225
- >
226
- {alignmentOptions.map(({ value, icon }) => (
227
- <ToolbarItem
228
- itemType='toggleGroupItem'
229
- key={value}
230
- value={value}
231
- icon={icon}
232
- data-testid={`grid.toolbar.${alignKey}.${value}`}
233
- >
234
- {t('toolbar action label', {
235
- key: t(`range key ${alignKey} label`),
236
- value: t(`range value ${value} label`),
237
- })}
238
- </ToolbarItem>
239
- ))}
240
- </NaturalToolbar.ToggleGroup>
241
- );
242
- };
243
-
244
- const styleOptions: ButtonProps<StyleValue>[] = [
245
- { value: 'highlight', icon: 'ph--highlighter--regular' },
246
- { value: 'softwrap', icon: 'ph--paragraph--regular' },
247
- ];
248
-
249
- const Styles = () => {
250
- const { cursorFallbackRange, model } = useSheetContext();
251
- const { onAction } = useToolbarContext('Styles');
252
- const { t } = useTranslation(SHEET_PLUGIN);
253
-
254
- // TODO(thure): Can this O(n) call be memoized?
255
- const activeValues = cursorFallbackRange
256
- ? model.sheet.ranges
257
- ?.filter(
258
- ({ range, key }) => key === 'style' && inRange(rangeFromIndex(model.sheet, range), cursorFallbackRange.from),
259
- )
260
- .reduce((acc, { value }) => {
261
- acc.add(value);
262
- return acc;
263
- }, new Set())
264
- : undefined;
265
-
266
- return (
267
- <>
268
- {styleOptions.map(({ value, icon }) => (
269
- <ToolbarItem
270
- itemType='toggle'
271
- key={value}
272
- pressed={activeValues?.has(value)}
273
- onPressedChange={(nextPressed: boolean) => {
274
- onAction?.({ key: 'style', value, unset: !nextPressed });
275
- }}
276
- icon={icon}
277
- >
278
- {t('toolbar action label', {
279
- key: t(`range key ${styleKey} label`),
280
- value: t(`range value ${value} label`),
281
- })}
282
- </ToolbarItem>
283
- ))}
284
- </>
285
- );
286
- };
287
-
288
- //
289
- // Actions
290
- //
291
-
292
- const Actions = () => {
293
- const { onAction } = useToolbarContext('Actions');
294
- const { cursorFallbackRange, cursor, model } = useSheetContext();
295
- const { t } = useTranslation(SHEET_PLUGIN);
296
-
297
- // TODO(thure): Can this O(n) call be memoized?
298
- const overlapsCommentAnchor = RefArray.allResolvedTargets(model.sheet.threads ?? [])
299
- .filter((thread) => thread.status !== 'resolved')
300
- .some((thread) => {
301
- if (!cursorFallbackRange) {
302
- return false;
303
- }
304
- return rangeToIndex(model.sheet, cursorFallbackRange) === thread.anchor;
305
- });
306
-
307
- const tooltipLabelKey = !cursor
308
- ? 'no cursor label'
309
- : overlapsCommentAnchor
310
- ? 'selection overlaps existing comment label'
311
- : 'comment label';
312
-
313
- return (
314
- <ToolbarItem
315
- itemType='button'
316
- value='comment'
317
- icon='ph--chat-text--regular'
318
- data-testid='editor.toolbar.comment'
319
- onClick={() => {
320
- if (!cursorFallbackRange) {
321
- return;
322
- }
323
- return onAction?.({
324
- key: 'comment',
325
- value: rangeToIndex(model.sheet, cursorFallbackRange),
326
- cellContent: model.getCellText(cursorFallbackRange.from),
327
- });
328
- }}
329
- disabled={!cursorFallbackRange || overlapsCommentAnchor}
330
- >
331
- {t(tooltipLabelKey)}
332
- </ToolbarItem>
333
- );
334
- };
335
-
336
- export const Toolbar = {
337
- Root: ToolbarRoot,
338
- Separator: ToolbarSeparator,
339
- Alignment,
340
- Styles,
341
- Actions,
342
- };
343
-
344
- export { useToolbarContext };