@sqlrooms/cells 0.29.0-rc.1 → 0.29.0-rc.3

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 (144) hide show
  1. package/README.md +8 -8
  2. package/dist/cellsSlice.d.ts.map +1 -1
  3. package/dist/cellsSlice.js +305 -264
  4. package/dist/cellsSlice.js.map +1 -1
  5. package/dist/components/AggregationSelector.d.ts +8 -0
  6. package/dist/components/AggregationSelector.d.ts.map +1 -0
  7. package/dist/components/AggregationSelector.js +13 -0
  8. package/dist/components/AggregationSelector.js.map +1 -0
  9. package/dist/components/CellSourceSelector.d.ts +12 -0
  10. package/dist/components/CellSourceSelector.d.ts.map +1 -0
  11. package/dist/components/CellSourceSelector.js +34 -0
  12. package/dist/components/CellSourceSelector.js.map +1 -0
  13. package/dist/components/ChartTypeSelector.d.ts +8 -0
  14. package/dist/components/ChartTypeSelector.d.ts.map +1 -0
  15. package/dist/components/ChartTypeSelector.js +13 -0
  16. package/dist/components/ChartTypeSelector.js.map +1 -0
  17. package/dist/components/CollapsibleSectionButton.d.ts +10 -0
  18. package/dist/components/CollapsibleSectionButton.d.ts.map +1 -0
  19. package/dist/components/CollapsibleSectionButton.js +10 -0
  20. package/dist/components/CollapsibleSectionButton.js.map +1 -0
  21. package/dist/components/ColorSelector.d.ts +24 -0
  22. package/dist/components/ColorSelector.d.ts.map +1 -0
  23. package/dist/components/ColorSelector.js +17 -0
  24. package/dist/components/ColorSelector.js.map +1 -0
  25. package/dist/components/FieldSelector.d.ts +11 -0
  26. package/dist/components/FieldSelector.d.ts.map +1 -0
  27. package/dist/components/FieldSelector.js +11 -0
  28. package/dist/components/FieldSelector.js.map +1 -0
  29. package/dist/components/FieldTypeIcon.d.ts +8 -0
  30. package/dist/components/FieldTypeIcon.d.ts.map +1 -0
  31. package/dist/components/FieldTypeIcon.js +27 -0
  32. package/dist/components/FieldTypeIcon.js.map +1 -0
  33. package/dist/components/InputCellContent.d.ts.map +1 -1
  34. package/dist/components/InputCellContent.js +3 -3
  35. package/dist/components/InputCellContent.js.map +1 -1
  36. package/dist/components/SelectionListener.d.ts +15 -0
  37. package/dist/components/SelectionListener.d.ts.map +1 -0
  38. package/dist/components/SelectionListener.js +74 -0
  39. package/dist/components/SelectionListener.js.map +1 -0
  40. package/dist/components/SqlCellConnectionSelector.d.ts +9 -0
  41. package/dist/components/SqlCellConnectionSelector.d.ts.map +1 -0
  42. package/dist/components/SqlCellConnectionSelector.js +21 -0
  43. package/dist/components/SqlCellConnectionSelector.js.map +1 -0
  44. package/dist/components/SqlCellContent.d.ts.map +1 -1
  45. package/dist/components/SqlCellContent.js +31 -156
  46. package/dist/components/SqlCellContent.js.map +1 -1
  47. package/dist/components/SqlCellDependentsMenu.d.ts +11 -0
  48. package/dist/components/SqlCellDependentsMenu.d.ts.map +1 -0
  49. package/dist/components/SqlCellDependentsMenu.js +62 -0
  50. package/dist/components/SqlCellDependentsMenu.js.map +1 -0
  51. package/dist/components/SqlCellEditor.d.ts +14 -0
  52. package/dist/components/SqlCellEditor.d.ts.map +1 -0
  53. package/dist/components/SqlCellEditor.js +17 -0
  54. package/dist/components/SqlCellEditor.js.map +1 -0
  55. package/dist/components/SqlCellResultNameEditor.d.ts +8 -0
  56. package/dist/components/SqlCellResultNameEditor.d.ts.map +1 -0
  57. package/dist/components/SqlCellResultNameEditor.js +38 -0
  58. package/dist/components/SqlCellResultNameEditor.js.map +1 -0
  59. package/dist/components/SqlCellResults.d.ts +17 -0
  60. package/dist/components/SqlCellResults.d.ts.map +1 -0
  61. package/dist/components/SqlCellResults.js +45 -0
  62. package/dist/components/SqlCellResults.js.map +1 -0
  63. package/dist/components/SqlCellRunButton.d.ts +5 -6
  64. package/dist/components/SqlCellRunButton.d.ts.map +1 -1
  65. package/dist/components/SqlCellRunButton.js +11 -7
  66. package/dist/components/SqlCellRunButton.js.map +1 -1
  67. package/dist/components/SqlQueryPreview.d.ts +9 -0
  68. package/dist/components/SqlQueryPreview.d.ts.map +1 -0
  69. package/dist/components/SqlQueryPreview.js +14 -0
  70. package/dist/components/SqlQueryPreview.js.map +1 -0
  71. package/dist/components/TextCellContent.d.ts.map +1 -1
  72. package/dist/components/TextCellContent.js +24 -7
  73. package/dist/components/TextCellContent.js.map +1 -1
  74. package/dist/components/VegaCellContent.d.ts +0 -1
  75. package/dist/components/VegaCellContent.d.ts.map +1 -1
  76. package/dist/components/VegaCellContent.js +61 -47
  77. package/dist/components/VegaCellContent.js.map +1 -1
  78. package/dist/components/VegaCellHeader.d.ts +11 -0
  79. package/dist/components/VegaCellHeader.d.ts.map +1 -0
  80. package/dist/components/VegaCellHeader.js +32 -0
  81. package/dist/components/VegaCellHeader.js.map +1 -0
  82. package/dist/components/VegaConfigPanel.d.ts +5 -0
  83. package/dist/components/VegaConfigPanel.d.ts.map +1 -1
  84. package/dist/components/VegaConfigPanel.js +53 -63
  85. package/dist/components/VegaConfigPanel.js.map +1 -1
  86. package/dist/dagUtils.d.ts +10 -9
  87. package/dist/dagUtils.d.ts.map +1 -1
  88. package/dist/dagUtils.js +76 -50
  89. package/dist/dagUtils.js.map +1 -1
  90. package/dist/defaultCellRegistry.d.ts.map +1 -1
  91. package/dist/defaultCellRegistry.js +79 -36
  92. package/dist/defaultCellRegistry.js.map +1 -1
  93. package/dist/execution.d.ts.map +1 -1
  94. package/dist/execution.js +24 -17
  95. package/dist/execution.js.map +1 -1
  96. package/dist/helpers.d.ts +20 -16
  97. package/dist/helpers.d.ts.map +1 -1
  98. package/dist/helpers.js +79 -44
  99. package/dist/helpers.js.map +1 -1
  100. package/dist/hooks/useVegaCellDataSource.d.ts +18 -0
  101. package/dist/hooks/useVegaCellDataSource.d.ts.map +1 -0
  102. package/dist/hooks/useVegaCellDataSource.js +40 -0
  103. package/dist/hooks/useVegaCellDataSource.js.map +1 -0
  104. package/dist/hooks/useVegaCellQuery.d.ts +16 -0
  105. package/dist/hooks/useVegaCellQuery.d.ts.map +1 -0
  106. package/dist/hooks/useVegaCellQuery.js +25 -0
  107. package/dist/hooks/useVegaCellQuery.js.map +1 -0
  108. package/dist/index.d.ts +3 -3
  109. package/dist/index.d.ts.map +1 -1
  110. package/dist/index.js +3 -3
  111. package/dist/index.js.map +1 -1
  112. package/dist/sqlHelpers.d.ts +8 -8
  113. package/dist/sqlHelpers.d.ts.map +1 -1
  114. package/dist/sqlHelpers.js +16 -12
  115. package/dist/sqlHelpers.js.map +1 -1
  116. package/dist/types.d.ts +113 -70
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js +22 -13
  119. package/dist/types.js.map +1 -1
  120. package/dist/useValidateResultName.d.ts +34 -0
  121. package/dist/useValidateResultName.d.ts.map +1 -0
  122. package/dist/useValidateResultName.js +111 -0
  123. package/dist/useValidateResultName.js.map +1 -0
  124. package/dist/utils.d.ts +10 -2
  125. package/dist/utils.d.ts.map +1 -1
  126. package/dist/utils.js +20 -4
  127. package/dist/utils.js.map +1 -1
  128. package/dist/vegaSelectionUtils.d.ts +14 -0
  129. package/dist/vegaSelectionUtils.d.ts.map +1 -0
  130. package/dist/vegaSelectionUtils.js +97 -0
  131. package/dist/vegaSelectionUtils.js.map +1 -0
  132. package/dist/vegaSpecBuilder.d.ts +34 -0
  133. package/dist/vegaSpecBuilder.d.ts.map +1 -0
  134. package/dist/vegaSpecBuilder.js +90 -0
  135. package/dist/vegaSpecBuilder.js.map +1 -0
  136. package/package.json +12 -13
  137. package/dist/components/DeleteSheetModal.d.ts +0 -9
  138. package/dist/components/DeleteSheetModal.d.ts.map +0 -1
  139. package/dist/components/DeleteSheetModal.js +0 -6
  140. package/dist/components/DeleteSheetModal.js.map +0 -1
  141. package/dist/components/SheetsTabBar.d.ts +0 -6
  142. package/dist/components/SheetsTabBar.d.ts.map +0 -1
  143. package/dist/components/SheetsTabBar.js +0 -57
  144. package/dist/components/SheetsTabBar.js.map +0 -1
