@tightknitai/block-kitchen 0.10.19 → 0.10.20
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.
- package/dist/helpers.d.cts +2 -2
- package/dist/helpers.d.ts +2 -2
- package/dist/index.cjs +480 -150
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +481 -151
- package/dist/index.js.map +1 -1
- package/dist/{palette-DNUiqoQK.d.cts → palette-4BJw_nd7.d.cts} +54 -7
- package/dist/{palette-DNUiqoQK.d.ts → palette-4BJw_nd7.d.ts} +54 -7
- package/dist/palette.cjs +52 -0
- package/dist/palette.cjs.map +1 -1
- package/dist/palette.d.cts +1 -1
- package/dist/palette.d.ts +1 -1
- package/dist/palette.js +52 -0
- package/dist/palette.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useSensors, useSensor, PointerSensor, TouchSensor, KeyboardSensor, pointerWithin, closestCenter, DndContext, DragOverlay, useDroppable, useDraggable } from '@dnd-kit/core';
|
|
2
2
|
import { sortableKeyboardCoordinates, SortableContext, verticalListSortingStrategy, useSortable } from '@dnd-kit/sortable';
|
|
3
|
-
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, ChevronRight, ChevronLeft, GripVertical, ChevronsUpDown, Check, Sun, Moon, MessageSquare, AppWindow, Home, Plus, ChevronDown, BookOpen, Undo2, Redo2, Trash2, Code2, Pencil, Send, Search, Copy, Info, CheckCircle2, LayoutGrid, ArrowUp, ArrowDown, Type, Bold, Italic, Strikethrough, Underline, Code, AtSign, List, ListOrdered, Quote, Smile, Link as Link$1 } from 'lucide-react';
|
|
3
|
+
import { X, Circle, Sparkles, FileText, AlignLeft, MousePointerClick, TextCursorInput, LayoutTemplate, Bell, Pilcrow, Image, Video, GalleryHorizontal, Table, ChartColumnBig, Container, Loader2, ExternalLink, AlertTriangle, ChevronRight, ChevronLeft, GripVertical, ChevronsUpDown, Check, Sun, Moon, MessageSquare, AppWindow, Home, Plus, ChevronDown, BookOpen, Undo2, Redo2, Trash2, Code2, Pencil, Send, Search, Copy, Info, CheckCircle2, LayoutGrid, ArrowUp, ArrowDown, Type, Bold, Italic, Strikethrough, Underline, Code, AtSign, List, ListOrdered, Quote, Hash, Smile, Link as Link$1 } from 'lucide-react';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import { createContext, useContext, useState, useRef, useEffect, useCallback, useMemo, useId } from 'react';
|
|
6
6
|
import { clsx } from 'clsx';
|
|
@@ -1066,6 +1066,58 @@ var defaultPalette = [
|
|
|
1066
1066
|
]
|
|
1067
1067
|
]
|
|
1068
1068
|
})
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
// Slack's documented example.
|
|
1072
|
+
id: "data_table_basic",
|
|
1073
|
+
label: "Data table",
|
|
1074
|
+
factory: () => ({
|
|
1075
|
+
type: "data_table",
|
|
1076
|
+
caption: "A Fabulous Table",
|
|
1077
|
+
rows: [
|
|
1078
|
+
[
|
|
1079
|
+
{ type: "raw_text", text: "Name" },
|
|
1080
|
+
{ type: "raw_text", text: "Department" },
|
|
1081
|
+
{ type: "raw_text", text: "Badge" }
|
|
1082
|
+
],
|
|
1083
|
+
[
|
|
1084
|
+
{ type: "raw_text", text: "Data Refinement Department" },
|
|
1085
|
+
{ type: "raw_text", text: "MDR" },
|
|
1086
|
+
{
|
|
1087
|
+
type: "rich_text",
|
|
1088
|
+
elements: [
|
|
1089
|
+
{ type: "rich_text_section", elements: [{ type: "text", text: "Blue", style: { bold: true } }] }
|
|
1090
|
+
]
|
|
1091
|
+
}
|
|
1092
|
+
],
|
|
1093
|
+
[
|
|
1094
|
+
{ type: "raw_text", text: "Art Sourcing Department" },
|
|
1095
|
+
{ type: "raw_text", text: "O&D" },
|
|
1096
|
+
{
|
|
1097
|
+
type: "rich_text",
|
|
1098
|
+
elements: [
|
|
1099
|
+
{
|
|
1100
|
+
type: "rich_text_section",
|
|
1101
|
+
elements: [
|
|
1102
|
+
{ type: "text", text: "Green " },
|
|
1103
|
+
{ type: "text", text: "review", style: { italic: true } }
|
|
1104
|
+
]
|
|
1105
|
+
}
|
|
1106
|
+
]
|
|
1107
|
+
}
|
|
1108
|
+
],
|
|
1109
|
+
[
|
|
1110
|
+
{ type: "raw_text", text: "Wellness Department" },
|
|
1111
|
+
{ type: "raw_text", text: "Wellness Center" },
|
|
1112
|
+
{
|
|
1113
|
+
type: "rich_text",
|
|
1114
|
+
elements: [
|
|
1115
|
+
{ type: "rich_text_section", elements: [{ type: "text", text: "Limited", style: { bold: true } }] }
|
|
1116
|
+
]
|
|
1117
|
+
}
|
|
1118
|
+
]
|
|
1119
|
+
]
|
|
1120
|
+
})
|
|
1069
1121
|
}
|
|
1070
1122
|
]
|
|
1071
1123
|
},
|
|
@@ -1730,6 +1782,8 @@ function labelForBlockType(type) {
|
|
|
1730
1782
|
return "Data Visualization";
|
|
1731
1783
|
case "container":
|
|
1732
1784
|
return "Container";
|
|
1785
|
+
case "data_table":
|
|
1786
|
+
return "Data Table";
|
|
1733
1787
|
}
|
|
1734
1788
|
}
|
|
1735
1789
|
var Sheet = DialogPrimitive.Root;
|
|
@@ -7780,6 +7834,387 @@ function ImageItemCard({
|
|
|
7780
7834
|
) })
|
|
7781
7835
|
] });
|
|
7782
7836
|
}
|
|
7837
|
+
var REMOVE_BUTTON_CLASS = "flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:cursor-not-allowed disabled:opacity-40";
|
|
7838
|
+
function CellGrid({
|
|
7839
|
+
label,
|
|
7840
|
+
help,
|
|
7841
|
+
rows,
|
|
7842
|
+
minRows,
|
|
7843
|
+
maxRows,
|
|
7844
|
+
maxColumns,
|
|
7845
|
+
lockFirstRow = false,
|
|
7846
|
+
blankCell,
|
|
7847
|
+
renderCell,
|
|
7848
|
+
renderColumnControl,
|
|
7849
|
+
onChange
|
|
7850
|
+
}) {
|
|
7851
|
+
const columnCount = rows[0]?.length ?? 0;
|
|
7852
|
+
const setCell = (rowIdx, colIdx, next) => {
|
|
7853
|
+
onChange(rows.map((row, r) => r === rowIdx ? row.map((cell, c) => c === colIdx ? next : cell) : row));
|
|
7854
|
+
};
|
|
7855
|
+
const addRow = () => {
|
|
7856
|
+
onChange([...rows, Array.from({ length: columnCount || 1 }, blankCell)]);
|
|
7857
|
+
};
|
|
7858
|
+
const removeRow = (rowIdx) => {
|
|
7859
|
+
if (rows.length <= minRows) {
|
|
7860
|
+
return;
|
|
7861
|
+
}
|
|
7862
|
+
onChange(rows.filter((_, r) => r !== rowIdx));
|
|
7863
|
+
};
|
|
7864
|
+
const addColumn = () => {
|
|
7865
|
+
onChange(
|
|
7866
|
+
rows.map((row) => [...row, blankCell()]),
|
|
7867
|
+
{ kind: "add" }
|
|
7868
|
+
);
|
|
7869
|
+
};
|
|
7870
|
+
const removeColumn = (colIdx) => {
|
|
7871
|
+
if (columnCount <= 1) {
|
|
7872
|
+
return;
|
|
7873
|
+
}
|
|
7874
|
+
onChange(
|
|
7875
|
+
rows.map((row) => row.filter((_, c) => c !== colIdx)),
|
|
7876
|
+
{ kind: "remove", index: colIdx }
|
|
7877
|
+
);
|
|
7878
|
+
};
|
|
7879
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
7880
|
+
/* @__PURE__ */ jsx(EditorField, { label, help, children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 overflow-x-auto", children: [
|
|
7881
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7882
|
+
/* @__PURE__ */ jsx("span", { className: "w-6 shrink-0", "aria-hidden": "true" }),
|
|
7883
|
+
Array.from({ length: columnCount }, (_, c) => /* @__PURE__ */ jsxs("div", { className: "flex min-w-[120px] flex-1 items-center gap-1", children: [
|
|
7884
|
+
renderColumnControl ? renderColumnControl(c) : /* @__PURE__ */ jsxs("span", { className: "flex-1 truncate px-1.5 text-[11px] text-muted-foreground", children: [
|
|
7885
|
+
"Column ",
|
|
7886
|
+
c + 1
|
|
7887
|
+
] }),
|
|
7888
|
+
/* @__PURE__ */ jsx(
|
|
7889
|
+
"button",
|
|
7890
|
+
{
|
|
7891
|
+
type: "button",
|
|
7892
|
+
"aria-label": `Remove column ${c + 1}`,
|
|
7893
|
+
onClick: () => removeColumn(c),
|
|
7894
|
+
disabled: columnCount <= 1,
|
|
7895
|
+
className: REMOVE_BUTTON_CLASS,
|
|
7896
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3 w-3" })
|
|
7897
|
+
}
|
|
7898
|
+
)
|
|
7899
|
+
] }, c))
|
|
7900
|
+
] }),
|
|
7901
|
+
rows.map((row, r) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7902
|
+
lockFirstRow && r === 0 ? /* @__PURE__ */ jsx("span", { className: "w-6 shrink-0", "aria-hidden": "true" }) : /* @__PURE__ */ jsx(
|
|
7903
|
+
"button",
|
|
7904
|
+
{
|
|
7905
|
+
type: "button",
|
|
7906
|
+
"aria-label": `Remove row ${r + 1}`,
|
|
7907
|
+
onClick: () => removeRow(r),
|
|
7908
|
+
disabled: rows.length <= minRows,
|
|
7909
|
+
className: REMOVE_BUTTON_CLASS,
|
|
7910
|
+
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3 w-3" })
|
|
7911
|
+
}
|
|
7912
|
+
),
|
|
7913
|
+
row.map((cell, c) => /* @__PURE__ */ jsx("div", { className: "flex min-w-[120px] flex-1 flex-col gap-0.5", children: renderCell(
|
|
7914
|
+
cell,
|
|
7915
|
+
{ row: r, col: c, label: `Row ${r + 1}, column ${c + 1}` },
|
|
7916
|
+
(next) => setCell(r, c, next)
|
|
7917
|
+
) }, c))
|
|
7918
|
+
] }, r))
|
|
7919
|
+
] }) }),
|
|
7920
|
+
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
7921
|
+
/* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", onClick: addRow, disabled: rows.length >= maxRows, children: [
|
|
7922
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" }),
|
|
7923
|
+
" Add row"
|
|
7924
|
+
] }),
|
|
7925
|
+
/* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", onClick: addColumn, disabled: columnCount >= maxColumns, children: [
|
|
7926
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" }),
|
|
7927
|
+
" Add column"
|
|
7928
|
+
] })
|
|
7929
|
+
] })
|
|
7930
|
+
] });
|
|
7931
|
+
}
|
|
7932
|
+
function CellTextInput({
|
|
7933
|
+
cell,
|
|
7934
|
+
label,
|
|
7935
|
+
placeholder,
|
|
7936
|
+
leading,
|
|
7937
|
+
richTextNote = "Was rich-text; editing replaces with plain text.",
|
|
7938
|
+
onChange
|
|
7939
|
+
}) {
|
|
7940
|
+
const input = /* @__PURE__ */ jsx(
|
|
7941
|
+
Input,
|
|
7942
|
+
{
|
|
7943
|
+
"aria-label": label,
|
|
7944
|
+
value: cell.type === "raw_text" ? cell.text : "[rich_text]",
|
|
7945
|
+
placeholder,
|
|
7946
|
+
onChange: (e) => onChange({ type: "raw_text", text: e.target.value }),
|
|
7947
|
+
className: "h-8 text-xs"
|
|
7948
|
+
}
|
|
7949
|
+
);
|
|
7950
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
7951
|
+
leading ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7952
|
+
leading,
|
|
7953
|
+
input
|
|
7954
|
+
] }) : input,
|
|
7955
|
+
cell.type === "rich_text" ? /* @__PURE__ */ jsx("span", { className: cn("text-[10px] text-muted-foreground", leading && "pl-7"), children: richTextNote }) : null
|
|
7956
|
+
] });
|
|
7957
|
+
}
|
|
7958
|
+
function NumberInput({
|
|
7959
|
+
id,
|
|
7960
|
+
value,
|
|
7961
|
+
onCommit,
|
|
7962
|
+
ariaLabel,
|
|
7963
|
+
className
|
|
7964
|
+
}) {
|
|
7965
|
+
const [draft, setDraft] = useState(String(value));
|
|
7966
|
+
useEffect(() => {
|
|
7967
|
+
setDraft(String(value));
|
|
7968
|
+
}, [value]);
|
|
7969
|
+
return /* @__PURE__ */ jsx(
|
|
7970
|
+
Input,
|
|
7971
|
+
{
|
|
7972
|
+
id,
|
|
7973
|
+
type: "number",
|
|
7974
|
+
inputMode: "numeric",
|
|
7975
|
+
"aria-label": ariaLabel,
|
|
7976
|
+
value: draft,
|
|
7977
|
+
className,
|
|
7978
|
+
onChange: (e) => {
|
|
7979
|
+
const raw = e.target.value;
|
|
7980
|
+
setDraft(raw);
|
|
7981
|
+
if (raw === "" || raw === "-" || raw === "." || raw === "-.") {
|
|
7982
|
+
return;
|
|
7983
|
+
}
|
|
7984
|
+
const next = Number(raw);
|
|
7985
|
+
if (!Number.isNaN(next)) {
|
|
7986
|
+
onCommit(next);
|
|
7987
|
+
}
|
|
7988
|
+
},
|
|
7989
|
+
onBlur: () => {
|
|
7990
|
+
const next = Number(draft);
|
|
7991
|
+
const safe = draft.trim() === "" || Number.isNaN(next) ? 0 : next;
|
|
7992
|
+
onCommit(safe);
|
|
7993
|
+
setDraft(String(safe));
|
|
7994
|
+
}
|
|
7995
|
+
}
|
|
7996
|
+
);
|
|
7997
|
+
}
|
|
7998
|
+
var MAX_ROWS = 201;
|
|
7999
|
+
var MIN_ROWS = 2;
|
|
8000
|
+
var MAX_COLUMNS = 20;
|
|
8001
|
+
var MAX_PAGE_SIZE = 100;
|
|
8002
|
+
var SELECT_CLASS = "flex h-9 w-full rounded-md border border-input bg-background px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50";
|
|
8003
|
+
function withOptional(block, key, value) {
|
|
8004
|
+
const next = { ...block };
|
|
8005
|
+
if (value === void 0) {
|
|
8006
|
+
delete next[key];
|
|
8007
|
+
} else {
|
|
8008
|
+
next[key] = value;
|
|
8009
|
+
}
|
|
8010
|
+
return next;
|
|
8011
|
+
}
|
|
8012
|
+
function realignRowHeader(index, edit) {
|
|
8013
|
+
if (index === void 0 || edit.kind === "add" || edit.index > index) {
|
|
8014
|
+
return index;
|
|
8015
|
+
}
|
|
8016
|
+
return edit.index === index ? void 0 : index - 1;
|
|
8017
|
+
}
|
|
8018
|
+
function cellText(cell) {
|
|
8019
|
+
switch (cell?.type) {
|
|
8020
|
+
case "raw_text":
|
|
8021
|
+
return cell.text;
|
|
8022
|
+
case "raw_number":
|
|
8023
|
+
return cell.text ?? String(cell.value);
|
|
8024
|
+
case "action_cell":
|
|
8025
|
+
return cell.element.text.text;
|
|
8026
|
+
default:
|
|
8027
|
+
return "";
|
|
8028
|
+
}
|
|
8029
|
+
}
|
|
8030
|
+
function toNumberCell(cell) {
|
|
8031
|
+
const text = cell.text.trim();
|
|
8032
|
+
const parsed = text === "" ? Number.NaN : Number(text.replace(/,/g, ""));
|
|
8033
|
+
if (Number.isFinite(parsed)) {
|
|
8034
|
+
return String(parsed) === text ? { type: "raw_number", value: parsed } : { type: "raw_number", value: parsed, text };
|
|
8035
|
+
}
|
|
8036
|
+
return text ? { type: "raw_number", value: 0, text } : { type: "raw_number", value: 0 };
|
|
8037
|
+
}
|
|
8038
|
+
function toTextCell(cell) {
|
|
8039
|
+
return { type: "raw_text", text: cell.text ?? String(cell.value) };
|
|
8040
|
+
}
|
|
8041
|
+
function DataTableEditor({ block, onChange }) {
|
|
8042
|
+
const rows = block.rows ?? [];
|
|
8043
|
+
const header = rows[0] ?? [];
|
|
8044
|
+
const rowHeader = block.row_header_column_index ?? 0;
|
|
8045
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
8046
|
+
/* @__PURE__ */ jsx(EditorField, { label: "Caption", help: "Required. Names the table for screen readers.", htmlFor: "data-table-caption", children: /* @__PURE__ */ jsx(
|
|
8047
|
+
Input,
|
|
8048
|
+
{
|
|
8049
|
+
id: "data-table-caption",
|
|
8050
|
+
value: block.caption,
|
|
8051
|
+
placeholder: "e.g. Open deals by stage",
|
|
8052
|
+
onChange: (e) => onChange({ ...block, caption: e.target.value })
|
|
8053
|
+
}
|
|
8054
|
+
) }),
|
|
8055
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
8056
|
+
/* @__PURE__ */ jsx(
|
|
8057
|
+
EditorField,
|
|
8058
|
+
{
|
|
8059
|
+
label: "Rows per page",
|
|
8060
|
+
help: "Optional, 1-100. Slack shows 5 when empty.",
|
|
8061
|
+
htmlFor: "data-table-page-size",
|
|
8062
|
+
children: /* @__PURE__ */ jsx(
|
|
8063
|
+
Input,
|
|
8064
|
+
{
|
|
8065
|
+
id: "data-table-page-size",
|
|
8066
|
+
type: "number",
|
|
8067
|
+
min: 1,
|
|
8068
|
+
max: MAX_PAGE_SIZE,
|
|
8069
|
+
value: block.page_size ?? "",
|
|
8070
|
+
placeholder: "5",
|
|
8071
|
+
onChange: (e) => {
|
|
8072
|
+
const n = Math.trunc(Number(e.target.value));
|
|
8073
|
+
const next = e.target.value === "" || Number.isNaN(n) ? void 0 : Math.min(MAX_PAGE_SIZE, Math.max(1, n));
|
|
8074
|
+
onChange(withOptional(block, "page_size", next));
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
8077
|
+
)
|
|
8078
|
+
}
|
|
8079
|
+
),
|
|
8080
|
+
/* @__PURE__ */ jsx(
|
|
8081
|
+
EditorField,
|
|
8082
|
+
{
|
|
8083
|
+
label: "Row header column",
|
|
8084
|
+
help: "The column that identifies each row for screen readers.",
|
|
8085
|
+
htmlFor: "data-table-row-header",
|
|
8086
|
+
children: /* @__PURE__ */ jsxs(
|
|
8087
|
+
"select",
|
|
8088
|
+
{
|
|
8089
|
+
id: "data-table-row-header",
|
|
8090
|
+
value: rowHeader,
|
|
8091
|
+
disabled: header.length === 0,
|
|
8092
|
+
onChange: (e) => {
|
|
8093
|
+
const index = Number(e.target.value);
|
|
8094
|
+
onChange(withOptional(block, "row_header_column_index", index === 0 ? void 0 : index));
|
|
8095
|
+
},
|
|
8096
|
+
className: SELECT_CLASS,
|
|
8097
|
+
children: [
|
|
8098
|
+
header.map((cell, c) => {
|
|
8099
|
+
const text = cellText(cell);
|
|
8100
|
+
return /* @__PURE__ */ jsx("option", { value: c, children: text ? `Column ${c + 1}: ${text}` : `Column ${c + 1}` }, c);
|
|
8101
|
+
}),
|
|
8102
|
+
rowHeader >= header.length ? /* @__PURE__ */ jsxs("option", { value: rowHeader, children: [
|
|
8103
|
+
"Column ",
|
|
8104
|
+
rowHeader + 1,
|
|
8105
|
+
" (missing)"
|
|
8106
|
+
] }) : null
|
|
8107
|
+
]
|
|
8108
|
+
}
|
|
8109
|
+
)
|
|
8110
|
+
}
|
|
8111
|
+
)
|
|
8112
|
+
] }),
|
|
8113
|
+
/* @__PURE__ */ jsx(
|
|
8114
|
+
CellGrid,
|
|
8115
|
+
{
|
|
8116
|
+
label: "Cells",
|
|
8117
|
+
help: "The first row is the header. Up to 200 more rows and 20 columns. Use # to make a cell a number; a column of only numbers sorts numerically.",
|
|
8118
|
+
rows,
|
|
8119
|
+
minRows: MIN_ROWS,
|
|
8120
|
+
maxRows: MAX_ROWS,
|
|
8121
|
+
maxColumns: MAX_COLUMNS,
|
|
8122
|
+
lockFirstRow: true,
|
|
8123
|
+
blankCell: () => ({ type: "raw_text", text: "" }),
|
|
8124
|
+
onChange: (nextRows, edit) => {
|
|
8125
|
+
const next = { ...block, rows: nextRows };
|
|
8126
|
+
onChange(
|
|
8127
|
+
edit ? withOptional(next, "row_header_column_index", realignRowHeader(block.row_header_column_index, edit)) : next
|
|
8128
|
+
);
|
|
8129
|
+
},
|
|
8130
|
+
renderCell: (cell, position, update) => /* @__PURE__ */ jsx(DataTableCellField, { cell, position, onChange: update })
|
|
8131
|
+
}
|
|
8132
|
+
)
|
|
8133
|
+
] });
|
|
8134
|
+
}
|
|
8135
|
+
function DataTableCellField({
|
|
8136
|
+
cell,
|
|
8137
|
+
position,
|
|
8138
|
+
onChange
|
|
8139
|
+
}) {
|
|
8140
|
+
const { row, col, label } = position;
|
|
8141
|
+
if (cell.type === "action_cell") {
|
|
8142
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8143
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8144
|
+
/* @__PURE__ */ jsx(ToggleSpacer, {}),
|
|
8145
|
+
/* @__PURE__ */ jsxs("div", { className: "flex h-8 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-dashed px-2 text-xs text-muted-foreground", children: [
|
|
8146
|
+
/* @__PURE__ */ jsx(MousePointerClick, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" }),
|
|
8147
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: cellText(cell) || "Button" })
|
|
8148
|
+
] })
|
|
8149
|
+
] }),
|
|
8150
|
+
/* @__PURE__ */ jsx("span", { className: "pl-7 text-[10px] text-muted-foreground", children: "Button cell. Edit it via View JSON." })
|
|
8151
|
+
] });
|
|
8152
|
+
}
|
|
8153
|
+
if (cell.type === "raw_number") {
|
|
8154
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
8155
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8156
|
+
/* @__PURE__ */ jsx(NumberToggle, { label, pressed: true, onClick: () => onChange(toTextCell(cell)) }),
|
|
8157
|
+
/* @__PURE__ */ jsx(
|
|
8158
|
+
NumberInput,
|
|
8159
|
+
{
|
|
8160
|
+
value: cell.value,
|
|
8161
|
+
ariaLabel: `${label} value`,
|
|
8162
|
+
onCommit: (value) => onChange({ ...cell, value }),
|
|
8163
|
+
className: "h-8 text-xs"
|
|
8164
|
+
}
|
|
8165
|
+
)
|
|
8166
|
+
] }),
|
|
8167
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8168
|
+
/* @__PURE__ */ jsx(ToggleSpacer, {}),
|
|
8169
|
+
/* @__PURE__ */ jsx(
|
|
8170
|
+
Input,
|
|
8171
|
+
{
|
|
8172
|
+
"aria-label": `${label} display text`,
|
|
8173
|
+
value: cell.text ?? "",
|
|
8174
|
+
placeholder: "Display as (optional)",
|
|
8175
|
+
onChange: (e) => {
|
|
8176
|
+
const { text: _omit, ...rest } = cell;
|
|
8177
|
+
onChange(e.target.value ? { ...rest, text: e.target.value } : rest);
|
|
8178
|
+
},
|
|
8179
|
+
className: "h-7 text-[11px]"
|
|
8180
|
+
}
|
|
8181
|
+
)
|
|
8182
|
+
] })
|
|
8183
|
+
] });
|
|
8184
|
+
}
|
|
8185
|
+
const isHeader = row === 0;
|
|
8186
|
+
return /* @__PURE__ */ jsx(
|
|
8187
|
+
CellTextInput,
|
|
8188
|
+
{
|
|
8189
|
+
cell,
|
|
8190
|
+
label,
|
|
8191
|
+
placeholder: isHeader ? `Header ${col + 1}` : "Cell text",
|
|
8192
|
+
richTextNote: isHeader ? "Header cells can't be rich text. Type to replace it." : void 0,
|
|
8193
|
+
leading: !isHeader && cell.type === "raw_text" ? /* @__PURE__ */ jsx(NumberToggle, { label, pressed: false, onClick: () => onChange(toNumberCell(cell)) }) : /* @__PURE__ */ jsx(ToggleSpacer, {}),
|
|
8194
|
+
onChange
|
|
8195
|
+
}
|
|
8196
|
+
);
|
|
8197
|
+
}
|
|
8198
|
+
function ToggleSpacer() {
|
|
8199
|
+
return /* @__PURE__ */ jsx("span", { className: "h-6 w-6 shrink-0", "aria-hidden": "true" });
|
|
8200
|
+
}
|
|
8201
|
+
function NumberToggle({ label, pressed, onClick }) {
|
|
8202
|
+
return /* @__PURE__ */ jsx(
|
|
8203
|
+
"button",
|
|
8204
|
+
{
|
|
8205
|
+
type: "button",
|
|
8206
|
+
"aria-label": `${label} as number`,
|
|
8207
|
+
"aria-pressed": pressed,
|
|
8208
|
+
title: pressed ? "Number cell. Click to make it text." : "Text cell. Click to make it a number.",
|
|
8209
|
+
onClick,
|
|
8210
|
+
className: cn(
|
|
8211
|
+
"flex h-6 w-6 shrink-0 items-center justify-center rounded transition-colors",
|
|
8212
|
+
pressed ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
8213
|
+
),
|
|
8214
|
+
children: /* @__PURE__ */ jsx(Hash, { className: "h-3 w-3" })
|
|
8215
|
+
}
|
|
8216
|
+
);
|
|
8217
|
+
}
|
|
7783
8218
|
var CHART_TYPES = ["line", "bar", "area", "pie"];
|
|
7784
8219
|
function isCartesian(chart) {
|
|
7785
8220
|
return chart.type !== "pie";
|
|
@@ -7834,46 +8269,6 @@ function DataVisualizationEditor({ block, onChange }) {
|
|
|
7834
8269
|
isCartesian(chart) ? /* @__PURE__ */ jsx(CartesianFields, { chart, onChange: setChart }) : /* @__PURE__ */ jsx(PieFields, { chart, onChange: setChart })
|
|
7835
8270
|
] });
|
|
7836
8271
|
}
|
|
7837
|
-
function NumberInput({
|
|
7838
|
-
id,
|
|
7839
|
-
value,
|
|
7840
|
-
onCommit,
|
|
7841
|
-
ariaLabel,
|
|
7842
|
-
className
|
|
7843
|
-
}) {
|
|
7844
|
-
const [draft, setDraft] = useState(String(value));
|
|
7845
|
-
useEffect(() => {
|
|
7846
|
-
setDraft(String(value));
|
|
7847
|
-
}, [value]);
|
|
7848
|
-
return /* @__PURE__ */ jsx(
|
|
7849
|
-
Input,
|
|
7850
|
-
{
|
|
7851
|
-
id,
|
|
7852
|
-
type: "number",
|
|
7853
|
-
inputMode: "numeric",
|
|
7854
|
-
"aria-label": ariaLabel,
|
|
7855
|
-
value: draft,
|
|
7856
|
-
className,
|
|
7857
|
-
onChange: (e) => {
|
|
7858
|
-
const raw = e.target.value;
|
|
7859
|
-
setDraft(raw);
|
|
7860
|
-
if (raw === "" || raw === "-" || raw === "." || raw === "-.") {
|
|
7861
|
-
return;
|
|
7862
|
-
}
|
|
7863
|
-
const next = Number(raw);
|
|
7864
|
-
if (!Number.isNaN(next)) {
|
|
7865
|
-
onCommit(next);
|
|
7866
|
-
}
|
|
7867
|
-
},
|
|
7868
|
-
onBlur: () => {
|
|
7869
|
-
const next = Number(draft);
|
|
7870
|
-
const safe = draft.trim() === "" || Number.isNaN(next) ? 0 : next;
|
|
7871
|
-
onCommit(safe);
|
|
7872
|
-
setDraft(String(safe));
|
|
7873
|
-
}
|
|
7874
|
-
}
|
|
7875
|
-
);
|
|
7876
|
-
}
|
|
7877
8272
|
function CartesianFields({ chart, onChange }) {
|
|
7878
8273
|
const series = chart.series;
|
|
7879
8274
|
const categories = chart.axis_config?.categories && chart.axis_config.categories.length > 0 ? chart.axis_config.categories : series[0]?.data.map((d) => d.label) ?? [];
|
|
@@ -9416,45 +9811,13 @@ function ImageAccessoryFields({ image, onChange }) {
|
|
|
9416
9811
|
] });
|
|
9417
9812
|
}
|
|
9418
9813
|
var ALIGN_OPTIONS = ["left", "center", "right"];
|
|
9419
|
-
function
|
|
9420
|
-
|
|
9421
|
-
return cell.text;
|
|
9422
|
-
}
|
|
9423
|
-
return "[rich_text]";
|
|
9814
|
+
function alignColumnSettings(settings, edit) {
|
|
9815
|
+
return edit.kind === "add" ? [...settings, null] : settings.filter((_, c) => c !== edit.index);
|
|
9424
9816
|
}
|
|
9425
9817
|
function TableEditor({ block, onChange }) {
|
|
9426
9818
|
const rows = block.rows ?? [];
|
|
9427
9819
|
const columnCount = rows[0]?.length ?? 0;
|
|
9428
9820
|
const columnSettings = block.column_settings ?? [];
|
|
9429
|
-
const setCell = (rowIdx, colIdx, text) => {
|
|
9430
|
-
const nextRows = rows.map(
|
|
9431
|
-
(row, r) => r === rowIdx ? row.map((cell, c) => c === colIdx ? { type: "raw_text", text } : cell) : row
|
|
9432
|
-
);
|
|
9433
|
-
onChange({ ...block, rows: nextRows });
|
|
9434
|
-
};
|
|
9435
|
-
const addRow = () => {
|
|
9436
|
-
const blankRow = Array.from({ length: columnCount || 1 }, () => ({ type: "raw_text", text: "" }));
|
|
9437
|
-
onChange({ ...block, rows: [...rows, blankRow] });
|
|
9438
|
-
};
|
|
9439
|
-
const removeRow = (rowIdx) => {
|
|
9440
|
-
if (rows.length <= 1) {
|
|
9441
|
-
return;
|
|
9442
|
-
}
|
|
9443
|
-
onChange({ ...block, rows: rows.filter((_, r) => r !== rowIdx) });
|
|
9444
|
-
};
|
|
9445
|
-
const addColumn = () => {
|
|
9446
|
-
const nextRows = rows.map((row) => [...row, { type: "raw_text", text: "" }]);
|
|
9447
|
-
const nextSettings = [...columnSettings, null];
|
|
9448
|
-
onChange({ ...block, rows: nextRows, column_settings: nextSettings });
|
|
9449
|
-
};
|
|
9450
|
-
const removeColumn = (colIdx) => {
|
|
9451
|
-
if (columnCount <= 1) {
|
|
9452
|
-
return;
|
|
9453
|
-
}
|
|
9454
|
-
const nextRows = rows.map((row) => row.filter((_, c) => c !== colIdx));
|
|
9455
|
-
const nextSettings = columnSettings.filter((_, c) => c !== colIdx);
|
|
9456
|
-
onChange({ ...block, rows: nextRows, column_settings: nextSettings });
|
|
9457
|
-
};
|
|
9458
9821
|
const setColumnAlign = (colIdx, align) => {
|
|
9459
9822
|
const next = Array.from({ length: columnCount }, (_, i) => columnSettings[i] ?? null);
|
|
9460
9823
|
if (align === "") {
|
|
@@ -9465,81 +9828,45 @@ function TableEditor({ block, onChange }) {
|
|
|
9465
9828
|
}
|
|
9466
9829
|
onChange({ ...block, column_settings: next });
|
|
9467
9830
|
};
|
|
9468
|
-
return /* @__PURE__ */
|
|
9469
|
-
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9486
|
-
|
|
9487
|
-
|
|
9488
|
-
|
|
9489
|
-
|
|
9490
|
-
|
|
9491
|
-
|
|
9492
|
-
|
|
9493
|
-
|
|
9494
|
-
|
|
9495
|
-
|
|
9496
|
-
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
type: "button",
|
|
9508
|
-
"aria-label": `Remove row ${r + 1}`,
|
|
9509
|
-
onClick: () => removeRow(r),
|
|
9510
|
-
disabled: rows.length <= 1,
|
|
9511
|
-
className: "flex h-6 w-6 shrink-0 items-center justify-center rounded text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:cursor-not-allowed disabled:opacity-40",
|
|
9512
|
-
children: /* @__PURE__ */ jsx(Trash2, { className: "h-3 w-3" })
|
|
9513
|
-
}
|
|
9514
|
-
),
|
|
9515
|
-
row.map((cell, c) => {
|
|
9516
|
-
const isRichText = cell.type === "rich_text";
|
|
9517
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex min-w-[120px] flex-1 flex-col gap-0.5", children: [
|
|
9518
|
-
/* @__PURE__ */ jsx(
|
|
9519
|
-
Input,
|
|
9520
|
-
{
|
|
9521
|
-
value: cellAsText(cell),
|
|
9522
|
-
placeholder: r === 0 ? `Header ${c + 1}` : "Cell text",
|
|
9523
|
-
onChange: (e) => setCell(r, c, e.target.value),
|
|
9524
|
-
className: "h-8 text-xs"
|
|
9525
|
-
}
|
|
9526
|
-
),
|
|
9527
|
-
isRichText ? /* @__PURE__ */ jsx("span", { className: "text-[10px] text-muted-foreground", children: "Was rich-text; editing replaces with plain text." }) : null
|
|
9528
|
-
] }, c);
|
|
9529
|
-
})
|
|
9530
|
-
] }, r))
|
|
9531
|
-
] }) }),
|
|
9532
|
-
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
9533
|
-
/* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", onClick: addRow, disabled: rows.length >= 100, children: [
|
|
9534
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" }),
|
|
9535
|
-
" Add row"
|
|
9536
|
-
] }),
|
|
9537
|
-
/* @__PURE__ */ jsxs(Button, { type: "button", size: "sm", onClick: addColumn, disabled: columnCount >= 20, children: [
|
|
9538
|
-
/* @__PURE__ */ jsx(Plus, { className: "h-3.5 w-3.5" }),
|
|
9539
|
-
" Add column"
|
|
9540
|
-
] })
|
|
9541
|
-
] })
|
|
9542
|
-
] });
|
|
9831
|
+
return /* @__PURE__ */ jsx(
|
|
9832
|
+
CellGrid,
|
|
9833
|
+
{
|
|
9834
|
+
label: "Cells",
|
|
9835
|
+
help: "Up to 100 rows and 20 columns. Slack allows one table per message.",
|
|
9836
|
+
rows,
|
|
9837
|
+
minRows: 1,
|
|
9838
|
+
maxRows: 100,
|
|
9839
|
+
maxColumns: 20,
|
|
9840
|
+
blankCell: () => ({ type: "raw_text", text: "" }),
|
|
9841
|
+
onChange: (nextRows, edit) => onChange({
|
|
9842
|
+
...block,
|
|
9843
|
+
rows: nextRows,
|
|
9844
|
+
...edit ? { column_settings: alignColumnSettings(columnSettings, edit) } : {}
|
|
9845
|
+
}),
|
|
9846
|
+
renderColumnControl: (c) => /* @__PURE__ */ jsxs(
|
|
9847
|
+
"select",
|
|
9848
|
+
{
|
|
9849
|
+
"aria-label": `Column ${c + 1} alignment`,
|
|
9850
|
+
value: columnSettings[c]?.align ?? "",
|
|
9851
|
+
onChange: (e) => setColumnAlign(c, e.target.value),
|
|
9852
|
+
className: "h-7 flex-1 rounded-sm border border-input bg-background px-1.5 text-[11px] text-muted-foreground",
|
|
9853
|
+
children: [
|
|
9854
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "Default" }),
|
|
9855
|
+
ALIGN_OPTIONS.map((a) => /* @__PURE__ */ jsx("option", { value: a, children: a }, a))
|
|
9856
|
+
]
|
|
9857
|
+
}
|
|
9858
|
+
),
|
|
9859
|
+
renderCell: (cell, { row, col, label }, update) => /* @__PURE__ */ jsx(
|
|
9860
|
+
CellTextInput,
|
|
9861
|
+
{
|
|
9862
|
+
cell,
|
|
9863
|
+
label,
|
|
9864
|
+
placeholder: row === 0 ? `Header ${col + 1}` : "Cell text",
|
|
9865
|
+
onChange: update
|
|
9866
|
+
}
|
|
9867
|
+
)
|
|
9868
|
+
}
|
|
9869
|
+
);
|
|
9543
9870
|
}
|
|
9544
9871
|
var STATUSES2 = ["pending", "in_progress", "complete", "error"];
|
|
9545
9872
|
function TaskCardEditor({ block, onChange }) {
|
|
@@ -9880,6 +10207,8 @@ function dispatch(block, onChange) {
|
|
|
9880
10207
|
return /* @__PURE__ */ jsx(DataVisualizationEditor, { block, onChange: (next) => onChange(next) });
|
|
9881
10208
|
case "container":
|
|
9882
10209
|
return /* @__PURE__ */ jsx(ContainerEditor, { block, onChange: (next) => onChange(next) });
|
|
10210
|
+
case "data_table":
|
|
10211
|
+
return /* @__PURE__ */ jsx(DataTableEditor, { block, onChange: (next) => onChange(next) });
|
|
9883
10212
|
default:
|
|
9884
10213
|
return null;
|
|
9885
10214
|
}
|
|
@@ -9903,7 +10232,8 @@ var BLOCK_TYPE_LABELS = {
|
|
|
9903
10232
|
plan: "Plan",
|
|
9904
10233
|
task_card: "Task Card",
|
|
9905
10234
|
data_visualization: "Data Visualization",
|
|
9906
|
-
container: "Container"
|
|
10235
|
+
container: "Container",
|
|
10236
|
+
data_table: "Data Table"
|
|
9907
10237
|
};
|
|
9908
10238
|
function BlockRow({
|
|
9909
10239
|
builderBlock,
|