@papernote/ui 1.1.0 → 1.2.0

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 (75) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +455 -455
  3. package/dist/components/CurrencyInput.d.ts +52 -0
  4. package/dist/components/CurrencyInput.d.ts.map +1 -0
  5. package/dist/components/DataTable.d.ts +3 -1
  6. package/dist/components/DataTable.d.ts.map +1 -1
  7. package/dist/components/Modal.d.ts.map +1 -1
  8. package/dist/components/Page.d.ts +2 -0
  9. package/dist/components/Page.d.ts.map +1 -1
  10. package/dist/components/PageLayout.d.ts +5 -1
  11. package/dist/components/PageLayout.d.ts.map +1 -1
  12. package/dist/components/index.d.ts +4 -0
  13. package/dist/components/index.d.ts.map +1 -1
  14. package/dist/index.d.ts +204 -4
  15. package/dist/index.esm.js +415 -88
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +413 -82
  18. package/dist/index.js.map +1 -1
  19. package/dist/styles.css +2877 -2675
  20. package/dist/utils/excelExport.d.ts +143 -0
  21. package/dist/utils/excelExport.d.ts.map +1 -0
  22. package/dist/utils/index.d.ts +2 -0
  23. package/dist/utils/index.d.ts.map +1 -1
  24. package/package.json +1 -1
  25. package/src/components/AdminModal.css +49 -49
  26. package/src/components/CurrencyInput.stories.tsx +290 -0
  27. package/src/components/CurrencyInput.tsx +193 -0
  28. package/src/components/DataTable.tsx +78 -14
  29. package/src/components/Modal.stories.tsx +64 -0
  30. package/src/components/Modal.tsx +15 -2
  31. package/src/components/Page.stories.tsx +76 -0
  32. package/src/components/Page.tsx +35 -3
  33. package/src/components/PageLayout.stories.tsx +75 -0
  34. package/src/components/PageLayout.tsx +28 -9
  35. package/src/components/RoleManager.css +10 -10
  36. package/src/components/Spreadsheet.css +216 -216
  37. package/src/components/Spreadsheet.stories.tsx +362 -362
  38. package/src/components/Spreadsheet.tsx +351 -351
  39. package/src/components/SpreadsheetSimple.stories.tsx +27 -27
  40. package/src/components/Tabs.tsx +152 -152
  41. package/src/components/index.ts +5 -0
  42. package/src/styles/index.css +41 -4
  43. package/src/utils/excelExport.stories.tsx +535 -0
  44. package/src/utils/excelExport.ts +225 -0
  45. package/src/utils/index.ts +3 -0
  46. package/tailwind.config.js +253 -253
  47. package/dist/components/Button.stories.d.ts +0 -51
  48. package/dist/components/Button.stories.d.ts.map +0 -1
  49. package/dist/components/ChartVisualizationUI.d.ts +0 -21
  50. package/dist/components/ChartVisualizationUI.d.ts.map +0 -1
  51. package/dist/components/ChatUI.d.ts +0 -23
  52. package/dist/components/ChatUI.d.ts.map +0 -1
  53. package/dist/components/CommissionDashboardUI.d.ts +0 -25
  54. package/dist/components/CommissionDashboardUI.d.ts.map +0 -1
  55. package/dist/components/DataTable.stories.d.ts +0 -23
  56. package/dist/components/DataTable.stories.d.ts.map +0 -1
  57. package/dist/components/FormField.d.ts +0 -35
  58. package/dist/components/FormField.d.ts.map +0 -1
  59. package/dist/components/Input.stories.d.ts +0 -366
  60. package/dist/components/Input.stories.d.ts.map +0 -1
  61. package/dist/components/InsightsPanelUI.d.ts +0 -21
  62. package/dist/components/InsightsPanelUI.d.ts.map +0 -1
  63. package/dist/components/PaymentHistoryTimeline.d.ts +0 -34
  64. package/dist/components/PaymentHistoryTimeline.d.ts.map +0 -1
  65. package/dist/components/RelationshipManagerUI.d.ts +0 -60
  66. package/dist/components/RelationshipManagerUI.d.ts.map +0 -1
  67. package/dist/components/RoleManager.d.ts +0 -19
  68. package/dist/components/RoleManager.d.ts.map +0 -1
  69. package/dist/components/SplitCommissionBadge.d.ts +0 -18
  70. package/dist/components/SplitCommissionBadge.d.ts.map +0 -1
  71. package/dist/components/Spreadsheet.css +0 -216
  72. package/dist/components/__tests__/Button.test.d.ts +0 -2
  73. package/dist/components/__tests__/Button.test.d.ts.map +0 -1
  74. package/dist/components/__tests__/Input.test.d.ts +0 -2
  75. package/dist/components/__tests__/Input.test.d.ts.map +0 -1