@@ -0,0 +1,90 @@
1
+ import { BRUSH_PARAM_NAME } from './vegaSelectionUtils';
2
+ /**
3
+ * Read the flat encoding/mark values from either a flat spec or a
4
+ * dual-layer cross-filter spec so the config panel dropdowns reflect
5
+ * the current state regardless of spec shape.
6
+ */
7
+ export function readSpecValues(spec) {
8
+ if (spec?.layer && Array.isArray(spec.layer)) {
9
+ const fg = spec.layer[1] ?? spec.layer[0];
10
+ const bg = spec.layer[0];
11
+ return {
12
+ mark: fg?.mark ?? bg?.mark,
13
+ xField: fg?.encoding?.x?.field ?? bg?.encoding?.x?.field,
14
+ yField: fg?.encoding?.y?.field ?? bg?.encoding?.y?.field,
15
+ yAggregate: fg?.encoding?.y?.aggregate ?? bg?.encoding?.y?.aggregate,
16
+ color: fg?.encoding?.color?.value,
17
+ };
18
+ }
19
+ return {
20
+ mark: spec?.mark,
21
+ xField: spec?.encoding?.x?.field,
22
+ yField: spec?.encoding?.y?.field,
23
+ yAggregate: spec?.encoding?.y?.aggregate,
24
+ color: spec?.encoding?.color?.value,
25
+ };
26
+ }
27
+ /**
28
+ * Build a dual-layer Vega-Lite spec with a brush selection param on the
29
+ * background layer and a filter transform on the foreground layer.
30
+ */
31
+ export function buildCrossFilterSpec(opts) {
32
+ const { mark, xField, xFieldType, yField, yAggregate, color } = opts;
33
+ const xEnc = xField
34
+ ? {
35
+ field: xField,
36
+ ...(xFieldType === 'numeric' ? { bin: { maxbins: 20 } } : {}),
37
+ }
38
+ : undefined;
39
+ const yEnc = yField
40
+ ? { field: yField, aggregate: yAggregate ?? 'sum' }
41
+ : yAggregate === 'count'
42
+ ? { aggregate: 'count' }
43
+ : undefined;
44
+ const encoding = {};
45
+ if (xEnc)
46
+ encoding.x = xEnc;
47
+ if (yEnc)
48
+ encoding.y = yEnc;
49
+ return {
50
+ layer: [
51
+ {
52
+ params: [
53
+ {
54
+ name: BRUSH_PARAM_NAME,
55
+ select: { type: 'interval', encodings: ['x'] },
56
+ },
57
+ ],
58
+ mark,
59
+ encoding: {
60
+ ...encoding,
61
+ color: { value: '#ddd' },
62
+ },
63
+ },
64
+ {
65
+ transform: [{ filter: { param: BRUSH_PARAM_NAME } }],
66
+ mark,
67
+ encoding: {
68
+ ...encoding,
69
+ ...(color ? { color: { value: color } } : {}),
70
+ },
71
+ },
72
+ ],
73
+ padding: 20,
74
+ };
75
+ }
76
+ /** Build a simple flat spec (no cross-filtering). */
77
+ export function buildFlatSpec(opts) {
78
+ const { mark, xField, yField, yAggregate, color } = opts;
79
+ const encoding = {};
80
+ if (xField)
81
+ encoding.x = { field: xField };
82
+ if (yField)
83
+ encoding.y = { field: yField, aggregate: yAggregate ?? 'sum' };
84
+ else if (yAggregate === 'count')
85
+ encoding.y = { aggregate: 'count' };
86
+ if (color)
87
+ encoding.color = { value: color };
88
+ return { mark, encoding, padding: 20 };
89
+ }
90
+ //# sourceMappingURL=vegaSpecBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vegaSpecBuilder.js","sourceRoot":"","sources":["../src/vegaSpecBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["import {BRUSH_PARAM_NAME} from './vegaSelectionUtils';\nimport type {BrushFieldType} from './types';\n\n/**\n * Read the flat encoding/mark values from either a flat spec or a\n * dual-layer cross-filter spec so the config panel dropdowns reflect\n * the current state regardless of spec shape.\n */\nexport function readSpecValues(spec: any): {\n mark: string | undefined;\n xField: string | undefined;\n yField: string | undefined;\n yAggregate: string | undefined;\n color: string | undefined;\n} {\n if (spec?.layer && Array.isArray(spec.layer)) {\n const fg = spec.layer[1] ?? spec.layer[0];\n const bg = spec.layer[0];\n return {\n mark: fg?.mark ?? bg?.mark,\n xField: fg?.encoding?.x?.field ?? bg?.encoding?.x?.field,\n yField: fg?.encoding?.y?.field ?? bg?.encoding?.y?.field,\n yAggregate: fg?.encoding?.y?.aggregate ?? bg?.encoding?.y?.aggregate,\n color: fg?.encoding?.color?.value,\n };\n }\n return {\n mark: spec?.mark,\n xField: spec?.encoding?.x?.field,\n yField: spec?.encoding?.y?.field,\n yAggregate: spec?.encoding?.y?.aggregate,\n color: spec?.encoding?.color?.value,\n };\n}\n\n/**\n * Build a dual-layer Vega-Lite spec with a brush selection param on the\n * background layer and a filter transform on the foreground layer.\n */\nexport function buildCrossFilterSpec(opts: {\n mark: string;\n xField?: string;\n xFieldType?: BrushFieldType;\n yField?: string;\n yAggregate?: string;\n color?: string;\n}): any {\n const {mark, xField, xFieldType, yField, yAggregate, color} = opts;\n const xEnc: any = xField\n ? {\n field: xField,\n ...(xFieldType === 'numeric' ? {bin: {maxbins: 20}} : {}),\n }\n : undefined;\n const yEnc: any = yField\n ? {field: yField, aggregate: yAggregate ?? 'sum'}\n : yAggregate === 'count'\n ? {aggregate: 'count'}\n : undefined;\n\n const encoding: any = {};\n if (xEnc) encoding.x = xEnc;\n if (yEnc) encoding.y = yEnc;\n\n return {\n layer: [\n {\n params: [\n {\n name: BRUSH_PARAM_NAME,\n select: {type: 'interval', encodings: ['x']},\n },\n ],\n mark,\n encoding: {\n ...encoding,\n color: {value: '#ddd'},\n },\n },\n {\n transform: [{filter: {param: BRUSH_PARAM_NAME}}],\n mark,\n encoding: {\n ...encoding,\n ...(color ? {color: {value: color}} : {}),\n },\n },\n ],\n padding: 20,\n };\n}\n\n/** Build a simple flat spec (no cross-filtering). */\nexport function buildFlatSpec(opts: {\n mark: string;\n xField?: string;\n yField?: string;\n yAggregate?: string;\n color?: string;\n}): any {\n const {mark, xField, yField, yAggregate, color} = opts;\n const encoding: any = {};\n if (xField) encoding.x = {field: xField};\n if (yField) encoding.y = {field: yField, aggregate: yAggregate ?? 'sum'};\n else if (yAggregate === 'count') encoding.y = {aggregate: 'count'};\n if (color) encoding.color = {value: color};\n return {mark, encoding, padding: 20};\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@sqlrooms/cells",
3
- "version": "0.29.0-rc.1",
4
- "private": false,
3
+ "version": "0.29.0-rc.3",
5
4
  "type": "module",
6
5
  "main": "dist/index.js",
7
6
  "module": "dist/index.js",
@@ -13,7 +12,7 @@
13
12
  "license": "MIT",
14
13
  "repository": {
15
14
  "type": "git",
16
- "url": "https://github.com/sqlrooms/sqlrooms.git"
15
+ "url": "git+https://github.com/sqlrooms/sqlrooms.git"
17
16
  },
18
17
  "sideEffects": false,
19
18
  "scripts": {
@@ -27,21 +26,21 @@
27
26
  },
28
27
  "dependencies": {
29
28
  "@paralleldrive/cuid2": "^2.2.2",
30
- "@sqlrooms/data-table": "0.29.0-rc.1",
31
- "@sqlrooms/db": "0.29.0-rc.1",
32
- "@sqlrooms/duckdb": "0.29.0-rc.1",
33
- "@sqlrooms/room-store": "0.29.0-rc.1",
34
- "@sqlrooms/sql-editor": "0.29.0-rc.1",
35
- "@sqlrooms/ui": "0.29.0-rc.1",
36
- "@sqlrooms/utils": "0.29.0-rc.1",
37
- "@sqlrooms/vega": "0.29.0-rc.1",
29
+ "@sqlrooms/data-table": "0.29.0-rc.3",
30
+ "@sqlrooms/db": "0.29.0-rc.3",
31
+ "@sqlrooms/duckdb": "0.29.0-rc.3",
32
+ "@sqlrooms/room-store": "0.29.0-rc.3",
33
+ "@sqlrooms/sql-editor": "0.29.0-rc.3",
34
+ "@sqlrooms/ui": "0.29.0-rc.3",
35
+ "@sqlrooms/utils": "0.29.0-rc.3",
36
+ "@sqlrooms/vega": "0.29.0-rc.3",
38
37
  "@tanstack/react-table": "^8.21.3",
39
38
  "apache-arrow": "17.0.0",
40
39
  "immer": "^11.0.1",
41
40
  "lucide-react": "^0.555.0",
42
- "monaco-editor": "^0.55.1",
43
41
  "react-hook-form": "^7.68.0",
44
42
  "react-markdown": "^10.1.0",
43
+ "remark-breaks": "^4.0.0",
45
44
  "remark-gfm": "^4.0.1",
46
45
  "zod": "^4.1.8"
47
46
  },