@@ -1,362 +1,362 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { Spreadsheet, SpreadsheetReport } from './Spreadsheet';
3
- import type { SpreadsheetCell, Matrix } from './Spreadsheet';
4
- import { useState } from 'react';
5
- import Button from './Button';
6
- import { Calculator } from 'lucide-react';
7
-
8
- const meta: Meta<typeof Spreadsheet> = {
9
- title: 'Components/Spreadsheet',
10
- component: Spreadsheet,
11
- parameters: {
12
- docs: {
13
- description: {
14
- component:
15
- 'Interactive spreadsheet component with Excel formula support (280+ formulas via Fast Formula Parser), import/export functionality, and save capabilities. Perfect for report designers and data editing interfaces.',
16
- },
17
- },
18
- },
19
- tags: ['autodocs'],
20
- };
21
-
22
- export default meta;
23
- type Story = StoryObj<typeof Spreadsheet>;
24
-
25
- /**
26
- * Basic spreadsheet with default settings
27
- */
28
- export const Basic: Story = {
29
- args: {
30
- rows: 10,
31
- columns: 5,
32
- },
33
- };
34
-
35
- /**
36
- * Spreadsheet with toolbar showing import/export/save actions
37
- */
38
- export const WithToolbar: Story = {
39
- args: {
40
- rows: 15,
41
- columns: 8,
42
- showToolbar: true,
43
- enableImport: true,
44
- enableExport: true,
45
- enableSave: true,
46
- title: 'Data Editor',
47
- exportFileName: 'my-data.xlsx',
48
- },
49
- render: (args) => {
50
- const [data, setData] = useState<Matrix<SpreadsheetCell>>();
51
-
52
- return (
53
- <Spreadsheet
54
- {...args}
55
- data={data}
56
- onChange={setData}
57
- onSave={async (data) => {
58
- console.log('Saving data:', data);
59
- // Simulate API call
60
- await new Promise((resolve) => setTimeout(resolve, 1000));
61
- }}
62
- />
63
- );
64
- },
65
- };
66
-
67
- /**
68
- * Spreadsheet wrapped in Card component for better presentation
69
- */
70
- export const InCard: Story = {
71
- args: {
72
- rows: 12,
73
- columns: 6,
74
- showToolbar: true,
75
- enableImport: true,
76
- enableExport: true,
77
- enableSave: true,
78
- title: 'Financial Report',
79
- wrapInCard: true,
80
- },
81
- render: (args) => {
82
- const [data, setData] = useState<Matrix<SpreadsheetCell>>();
83
-
84
- return (
85
- <Spreadsheet
86
- {...args}
87
- data={data}
88
- onChange={setData}
89
- onSave={async (data) => {
90
- console.log('Saving:', data);
91
- await new Promise((resolve) => setTimeout(resolve, 800));
92
- }}
93
- />
94
- );
95
- },
96
- };
97
-
98
- /**
99
- * Pre-populated spreadsheet with formula examples
100
- */
101
- export const WithFormulas: Story = {
102
- render: () => {
103
- const initialData: Matrix<SpreadsheetCell> = [
104
- [
105
- { value: 'Product', readOnly: true, className: 'font-bold' },
106
- { value: 'Q1', readOnly: true, className: 'font-bold' },
107
- { value: 'Q2', readOnly: true, className: 'font-bold' },
108
- { value: 'Q3', readOnly: true, className: 'font-bold' },
109
- { value: 'Q4', readOnly: true, className: 'font-bold' },
110
- { value: 'Total', readOnly: true, className: 'font-bold' },
111
- ],
112
- [
113
- { value: 'Widget A' },
114
- { value: 15000 },
115
- { value: 18000 },
116
- { value: 22000 },
117
- { value: 19000 },
118
- { formula: '=SUM(B2:E2)' },
119
- ],
120
- [
121
- { value: 'Widget B' },
122
- { value: 12000 },
123
- { value: 13500 },
124
- { value: 14200 },
125
- { value: 15800 },
126
- { formula: '=SUM(B3:E3)' },
127
- ],
128
- [
129
- { value: 'Widget C' },
130
- { value: 8500 },
131
- { value: 9200 },
132
- { value: 11000 },
133
- { value: 12300 },
134
- { formula: '=SUM(B4:E4)' },
135
- ],
136
- [],
137
- [
138
- { value: 'Quarterly Total', readOnly: true, className: 'font-bold' },
139
- { formula: '=SUM(B2:B4)' },
140
- { formula: '=SUM(C2:C4)' },
141
- { formula: '=SUM(D2:D4)' },
142
- { formula: '=SUM(E2:E4)' },
143
- { formula: '=SUM(F2:F4)' },
144
- ],
145
- [
146
- { value: 'Average per Product', readOnly: true, className: 'font-bold' },
147
- { formula: '=AVERAGE(B2:B4)' },
148
- { formula: '=AVERAGE(C2:C4)' },
149
- { formula: '=AVERAGE(D2:D4)' },
150
- { formula: '=AVERAGE(E2:E4)' },
151
- { formula: '=AVERAGE(F2:F4)' },
152
- ],
153
- ];
154
-
155
- const [data, setData] = useState<Matrix<SpreadsheetCell>>(initialData);
156
-
157
- return (
158
- <div className="p-4">
159
- <h3 className="text-lg font-semibold mb-4">Sales Report with Formulas</h3>
160
- <p className="text-sm text-ink-600 mb-4">
161
- This example demonstrates SUM and AVERAGE formulas. Try editing the values in Q1-Q4 columns
162
- and watch the totals update automatically!
163
- </p>
164
- <Spreadsheet
165
- data={data}
166
- onChange={setData}
167
- showToolbar
168
- enableExport
169
- enableSave
170
- title="Quarterly Sales Report"
171
- wrapInCard
172
- exportFileName="sales-report.xlsx"
173
- onSave={async (data) => {
174
- console.log('Saving report:', data);
175
- await new Promise((resolve) => setTimeout(resolve, 1000));
176
- }}
177
- />
178
- </div>
179
- );
180
- },
181
- };
182
-
183
- /**
184
- * Read-only spreadsheet for viewing reports
185
- */
186
- export const ReadOnly: Story = {
187
- render: () => {
188
- const reportData: Matrix<SpreadsheetCell> = [
189
- [
190
- { value: 'Metric', readOnly: true },
191
- { value: 'Value', readOnly: true },
192
- { value: 'Target', readOnly: true },
193
- { value: 'Status', readOnly: true },
194
- ],
195
- [{ value: 'Revenue' }, { value: 125000 }, { value: 120000 }, { value: '✓ Met' }],
196
- [{ value: 'Expenses' }, { value: 85000 }, { value: 90000 }, { value: '✓ Under' }],
197
- [{ value: 'Profit' }, { formula: '=B2-B3' }, { formula: '=C2-C3' }, { value: '✓ Above' }],
198
- [{ value: 'Margin %' }, { formula: '=B4/B2*100' }, { formula: '=C4/C2*100' }, { value: '' }],
199
- ];
200
-
201
- return (
202
- <Spreadsheet
203
- data={reportData}
204
- readOnly
205
- title="Financial Summary (Read-Only)"
206
- showToolbar
207
- enableExport
208
- wrapInCard
209
- exportFileName="financial-summary.xlsx"
210
- />
211
- );
212
- },
213
- };
214
-
215
- /**
216
- * SpreadsheetReport component - pre-configured for report designer use
217
- */
218
- export const ReportDesigner: Story = {
219
- render: () => {
220
- const [reportData, setReportData] = useState<Matrix<SpreadsheetCell>>([
221
- [
222
- { value: 'Month', readOnly: true },
223
- { value: 'Sales', readOnly: true },
224
- { value: 'Costs', readOnly: true },
225
- { value: 'Profit', readOnly: true },
226
- ],
227
- [{ value: 'January' }, { value: 50000 }, { value: 30000 }, { formula: '=B2-C2' }],
228
- [{ value: 'February' }, { value: 55000 }, { value: 32000 }, { formula: '=B3-C3' }],
229
- [{ value: 'March' }, { value: 62000 }, { value: 35000 }, { formula: '=B4-C4' }],
230
- [],
231
- [
232
- { value: 'Total', readOnly: true },
233
- { formula: '=SUM(B2:B4)' },
234
- { formula: '=SUM(C2:C4)' },
235
- { formula: '=SUM(D2:D4)' },
236
- ],
237
- ]);
238
-
239
- return (
240
- <div className="max-w-6xl mx-auto p-6">
241
- <h2 className="text-2xl font-bold mb-4">Report Designer</h2>
242
- <p className="text-ink-600 mb-6">
243
- The SpreadsheetReport component comes pre-configured with toolbar, import/export, and save
244
- functionality. Perfect for building interactive reports!
245
- </p>
246
-
247
- <SpreadsheetReport
248
- data={reportData}
249
- onChange={setReportData}
250
- title="Monthly Financial Report"
251
- exportFileName="monthly-report.xlsx"
252
- onSave={async (data) => {
253
- console.log('Saving report:', data);
254
- await new Promise((resolve) => setTimeout(resolve, 1200));
255
- }}
256
- />
257
-
258
- <div className="mt-6 p-4 bg-paper-50 border border-stone-200 rounded-lg">
259
- <h3 className="font-semibold mb-2">Formula Support</h3>
260
- <p className="text-sm text-ink-600 mb-2">
261
- Fast Formula Parser provides 280+ Excel formulas including:
262
- </p>
263
- <ul className="text-sm text-ink-600 list-disc list-inside space-y-1">
264
- <li>Math: SUM, AVERAGE, ROUND, ABS, POWER, SQRT</li>
265
- <li>Logical: IF, AND, OR, NOT, IFERROR</li>
266
- <li>Lookup: VLOOKUP, HLOOKUP, INDEX</li>
267
- <li>Text: CONCATENATE, LEFT, RIGHT, TRIM, UPPER, LOWER</li>
268
- <li>Date/Time: DATE, TODAY, YEAR, MONTH, DAY</li>
269
- <li>Statistical: COUNT, COUNTIF, MAX, MIN, STDEV</li>
270
- </ul>
271
- </div>
272
- </div>
273
- );
274
- },
275
- };
276
-
277
- /**
278
- * Spreadsheet with custom actions in toolbar
279
- */
280
- export const WithCustomActions: Story = {
281
- render: () => {
282
- const [data, setData] = useState<Matrix<SpreadsheetCell>>();
283
-
284
- return (
285
- <Spreadsheet
286
- data={data}
287
- onChange={setData}
288
- rows={10}
289
- columns={6}
290
- showToolbar
291
- enableImport
292
- enableExport
293
- title="Custom Actions Demo"
294
- actions={
295
- <>
296
- <Button
297
- variant="ghost"
298
- size="sm"
299
- icon={<Calculator className="h-4 w-4" />}
300
- onClick={() => console.log('Calculate clicked')}
301
- >
302
- Calculate
303
- </Button>
304
- <Button
305
- variant="secondary"
306
- size="sm"
307
- onClick={() => console.log('Clear clicked')}
308
- >
309
- Clear
310
- </Button>
311
- </>
312
- }
313
- wrapInCard
314
- />
315
- );
316
- },
317
- };
318
-
319
- /**
320
- * Compact spreadsheet for smaller spaces
321
- */
322
- export const Compact: Story = {
323
- args: {
324
- rows: 8,
325
- columns: 4,
326
- showToolbar: false,
327
- className: 'text-sm',
328
- },
329
- };
330
-
331
- /**
332
- * Large spreadsheet for complex data entry
333
- */
334
- export const Large: Story = {
335
- args: {
336
- rows: 50,
337
- columns: 20,
338
- showToolbar: true,
339
- enableImport: true,
340
- enableExport: true,
341
- enableSave: true,
342
- title: 'Large Dataset Editor',
343
- wrapInCard: true,
344
- },
345
- render: (args) => {
346
- const [data, setData] = useState<Matrix<SpreadsheetCell>>();
347
-
348
- return (
349
- <div style={{ height: '600px' }}>
350
- <Spreadsheet
351
- {...args}
352
- data={data}
353
- onChange={setData}
354
- onSave={async (data) => {
355
- console.log('Saving large dataset');
356
- await new Promise((resolve) => setTimeout(resolve, 1500));
357
- }}
358
- />
359
- </div>
360
- );
361
- },
362
- };
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { Spreadsheet, SpreadsheetReport } from './Spreadsheet';
3
+ import type { SpreadsheetCell, Matrix } from './Spreadsheet';
4
+ import { useState } from 'react';
5
+ import Button from './Button';
6
+ import { Calculator } from 'lucide-react';
7
+
8
+ const meta: Meta<typeof Spreadsheet> = {
9
+ title: 'Components/Spreadsheet',
10
+ component: Spreadsheet,
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component:
15
+ 'Interactive spreadsheet component with Excel formula support (280+ formulas via Fast Formula Parser), import/export functionality, and save capabilities. Perfect for report designers and data editing interfaces.',
16
+ },
17
+ },
18
+ },
19
+ tags: ['autodocs'],
20
+ };
21
+
22
+ export default meta;
23
+ type Story = StoryObj<typeof Spreadsheet>;
24
+
25
+ /**
26
+ * Basic spreadsheet with default settings
27
+ */
28
+ export const Basic: Story = {
29
+ args: {
30
+ rows: 10,
31
+ columns: 5,
32
+ },
33
+ };
34
+
35
+ /**
36
+ * Spreadsheet with toolbar showing import/export/save actions
37
+ */
38
+ export const WithToolbar: Story = {
39
+ args: {
40
+ rows: 15,
41
+ columns: 8,
42
+ showToolbar: true,
43
+ enableImport: true,
44
+ enableExport: true,
45
+ enableSave: true,
46
+ title: 'Data Editor',
47
+ exportFileName: 'my-data.xlsx',
48
+ },
49
+ render: (args) => {
50
+ const [data, setData] = useState<Matrix<SpreadsheetCell>>();
51
+
52
+ return (
53
+ <Spreadsheet
54
+ {...args}
55
+ data={data}
56
+ onChange={setData}
57
+ onSave={async (data) => {
58
+ console.log('Saving data:', data);
59
+ // Simulate API call
60
+ await new Promise((resolve) => setTimeout(resolve, 1000));
61
+ }}
62
+ />
63
+ );
64
+ },
65
+ };
66
+
67
+ /**
68
+ * Spreadsheet wrapped in Card component for better presentation
69
+ */
70
+ export const InCard: Story = {
71
+ args: {
72
+ rows: 12,
73
+ columns: 6,
74
+ showToolbar: true,
75
+ enableImport: true,
76
+ enableExport: true,
77
+ enableSave: true,
78
+ title: 'Financial Report',
79
+ wrapInCard: true,
80
+ },
81
+ render: (args) => {
82
+ const [data, setData] = useState<Matrix<SpreadsheetCell>>();
83
+
84
+ return (
85
+ <Spreadsheet
86
+ {...args}
87
+ data={data}
88
+ onChange={setData}
89
+ onSave={async (data) => {
90
+ console.log('Saving:', data);
91
+ await new Promise((resolve) => setTimeout(resolve, 800));
92
+ }}
93
+ />
94
+ );
95
+ },
96
+ };
97
+
98
+ /**
99
+ * Pre-populated spreadsheet with formula examples
100
+ */
101
+ export const WithFormulas: Story = {
102
+ render: () => {
103
+ const initialData: Matrix<SpreadsheetCell> = [
104
+ [
105
+ { value: 'Product', readOnly: true, className: 'font-bold' },
106
+ { value: 'Q1', readOnly: true, className: 'font-bold' },
107
+ { value: 'Q2', readOnly: true, className: 'font-bold' },
108
+ { value: 'Q3', readOnly: true, className: 'font-bold' },
109
+ { value: 'Q4', readOnly: true, className: 'font-bold' },
110
+ { value: 'Total', readOnly: true, className: 'font-bold' },
111
+ ],
112
+ [
113
+ { value: 'Widget A' },
114
+ { value: 15000 },
115
+ { value: 18000 },
116
+ { value: 22000 },
117
+ { value: 19000 },
118
+ { formula: '=SUM(B2:E2)' },
119
+ ],
120
+ [
121
+ { value: 'Widget B' },
122
+ { value: 12000 },
123
+ { value: 13500 },
124
+ { value: 14200 },
125
+ { value: 15800 },
126
+ { formula: '=SUM(B3:E3)' },
127
+ ],
128
+ [
129
+ { value: 'Widget C' },
130
+ { value: 8500 },
131
+ { value: 9200 },
132
+ { value: 11000 },
133
+ { value: 12300 },
134
+ { formula: '=SUM(B4:E4)' },
135
+ ],
136
+ [],
137
+ [
138
+ { value: 'Quarterly Total', readOnly: true, className: 'font-bold' },
139
+ { formula: '=SUM(B2:B4)' },
140
+ { formula: '=SUM(C2:C4)' },
141
+ { formula: '=SUM(D2:D4)' },
142
+ { formula: '=SUM(E2:E4)' },
143
+ { formula: '=SUM(F2:F4)' },
144
+ ],
145
+ [
146
+ { value: 'Average per Product', readOnly: true, className: 'font-bold' },
147
+ { formula: '=AVERAGE(B2:B4)' },
148
+ { formula: '=AVERAGE(C2:C4)' },
149
+ { formula: '=AVERAGE(D2:D4)' },
150
+ { formula: '=AVERAGE(E2:E4)' },
151
+ { formula: '=AVERAGE(F2:F4)' },
152
+ ],
153
+ ];
154
+
155
+ const [data, setData] = useState<Matrix<SpreadsheetCell>>(initialData);
156
+
157
+ return (
158
+ <div className="p-4">
159
+ <h3 className="text-lg font-semibold mb-4">Sales Report with Formulas</h3>
160
+ <p className="text-sm text-ink-600 mb-4">
161
+ This example demonstrates SUM and AVERAGE formulas. Try editing the values in Q1-Q4 columns
162
+ and watch the totals update automatically!
163
+ </p>
164
+ <Spreadsheet
165
+ data={data}
166
+ onChange={setData}
167
+ showToolbar
168
+ enableExport
169
+ enableSave
170
+ title="Quarterly Sales Report"
171
+ wrapInCard
172
+ exportFileName="sales-report.xlsx"
173
+ onSave={async (data) => {
174
+ console.log('Saving report:', data);
175
+ await new Promise((resolve) => setTimeout(resolve, 1000));
176
+ }}
177
+ />
178
+ </div>
179
+ );
180
+ },
181
+ };
182
+
183
+ /**
184
+ * Read-only spreadsheet for viewing reports
185
+ */
186
+ export const ReadOnly: Story = {
187
+ render: () => {
188
+ const reportData: Matrix<SpreadsheetCell> = [
189
+ [
190
+ { value: 'Metric', readOnly: true },
191
+ { value: 'Value', readOnly: true },
192
+ { value: 'Target', readOnly: true },
193
+ { value: 'Status', readOnly: true },
194
+ ],
195
+ [{ value: 'Revenue' }, { value: 125000 }, { value: 120000 }, { value: '✓ Met' }],
196
+ [{ value: 'Expenses' }, { value: 85000 }, { value: 90000 }, { value: '✓ Under' }],
197
+ [{ value: 'Profit' }, { formula: '=B2-B3' }, { formula: '=C2-C3' }, { value: '✓ Above' }],
198
+ [{ value: 'Margin %' }, { formula: '=B4/B2*100' }, { formula: '=C4/C2*100' }, { value: '' }],
199
+ ];
200
+
201
+ return (
202
+ <Spreadsheet
203
+ data={reportData}
204
+ readOnly
205
+ title="Financial Summary (Read-Only)"
206
+ showToolbar
207
+ enableExport
208
+ wrapInCard
209
+ exportFileName="financial-summary.xlsx"
210
+ />
211
+ );
212
+ },
213
+ };
214
+
215
+ /**
216
+ * SpreadsheetReport component - pre-configured for report designer use
217
+ */
218
+ export const ReportDesigner: Story = {
219
+ render: () => {
220
+ const [reportData, setReportData] = useState<Matrix<SpreadsheetCell>>([
221
+ [
222
+ { value: 'Month', readOnly: true },
223
+ { value: 'Sales', readOnly: true },
224
+ { value: 'Costs', readOnly: true },
225
+ { value: 'Profit', readOnly: true },
226
+ ],
227
+ [{ value: 'January' }, { value: 50000 }, { value: 30000 }, { formula: '=B2-C2' }],
228
+ [{ value: 'February' }, { value: 55000 }, { value: 32000 }, { formula: '=B3-C3' }],
229
+ [{ value: 'March' }, { value: 62000 }, { value: 35000 }, { formula: '=B4-C4' }],
230
+ [],
231
+ [
232
+ { value: 'Total', readOnly: true },
233
+ { formula: '=SUM(B2:B4)' },
234
+ { formula: '=SUM(C2:C4)' },
235
+ { formula: '=SUM(D2:D4)' },
236
+ ],
237
+ ]);
238
+
239
+ return (
240
+ <div className="max-w-6xl mx-auto p-6">
241
+ <h2 className="text-2xl font-bold mb-4">Report Designer</h2>
242
+ <p className="text-ink-600 mb-6">
243
+ The SpreadsheetReport component comes pre-configured with toolbar, import/export, and save
244
+ functionality. Perfect for building interactive reports!
245
+ </p>
246
+
247
+ <SpreadsheetReport
248
+ data={reportData}
249
+ onChange={setReportData}
250
+ title="Monthly Financial Report"
251
+ exportFileName="monthly-report.xlsx"
252
+ onSave={async (data) => {
253
+ console.log('Saving report:', data);
254
+ await new Promise((resolve) => setTimeout(resolve, 1200));
255
+ }}
256
+ />
257
+
258
+ <div className="mt-6 p-4 bg-paper-50 border border-stone-200 rounded-lg">
259
+ <h3 className="font-semibold mb-2">Formula Support</h3>
260
+ <p className="text-sm text-ink-600 mb-2">
261
+ Fast Formula Parser provides 280+ Excel formulas including:
262
+ </p>
263
+ <ul className="text-sm text-ink-600 list-disc list-inside space-y-1">
264
+ <li>Math: SUM, AVERAGE, ROUND, ABS, POWER, SQRT</li>
265
+ <li>Logical: IF, AND, OR, NOT, IFERROR</li>
266
+ <li>Lookup: VLOOKUP, HLOOKUP, INDEX</li>
267
+ <li>Text: CONCATENATE, LEFT, RIGHT, TRIM, UPPER, LOWER</li>
268
+ <li>Date/Time: DATE, TODAY, YEAR, MONTH, DAY</li>
269
+ <li>Statistical: COUNT, COUNTIF, MAX, MIN, STDEV</li>
270
+ </ul>
271
+ </div>
272
+ </div>
273
+ );
274
+ },
275
+ };
276
+
277
+ /**
278
+ * Spreadsheet with custom actions in toolbar
279
+ */
280
+ export const WithCustomActions: Story = {
281
+ render: () => {
282
+ const [data, setData] = useState<Matrix<SpreadsheetCell>>();
283
+
284
+ return (
285
+ <Spreadsheet
286
+ data={data}
287
+ onChange={setData}
288
+ rows={10}
289
+ columns={6}
290
+ showToolbar
291
+ enableImport
292
+ enableExport
293
+ title="Custom Actions Demo"
294
+ actions={
295
+ <>
296
+ <Button
297
+ variant="ghost"
298
+ size="sm"
299
+ icon={<Calculator className="h-4 w-4" />}
300
+ onClick={() => console.log('Calculate clicked')}
301
+ >
302
+ Calculate
303
+ </Button>
304
+ <Button
305
+ variant="secondary"
306
+ size="sm"
307
+ onClick={() => console.log('Clear clicked')}
308
+ >
309
+ Clear
310
+ </Button>
311
+ </>
312
+ }
313
+ wrapInCard
314
+ />
315
+ );
316
+ },
317
+ };
318
+
319
+ /**
320
+ * Compact spreadsheet for smaller spaces
321
+ */
322
+ export const Compact: Story = {
323
+ args: {
324
+ rows: 8,
325
+ columns: 4,
326
+ showToolbar: false,
327
+ className: 'text-sm',
328
+ },
329
+ };
330
+
331
+ /**
332
+ * Large spreadsheet for complex data entry
333
+ */
334
+ export const Large: Story = {
335
+ args: {
336
+ rows: 50,
337
+ columns: 20,
338
+ showToolbar: true,
339
+ enableImport: true,
340
+ enableExport: true,
341
+ enableSave: true,
342
+ title: 'Large Dataset Editor',
343
+ wrapInCard: true,
344
+ },
345
+ render: (args) => {
346
+ const [data, setData] = useState<Matrix<SpreadsheetCell>>();
347
+
348
+ return (
349
+ <div style={{ height: '600px' }}>
350
+ <Spreadsheet
351
+ {...args}
352
+ data={data}
353
+ onChange={setData}
354
+ onSave={async (data) => {
355
+ console.log('Saving large dataset');
356
+ await new Promise((resolve) => setTimeout(resolve, 1500));
357
+ }}
358
+ />
359
+ </div>
360
+ );
361
+ },
362
+ };