@@ -53,5 +52,5 @@
53
52
  "react": "^18 || ^19",
54
53
  "react-dom": "^18 || ^19"
55
54
  },
56
- "gitHead": "69f127fd34bd7f2ce3d75d6098dbf8c1f5ab50f3"
55
+ "gitHead": "4ffaf6c31d41c27f96bd3e4f5e83d431968721c3"
57
56
  }
@@ -1,9 +0,0 @@
1
- import React from 'react';
2
- export type DeleteSheetModalProps = {
3
- isOpen: boolean;
4
- onClose: () => void;
5
- onConfirm: () => void;
6
- sheetTitle?: string;
7
- };
8
- export declare const DeleteSheetModal: React.FC<DeleteSheetModalProps>;
9
- //# sourceMappingURL=DeleteSheetModal.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DeleteSheetModal.d.ts","sourceRoot":"","sources":["../../src/components/DeleteSheetModal.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA2B5D,CAAC"}
@@ -1,6 +0,0 @@
1
- import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, Button, } from '@sqlrooms/ui';
3
- export const DeleteSheetModal = ({ isOpen, onClose, onConfirm, sheetTitle, }) => {
4
- return (_jsx(Dialog, { open: isOpen, onOpenChange: (open) => !open && onClose(), children: _jsxs(DialogContent, { children: [_jsxs(DialogHeader, { children: [_jsxs(DialogTitle, { children: ["Delete ", sheetTitle || 'Sheet'] }), _jsx(DialogDescription, { children: "Are you sure you want to delete this sheet? This action cannot be undone." })] }), _jsxs(DialogFooter, { children: [_jsx(Button, { variant: "outline", onClick: onClose, children: "Cancel" }), _jsx(Button, { variant: "destructive", onClick: onConfirm, children: "Delete" })] })] }) }));
5
- };
6
- //# sourceMappingURL=DeleteSheetModal.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"DeleteSheetModal.js","sourceRoot":"","sources":["../../src/components/DeleteSheetModal.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,MAAM,GACP,MAAM,cAAc,CAAC;AAUtB,MAAM,CAAC,MAAM,gBAAgB,GAAoC,CAAC,EAChE,MAAM,EACN,OAAO,EACP,SAAS,EACT,UAAU,GACX,EAAE,EAAE;IACH,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE,YAC9D,MAAC,aAAa,eACZ,MAAC,YAAY,eACX,MAAC,WAAW,0BAAS,UAAU,IAAI,OAAO,IAAe,EACzD,KAAC,iBAAiB,4FAGE,IACP,EACf,MAAC,YAAY,eACX,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,OAAO,EAAE,OAAO,uBAEjC,EACT,KAAC,MAAM,IAAC,OAAO,EAAC,aAAa,EAAC,OAAO,EAAE,SAAS,uBAEvC,IACI,IACD,GACT,CACV,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n Button,\n} from '@sqlrooms/ui';\nimport React from 'react';\n\nexport type DeleteSheetModalProps = {\n isOpen: boolean;\n onClose: () => void;\n onConfirm: () => void;\n sheetTitle?: string;\n};\n\nexport const DeleteSheetModal: React.FC<DeleteSheetModalProps> = ({\n isOpen,\n onClose,\n onConfirm,\n sheetTitle,\n}) => {\n return (\n <Dialog open={isOpen} onOpenChange={(open) => !open && onClose()}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Delete {sheetTitle || 'Sheet'}</DialogTitle>\n <DialogDescription>\n Are you sure you want to delete this sheet? This action cannot be\n undone.\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>\n Cancel\n </Button>\n <Button variant=\"destructive\" onClick={onConfirm}>\n Delete\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n};\n"]}
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- export type SheetsTabBarProps = {
3
- className?: string;
4
- };
5
- export declare const SheetsTabBar: React.FC<SheetsTabBarProps>;
6
- //# sourceMappingURL=SheetsTabBar.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SheetsTabBar.d.ts","sourceRoot":"","sources":["../../src/components/SheetsTabBar.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAK5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAQF,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAmIpD,CAAC"}
@@ -1,57 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Button, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, TabStrip, } from '@sqlrooms/ui';
3
- import { AppWindow, FileText, LayoutDashboard, PencilIcon, PlusIcon, TrashIcon, } from 'lucide-react';
4
- import React, { useCallback, useMemo, useState } from 'react';
5
- import { useCellsStore } from '../hooks';
6
- import { DeleteSheetModal } from './DeleteSheetModal';
7
- const TYPE_ICONS = {
8
- notebook: FileText,
9
- canvas: LayoutDashboard,
10
- app: AppWindow,
11
- };
12
- export const SheetsTabBar = ({ className }) => {
13
- const sheetOrder = useCellsStore((s) => s.cells.config.sheetOrder);
14
- const sheets = useCellsStore((s) => s.cells.config.sheets);
15
- const currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);
16
- const supportedTypes = useCellsStore((s) => s.cells.supportedSheetTypes);
17
- const addSheet = useCellsStore((s) => s.cells.addSheet);
18
- const removeSheet = useCellsStore((s) => s.cells.removeSheet);
19
- const closeSheet = useCellsStore((s) => s.cells.closeSheet);
20
- const openSheet = useCellsStore((s) => s.cells.openSheet);
21
- const setSheetOrder = useCellsStore((s) => s.cells.setSheetOrder);
22
- const renameSheet = useCellsStore((s) => s.cells.renameSheet);
23
- const setCurrentSheet = useCellsStore((s) => s.cells.setCurrentSheet);
24
- const [sheetToDelete, setSheetToDelete] = useState(null);
25
- const handleDeleteRequest = useCallback((sheetId) => {
26
- const sheet = sheets[sheetId];
27
- if (sheet && sheet.cellIds.length === 0) {
28
- removeSheet(sheetId);
29
- }
30
- else {
31
- setSheetToDelete(sheetId);
32
- }
33
- }, [sheets, removeSheet]);
34
- const handleConfirmDelete = useCallback(() => {
35
- if (sheetToDelete) {
36
- removeSheet(sheetToDelete);
37
- setSheetToDelete(null);
38
- }
39
- }, [sheetToDelete, removeSheet]);
40
- const tabs = useMemo(() => Object.values(sheets).map((sheet) => ({
41
- id: sheet.id,
42
- name: sheet.title || 'Untitled',
43
- type: sheet.type || 'notebook',
44
- })), [sheets]);
45
- return (_jsxs(TabStrip, { className: className, tabs: tabs, openTabs: sheetOrder, selectedTabId: currentSheetId, onSelect: setCurrentSheet, onRename: renameSheet, onClose: closeSheet, onOpenTabsChange: setSheetOrder, renderTabTitle: (tab) => {
46
- const Icon = TYPE_ICONS[tab.type] || FileText;
47
- return (_jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [_jsx(Icon, { className: "text-muted-foreground h-3.5 w-3.5 shrink-0" }), _jsx("div", { className: "truncate text-sm", children: tab.name })] }));
48
- }, renderTabMenu: (tab) => (_jsxs(_Fragment, { children: [_jsxs(TabStrip.MenuItem, { onClick: () => renameSheet(tab.id, tab.name), children: [_jsx(PencilIcon, { className: "mr-2 h-4 w-4" }), "Rename"] }), _jsx(TabStrip.MenuSeparator, {}), _jsxs(TabStrip.MenuItem, { variant: "destructive", onClick: () => handleDeleteRequest(tab.id), children: [_jsx(TrashIcon, { className: "mr-2 h-4 w-4" }), "Delete"] })] })), renderSearchItemActions: (tab) => (_jsxs(_Fragment, { children: [_jsx(TabStrip.SearchItemAction, { icon: _jsx(PencilIcon, { className: "h-3 w-3" }), "aria-label": `Rename ${tab.name}`, onClick: () => renameSheet(tab.id, tab.name) }), _jsx(TabStrip.SearchItemAction, { icon: _jsx(TrashIcon, { className: "h-3 w-3" }), "aria-label": `Delete ${tab.name}`, onClick: () => handleDeleteRequest(tab.id) })] })), children: [_jsx(TabStrip.SearchDropdown, {}), _jsx(TabStrip.Tabs, { tabClassName: "pl-2" }), supportedTypes.length === 1 ? (_jsx(AddNewSheetButton, { onClick: () => addSheet(undefined, supportedTypes[0]) })) : (_jsxs(DropdownMenu, { children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx(AddNewSheetButton, {}) }), _jsx(DropdownMenuContent, { align: "start", children: supportedTypes.map((type) => {
49
- const Icon = TYPE_ICONS[type];
50
- return (_jsxs(DropdownMenuItem, { onClick: () => addSheet(undefined, type), className: "capitalize", children: [_jsx(Icon, { className: "mr-2 h-4 w-4" }), "New ", type] }, type));
51
- }) })] })), _jsx(DeleteSheetModal, { isOpen: sheetToDelete !== null, onClose: () => setSheetToDelete(null), onConfirm: handleConfirmDelete, sheetTitle: sheetToDelete ? sheets[sheetToDelete]?.title : undefined })] }));
52
- };
53
- const AddNewSheetButton = React.forwardRef(({ className, ...props }, ref) => {
54
- return (_jsx(Button, { ref: ref, size: "icon", variant: "ghost", className: `hover:bg-primary/10 h-full w-8 rounded-none ${className ?? ''}`, ...props, children: _jsx(PlusIcon, { className: "h-4 w-4" }) }));
55
- });
56
- AddNewSheetButton.displayName = 'AddNewSheetButton';
57
- //# sourceMappingURL=SheetsTabBar.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"SheetsTabBar.js","sourceRoot":"","sources":["../../src/components/SheetsTabBar.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n TabStrip,\n TabDescriptor,\n} from '@sqlrooms/ui';\nimport {\n AppWindow,\n FileText,\n LayoutDashboard,\n PencilIcon,\n PlusIcon,\n TrashIcon,\n} from 'lucide-react';\nimport React, {useCallback, useMemo, useState} from 'react';\nimport {useCellsStore} from '../hooks';\nimport {SheetType} from '../types';\nimport {DeleteSheetModal} from './DeleteSheetModal';\n\nexport type SheetsTabBarProps = {\n className?: string;\n};\n\nconst TYPE_ICONS: Record<SheetType, React.ElementType> = {\n notebook: FileText,\n canvas: LayoutDashboard,\n app: AppWindow,\n};\n\nexport const SheetsTabBar: React.FC<SheetsTabBarProps> = ({className}) => {\n const sheetOrder = useCellsStore((s) => s.cells.config.sheetOrder);\n const sheets = useCellsStore((s) => s.cells.config.sheets);\n const currentSheetId = useCellsStore((s) => s.cells.config.currentSheetId);\n const supportedTypes = useCellsStore((s) => s.cells.supportedSheetTypes);\n const addSheet = useCellsStore((s) => s.cells.addSheet);\n const removeSheet = useCellsStore((s) => s.cells.removeSheet);\n const closeSheet = useCellsStore((s) => s.cells.closeSheet);\n const openSheet = useCellsStore((s) => s.cells.openSheet);\n const setSheetOrder = useCellsStore((s) => s.cells.setSheetOrder);\n const renameSheet = useCellsStore((s) => s.cells.renameSheet);\n const setCurrentSheet = useCellsStore((s) => s.cells.setCurrentSheet);\n\n const [sheetToDelete, setSheetToDelete] = useState<string | null>(null);\n\n const handleDeleteRequest = useCallback(\n (sheetId: string) => {\n const sheet = sheets[sheetId];\n if (sheet && sheet.cellIds.length === 0) {\n removeSheet(sheetId);\n } else {\n setSheetToDelete(sheetId);\n }\n },\n [sheets, removeSheet],\n );\n\n const handleConfirmDelete = useCallback(() => {\n if (sheetToDelete) {\n removeSheet(sheetToDelete);\n setSheetToDelete(null);\n }\n }, [sheetToDelete, removeSheet]);\n\n const tabs = useMemo(\n () =>\n Object.values(sheets).map((sheet) => ({\n id: sheet.id,\n name: sheet.title || 'Untitled',\n type: sheet.type || 'notebook',\n })),\n [sheets],\n );\n\n return (\n <TabStrip\n className={className}\n tabs={tabs}\n openTabs={sheetOrder}\n selectedTabId={currentSheetId}\n onSelect={setCurrentSheet}\n onRename={renameSheet}\n onClose={closeSheet}\n onOpenTabsChange={setSheetOrder}\n renderTabTitle={(tab: TabDescriptor) => {\n const Icon = TYPE_ICONS[tab.type as SheetType] || FileText;\n return (\n <div className=\"flex min-w-0 items-center gap-2\">\n <Icon className=\"text-muted-foreground h-3.5 w-3.5 shrink-0\" />\n <div className=\"truncate text-sm\">{tab.name}</div>\n </div>\n );\n }}\n renderTabMenu={(tab) => (\n <>\n <TabStrip.MenuItem onClick={() => renameSheet(tab.id, tab.name)}>\n <PencilIcon className=\"mr-2 h-4 w-4\" />\n Rename\n </TabStrip.MenuItem>\n <TabStrip.MenuSeparator />\n <TabStrip.MenuItem\n variant=\"destructive\"\n onClick={() => handleDeleteRequest(tab.id)}\n >\n <TrashIcon className=\"mr-2 h-4 w-4\" />\n Delete\n </TabStrip.MenuItem>\n </>\n )}\n renderSearchItemActions={(tab) => (\n <>\n <TabStrip.SearchItemAction\n icon={<PencilIcon className=\"h-3 w-3\" />}\n aria-label={`Rename ${tab.name}`}\n onClick={() => renameSheet(tab.id, tab.name)}\n />\n <TabStrip.SearchItemAction\n icon={<TrashIcon className=\"h-3 w-3\" />}\n aria-label={`Delete ${tab.name}`}\n onClick={() => handleDeleteRequest(tab.id)}\n />\n </>\n )}\n >\n <TabStrip.SearchDropdown />\n <TabStrip.Tabs tabClassName=\"pl-2\" />\n\n {supportedTypes.length === 1 ? (\n <AddNewSheetButton\n onClick={() => addSheet(undefined, supportedTypes[0])}\n />\n ) : (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <AddNewSheetButton />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"start\">\n {supportedTypes.map((type) => {\n const Icon = TYPE_ICONS[type];\n return (\n <DropdownMenuItem\n key={type}\n onClick={() => addSheet(undefined, type)}\n className=\"capitalize\"\n >\n <Icon className=\"mr-2 h-4 w-4\" />\n New {type}\n </DropdownMenuItem>\n );\n })}\n </DropdownMenuContent>\n </DropdownMenu>\n )}\n <DeleteSheetModal\n isOpen={sheetToDelete !== null}\n onClose={() => setSheetToDelete(null)}\n onConfirm={handleConfirmDelete}\n sheetTitle={sheetToDelete ? sheets[sheetToDelete]?.title : undefined}\n />\n </TabStrip>\n );\n};\n\nconst AddNewSheetButton = React.forwardRef<\n HTMLButtonElement,\n React.ComponentPropsWithoutRef<typeof Button>\n>(({className, ...props}, ref) => {\n return (\n <Button\n ref={ref}\n size=\"icon\"\n variant=\"ghost\"\n className={`hover:bg-primary/10 h-full w-8 rounded-none ${className ?? ''}`}\n {...props}\n >\n <PlusIcon className=\"h-4 w-4\" />\n </Button>\n );\n});\nAddNewSheetButton.displayName = 'AddNewSheetButton';\n"]}