@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.cjs
CHANGED
|
@@ -1096,6 +1096,58 @@ var defaultPalette = [
|
|
|
1096
1096
|
]
|
|
1097
1097
|
]
|
|
1098
1098
|
})
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
// Slack's documented example.
|
|
1102
|
+
id: "data_table_basic",
|
|
1103
|
+
label: "Data table",
|
|
1104
|
+
factory: () => ({
|
|
1105
|
+
type: "data_table",
|
|
1106
|
+
caption: "A Fabulous Table",
|
|
1107
|
+
rows: [
|
|
1108
|
+
[
|
|
1109
|
+
{ type: "raw_text", text: "Name" },
|
|
1110
|
+
{ type: "raw_text", text: "Department" },
|
|
1111
|
+
{ type: "raw_text", text: "Badge" }
|
|
1112
|
+
],
|
|
1113
|
+
[
|
|
1114
|
+
{ type: "raw_text", text: "Data Refinement Department" },
|
|
1115
|
+
{ type: "raw_text", text: "MDR" },
|
|
1116
|
+
{
|
|
1117
|
+
type: "rich_text",
|
|
1118
|
+
elements: [
|
|
1119
|
+
{ type: "rich_text_section", elements: [{ type: "text", text: "Blue", style: { bold: true } }] }
|
|
1120
|
+
]
|
|
1121
|
+
}
|
|
1122
|
+
],
|
|
1123
|
+
[
|
|
1124
|
+
{ type: "raw_text", text: "Art Sourcing Department" },
|
|
1125
|
+
{ type: "raw_text", text: "O&D" },
|
|
1126
|
+
{
|
|
1127
|
+
type: "rich_text",
|
|
1128
|
+
elements: [
|
|
1129
|
+
{
|
|
1130
|
+
type: "rich_text_section",
|
|
1131
|
+
elements: [
|
|
1132
|
+
{ type: "text", text: "Green " },
|
|
1133
|
+
{ type: "text", text: "review", style: { italic: true } }
|
|
1134
|
+
]
|
|
1135
|
+
}
|
|
1136
|
+
]
|
|
1137
|
+
}
|
|
1138
|
+
],
|
|
1139
|
+
[
|
|
1140
|
+
{ type: "raw_text", text: "Wellness Department" },
|
|
1141
|
+
{ type: "raw_text", text: "Wellness Center" },
|
|
1142
|
+
{
|
|
1143
|
+
type: "rich_text",
|
|
1144
|
+
elements: [
|
|
1145
|
+
{ type: "rich_text_section", elements: [{ type: "text", text: "Limited", style: { bold: true } }] }
|
|
1146
|
+
]
|
|
1147
|
+
}
|
|
1148
|
+
]
|
|
1149
|
+
]
|
|
1150
|
+
})
|
|
1099
1151
|
}
|
|
1100
1152
|
]
|
|
1101
1153
|
},
|
|
@@ -1760,6 +1812,8 @@ function labelForBlockType(type) {
|
|
|
1760
1812
|
return "Data Visualization";
|
|
1761
1813
|
case "container":
|
|
1762
1814
|
return "Container";
|
|
1815
|
+
case "data_table":
|
|
1816
|
+
return "Data Table";
|
|
1763
1817
|
}
|
|
1764
1818
|
}
|
|
1765
1819
|
var Sheet = DialogPrimitive__namespace.Root;
|
|
@@ -7810,6 +7864,387 @@ function ImageItemCard({
|
|
|
7810
7864
|
) })
|
|
7811
7865
|
] });
|
|
7812
7866
|
}
|
|
7867
|
+
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";
|
|
7868
|
+
function CellGrid({
|
|
7869
|
+
label,
|
|
7870
|
+
help,
|
|
7871
|
+
rows,
|
|
7872
|
+
minRows,
|
|
7873
|
+
maxRows,
|
|
7874
|
+
maxColumns,
|
|
7875
|
+
lockFirstRow = false,
|
|
7876
|
+
blankCell,
|
|
7877
|
+
renderCell,
|
|
7878
|
+
renderColumnControl,
|
|
7879
|
+
onChange
|
|
7880
|
+
}) {
|
|
7881
|
+
const columnCount = rows[0]?.length ?? 0;
|
|
7882
|
+
const setCell = (rowIdx, colIdx, next) => {
|
|
7883
|
+
onChange(rows.map((row, r) => r === rowIdx ? row.map((cell, c) => c === colIdx ? next : cell) : row));
|
|
7884
|
+
};
|
|
7885
|
+
const addRow = () => {
|
|
7886
|
+
onChange([...rows, Array.from({ length: columnCount || 1 }, blankCell)]);
|
|
7887
|
+
};
|
|
7888
|
+
const removeRow = (rowIdx) => {
|
|
7889
|
+
if (rows.length <= minRows) {
|
|
7890
|
+
return;
|
|
7891
|
+
}
|
|
7892
|
+
onChange(rows.filter((_, r) => r !== rowIdx));
|
|
7893
|
+
};
|
|
7894
|
+
const addColumn = () => {
|
|
7895
|
+
onChange(
|
|
7896
|
+
rows.map((row) => [...row, blankCell()]),
|
|
7897
|
+
{ kind: "add" }
|
|
7898
|
+
);
|
|
7899
|
+
};
|
|
7900
|
+
const removeColumn = (colIdx) => {
|
|
7901
|
+
if (columnCount <= 1) {
|
|
7902
|
+
return;
|
|
7903
|
+
}
|
|
7904
|
+
onChange(
|
|
7905
|
+
rows.map((row) => row.filter((_, c) => c !== colIdx)),
|
|
7906
|
+
{ kind: "remove", index: colIdx }
|
|
7907
|
+
);
|
|
7908
|
+
};
|
|
7909
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
7910
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label, help, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2 overflow-x-auto", children: [
|
|
7911
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7912
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-6 shrink-0", "aria-hidden": "true" }),
|
|
7913
|
+
Array.from({ length: columnCount }, (_, c) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-[120px] flex-1 items-center gap-1", children: [
|
|
7914
|
+
renderColumnControl ? renderColumnControl(c) : /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex-1 truncate px-1.5 text-[11px] text-muted-foreground", children: [
|
|
7915
|
+
"Column ",
|
|
7916
|
+
c + 1
|
|
7917
|
+
] }),
|
|
7918
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7919
|
+
"button",
|
|
7920
|
+
{
|
|
7921
|
+
type: "button",
|
|
7922
|
+
"aria-label": `Remove column ${c + 1}`,
|
|
7923
|
+
onClick: () => removeColumn(c),
|
|
7924
|
+
disabled: columnCount <= 1,
|
|
7925
|
+
className: REMOVE_BUTTON_CLASS,
|
|
7926
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
|
|
7927
|
+
}
|
|
7928
|
+
)
|
|
7929
|
+
] }, c))
|
|
7930
|
+
] }),
|
|
7931
|
+
rows.map((row, r) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7932
|
+
lockFirstRow && r === 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "w-6 shrink-0", "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
7933
|
+
"button",
|
|
7934
|
+
{
|
|
7935
|
+
type: "button",
|
|
7936
|
+
"aria-label": `Remove row ${r + 1}`,
|
|
7937
|
+
onClick: () => removeRow(r),
|
|
7938
|
+
disabled: rows.length <= minRows,
|
|
7939
|
+
className: REMOVE_BUTTON_CLASS,
|
|
7940
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
|
|
7941
|
+
}
|
|
7942
|
+
),
|
|
7943
|
+
row.map((cell, c) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex min-w-[120px] flex-1 flex-col gap-0.5", children: renderCell(
|
|
7944
|
+
cell,
|
|
7945
|
+
{ row: r, col: c, label: `Row ${r + 1}, column ${c + 1}` },
|
|
7946
|
+
(next) => setCell(r, c, next)
|
|
7947
|
+
) }, c))
|
|
7948
|
+
] }, r))
|
|
7949
|
+
] }) }),
|
|
7950
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
7951
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addRow, disabled: rows.length >= maxRows, children: [
|
|
7952
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
7953
|
+
" Add row"
|
|
7954
|
+
] }),
|
|
7955
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addColumn, disabled: columnCount >= maxColumns, children: [
|
|
7956
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
7957
|
+
" Add column"
|
|
7958
|
+
] })
|
|
7959
|
+
] })
|
|
7960
|
+
] });
|
|
7961
|
+
}
|
|
7962
|
+
function CellTextInput({
|
|
7963
|
+
cell,
|
|
7964
|
+
label,
|
|
7965
|
+
placeholder,
|
|
7966
|
+
leading,
|
|
7967
|
+
richTextNote = "Was rich-text; editing replaces with plain text.",
|
|
7968
|
+
onChange
|
|
7969
|
+
}) {
|
|
7970
|
+
const input = /* @__PURE__ */ jsxRuntime.jsx(
|
|
7971
|
+
Input,
|
|
7972
|
+
{
|
|
7973
|
+
"aria-label": label,
|
|
7974
|
+
value: cell.type === "raw_text" ? cell.text : "[rich_text]",
|
|
7975
|
+
placeholder,
|
|
7976
|
+
onChange: (e) => onChange({ type: "raw_text", text: e.target.value }),
|
|
7977
|
+
className: "h-8 text-xs"
|
|
7978
|
+
}
|
|
7979
|
+
);
|
|
7980
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
7981
|
+
leading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
7982
|
+
leading,
|
|
7983
|
+
input
|
|
7984
|
+
] }) : input,
|
|
7985
|
+
cell.type === "rich_text" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("text-[10px] text-muted-foreground", leading && "pl-7"), children: richTextNote }) : null
|
|
7986
|
+
] });
|
|
7987
|
+
}
|
|
7988
|
+
function NumberInput({
|
|
7989
|
+
id,
|
|
7990
|
+
value,
|
|
7991
|
+
onCommit,
|
|
7992
|
+
ariaLabel,
|
|
7993
|
+
className
|
|
7994
|
+
}) {
|
|
7995
|
+
const [draft, setDraft] = React.useState(String(value));
|
|
7996
|
+
React.useEffect(() => {
|
|
7997
|
+
setDraft(String(value));
|
|
7998
|
+
}, [value]);
|
|
7999
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8000
|
+
Input,
|
|
8001
|
+
{
|
|
8002
|
+
id,
|
|
8003
|
+
type: "number",
|
|
8004
|
+
inputMode: "numeric",
|
|
8005
|
+
"aria-label": ariaLabel,
|
|
8006
|
+
value: draft,
|
|
8007
|
+
className,
|
|
8008
|
+
onChange: (e) => {
|
|
8009
|
+
const raw = e.target.value;
|
|
8010
|
+
setDraft(raw);
|
|
8011
|
+
if (raw === "" || raw === "-" || raw === "." || raw === "-.") {
|
|
8012
|
+
return;
|
|
8013
|
+
}
|
|
8014
|
+
const next = Number(raw);
|
|
8015
|
+
if (!Number.isNaN(next)) {
|
|
8016
|
+
onCommit(next);
|
|
8017
|
+
}
|
|
8018
|
+
},
|
|
8019
|
+
onBlur: () => {
|
|
8020
|
+
const next = Number(draft);
|
|
8021
|
+
const safe = draft.trim() === "" || Number.isNaN(next) ? 0 : next;
|
|
8022
|
+
onCommit(safe);
|
|
8023
|
+
setDraft(String(safe));
|
|
8024
|
+
}
|
|
8025
|
+
}
|
|
8026
|
+
);
|
|
8027
|
+
}
|
|
8028
|
+
var MAX_ROWS = 201;
|
|
8029
|
+
var MIN_ROWS = 2;
|
|
8030
|
+
var MAX_COLUMNS = 20;
|
|
8031
|
+
var MAX_PAGE_SIZE = 100;
|
|
8032
|
+
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";
|
|
8033
|
+
function withOptional(block, key, value) {
|
|
8034
|
+
const next = { ...block };
|
|
8035
|
+
if (value === void 0) {
|
|
8036
|
+
delete next[key];
|
|
8037
|
+
} else {
|
|
8038
|
+
next[key] = value;
|
|
8039
|
+
}
|
|
8040
|
+
return next;
|
|
8041
|
+
}
|
|
8042
|
+
function realignRowHeader(index, edit) {
|
|
8043
|
+
if (index === void 0 || edit.kind === "add" || edit.index > index) {
|
|
8044
|
+
return index;
|
|
8045
|
+
}
|
|
8046
|
+
return edit.index === index ? void 0 : index - 1;
|
|
8047
|
+
}
|
|
8048
|
+
function cellText(cell) {
|
|
8049
|
+
switch (cell?.type) {
|
|
8050
|
+
case "raw_text":
|
|
8051
|
+
return cell.text;
|
|
8052
|
+
case "raw_number":
|
|
8053
|
+
return cell.text ?? String(cell.value);
|
|
8054
|
+
case "action_cell":
|
|
8055
|
+
return cell.element.text.text;
|
|
8056
|
+
default:
|
|
8057
|
+
return "";
|
|
8058
|
+
}
|
|
8059
|
+
}
|
|
8060
|
+
function toNumberCell(cell) {
|
|
8061
|
+
const text = cell.text.trim();
|
|
8062
|
+
const parsed = text === "" ? Number.NaN : Number(text.replace(/,/g, ""));
|
|
8063
|
+
if (Number.isFinite(parsed)) {
|
|
8064
|
+
return String(parsed) === text ? { type: "raw_number", value: parsed } : { type: "raw_number", value: parsed, text };
|
|
8065
|
+
}
|
|
8066
|
+
return text ? { type: "raw_number", value: 0, text } : { type: "raw_number", value: 0 };
|
|
8067
|
+
}
|
|
8068
|
+
function toTextCell(cell) {
|
|
8069
|
+
return { type: "raw_text", text: cell.text ?? String(cell.value) };
|
|
8070
|
+
}
|
|
8071
|
+
function DataTableEditor({ block, onChange }) {
|
|
8072
|
+
const rows = block.rows ?? [];
|
|
8073
|
+
const header = rows[0] ?? [];
|
|
8074
|
+
const rowHeader = block.row_header_column_index ?? 0;
|
|
8075
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
|
|
8076
|
+
/* @__PURE__ */ jsxRuntime.jsx(EditorField, { label: "Caption", help: "Required. Names the table for screen readers.", htmlFor: "data-table-caption", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8077
|
+
Input,
|
|
8078
|
+
{
|
|
8079
|
+
id: "data-table-caption",
|
|
8080
|
+
value: block.caption,
|
|
8081
|
+
placeholder: "e.g. Open deals by stage",
|
|
8082
|
+
onChange: (e) => onChange({ ...block, caption: e.target.value })
|
|
8083
|
+
}
|
|
8084
|
+
) }),
|
|
8085
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
8086
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8087
|
+
EditorField,
|
|
8088
|
+
{
|
|
8089
|
+
label: "Rows per page",
|
|
8090
|
+
help: "Optional, 1-100. Slack shows 5 when empty.",
|
|
8091
|
+
htmlFor: "data-table-page-size",
|
|
8092
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8093
|
+
Input,
|
|
8094
|
+
{
|
|
8095
|
+
id: "data-table-page-size",
|
|
8096
|
+
type: "number",
|
|
8097
|
+
min: 1,
|
|
8098
|
+
max: MAX_PAGE_SIZE,
|
|
8099
|
+
value: block.page_size ?? "",
|
|
8100
|
+
placeholder: "5",
|
|
8101
|
+
onChange: (e) => {
|
|
8102
|
+
const n = Math.trunc(Number(e.target.value));
|
|
8103
|
+
const next = e.target.value === "" || Number.isNaN(n) ? void 0 : Math.min(MAX_PAGE_SIZE, Math.max(1, n));
|
|
8104
|
+
onChange(withOptional(block, "page_size", next));
|
|
8105
|
+
}
|
|
8106
|
+
}
|
|
8107
|
+
)
|
|
8108
|
+
}
|
|
8109
|
+
),
|
|
8110
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8111
|
+
EditorField,
|
|
8112
|
+
{
|
|
8113
|
+
label: "Row header column",
|
|
8114
|
+
help: "The column that identifies each row for screen readers.",
|
|
8115
|
+
htmlFor: "data-table-row-header",
|
|
8116
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8117
|
+
"select",
|
|
8118
|
+
{
|
|
8119
|
+
id: "data-table-row-header",
|
|
8120
|
+
value: rowHeader,
|
|
8121
|
+
disabled: header.length === 0,
|
|
8122
|
+
onChange: (e) => {
|
|
8123
|
+
const index = Number(e.target.value);
|
|
8124
|
+
onChange(withOptional(block, "row_header_column_index", index === 0 ? void 0 : index));
|
|
8125
|
+
},
|
|
8126
|
+
className: SELECT_CLASS,
|
|
8127
|
+
children: [
|
|
8128
|
+
header.map((cell, c) => {
|
|
8129
|
+
const text = cellText(cell);
|
|
8130
|
+
return /* @__PURE__ */ jsxRuntime.jsx("option", { value: c, children: text ? `Column ${c + 1}: ${text}` : `Column ${c + 1}` }, c);
|
|
8131
|
+
}),
|
|
8132
|
+
rowHeader >= header.length ? /* @__PURE__ */ jsxRuntime.jsxs("option", { value: rowHeader, children: [
|
|
8133
|
+
"Column ",
|
|
8134
|
+
rowHeader + 1,
|
|
8135
|
+
" (missing)"
|
|
8136
|
+
] }) : null
|
|
8137
|
+
]
|
|
8138
|
+
}
|
|
8139
|
+
)
|
|
8140
|
+
}
|
|
8141
|
+
)
|
|
8142
|
+
] }),
|
|
8143
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8144
|
+
CellGrid,
|
|
8145
|
+
{
|
|
8146
|
+
label: "Cells",
|
|
8147
|
+
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.",
|
|
8148
|
+
rows,
|
|
8149
|
+
minRows: MIN_ROWS,
|
|
8150
|
+
maxRows: MAX_ROWS,
|
|
8151
|
+
maxColumns: MAX_COLUMNS,
|
|
8152
|
+
lockFirstRow: true,
|
|
8153
|
+
blankCell: () => ({ type: "raw_text", text: "" }),
|
|
8154
|
+
onChange: (nextRows, edit) => {
|
|
8155
|
+
const next = { ...block, rows: nextRows };
|
|
8156
|
+
onChange(
|
|
8157
|
+
edit ? withOptional(next, "row_header_column_index", realignRowHeader(block.row_header_column_index, edit)) : next
|
|
8158
|
+
);
|
|
8159
|
+
},
|
|
8160
|
+
renderCell: (cell, position, update) => /* @__PURE__ */ jsxRuntime.jsx(DataTableCellField, { cell, position, onChange: update })
|
|
8161
|
+
}
|
|
8162
|
+
)
|
|
8163
|
+
] });
|
|
8164
|
+
}
|
|
8165
|
+
function DataTableCellField({
|
|
8166
|
+
cell,
|
|
8167
|
+
position,
|
|
8168
|
+
onChange
|
|
8169
|
+
}) {
|
|
8170
|
+
const { row, col, label } = position;
|
|
8171
|
+
if (cell.type === "action_cell") {
|
|
8172
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8173
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8174
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleSpacer, {}),
|
|
8175
|
+
/* @__PURE__ */ jsxRuntime.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: [
|
|
8176
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.MousePointerClick, { className: "h-3 w-3 shrink-0", "aria-hidden": "true" }),
|
|
8177
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate", children: cellText(cell) || "Button" })
|
|
8178
|
+
] })
|
|
8179
|
+
] }),
|
|
8180
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "pl-7 text-[10px] text-muted-foreground", children: "Button cell. Edit it via View JSON." })
|
|
8181
|
+
] });
|
|
8182
|
+
}
|
|
8183
|
+
if (cell.type === "raw_number") {
|
|
8184
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8185
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8186
|
+
/* @__PURE__ */ jsxRuntime.jsx(NumberToggle, { label, pressed: true, onClick: () => onChange(toTextCell(cell)) }),
|
|
8187
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8188
|
+
NumberInput,
|
|
8189
|
+
{
|
|
8190
|
+
value: cell.value,
|
|
8191
|
+
ariaLabel: `${label} value`,
|
|
8192
|
+
onCommit: (value) => onChange({ ...cell, value }),
|
|
8193
|
+
className: "h-8 text-xs"
|
|
8194
|
+
}
|
|
8195
|
+
)
|
|
8196
|
+
] }),
|
|
8197
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1", children: [
|
|
8198
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToggleSpacer, {}),
|
|
8199
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8200
|
+
Input,
|
|
8201
|
+
{
|
|
8202
|
+
"aria-label": `${label} display text`,
|
|
8203
|
+
value: cell.text ?? "",
|
|
8204
|
+
placeholder: "Display as (optional)",
|
|
8205
|
+
onChange: (e) => {
|
|
8206
|
+
const { text: _omit, ...rest } = cell;
|
|
8207
|
+
onChange(e.target.value ? { ...rest, text: e.target.value } : rest);
|
|
8208
|
+
},
|
|
8209
|
+
className: "h-7 text-[11px]"
|
|
8210
|
+
}
|
|
8211
|
+
)
|
|
8212
|
+
] })
|
|
8213
|
+
] });
|
|
8214
|
+
}
|
|
8215
|
+
const isHeader = row === 0;
|
|
8216
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8217
|
+
CellTextInput,
|
|
8218
|
+
{
|
|
8219
|
+
cell,
|
|
8220
|
+
label,
|
|
8221
|
+
placeholder: isHeader ? `Header ${col + 1}` : "Cell text",
|
|
8222
|
+
richTextNote: isHeader ? "Header cells can't be rich text. Type to replace it." : void 0,
|
|
8223
|
+
leading: !isHeader && cell.type === "raw_text" ? /* @__PURE__ */ jsxRuntime.jsx(NumberToggle, { label, pressed: false, onClick: () => onChange(toNumberCell(cell)) }) : /* @__PURE__ */ jsxRuntime.jsx(ToggleSpacer, {}),
|
|
8224
|
+
onChange
|
|
8225
|
+
}
|
|
8226
|
+
);
|
|
8227
|
+
}
|
|
8228
|
+
function ToggleSpacer() {
|
|
8229
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-6 w-6 shrink-0", "aria-hidden": "true" });
|
|
8230
|
+
}
|
|
8231
|
+
function NumberToggle({ label, pressed, onClick }) {
|
|
8232
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8233
|
+
"button",
|
|
8234
|
+
{
|
|
8235
|
+
type: "button",
|
|
8236
|
+
"aria-label": `${label} as number`,
|
|
8237
|
+
"aria-pressed": pressed,
|
|
8238
|
+
title: pressed ? "Number cell. Click to make it text." : "Text cell. Click to make it a number.",
|
|
8239
|
+
onClick,
|
|
8240
|
+
className: cn(
|
|
8241
|
+
"flex h-6 w-6 shrink-0 items-center justify-center rounded transition-colors",
|
|
8242
|
+
pressed ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-accent hover:text-foreground"
|
|
8243
|
+
),
|
|
8244
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Hash, { className: "h-3 w-3" })
|
|
8245
|
+
}
|
|
8246
|
+
);
|
|
8247
|
+
}
|
|
7813
8248
|
var CHART_TYPES = ["line", "bar", "area", "pie"];
|
|
7814
8249
|
function isCartesian(chart) {
|
|
7815
8250
|
return chart.type !== "pie";
|
|
@@ -7864,46 +8299,6 @@ function DataVisualizationEditor({ block, onChange }) {
|
|
|
7864
8299
|
isCartesian(chart) ? /* @__PURE__ */ jsxRuntime.jsx(CartesianFields, { chart, onChange: setChart }) : /* @__PURE__ */ jsxRuntime.jsx(PieFields, { chart, onChange: setChart })
|
|
7865
8300
|
] });
|
|
7866
8301
|
}
|
|
7867
|
-
function NumberInput({
|
|
7868
|
-
id,
|
|
7869
|
-
value,
|
|
7870
|
-
onCommit,
|
|
7871
|
-
ariaLabel,
|
|
7872
|
-
className
|
|
7873
|
-
}) {
|
|
7874
|
-
const [draft, setDraft] = React.useState(String(value));
|
|
7875
|
-
React.useEffect(() => {
|
|
7876
|
-
setDraft(String(value));
|
|
7877
|
-
}, [value]);
|
|
7878
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7879
|
-
Input,
|
|
7880
|
-
{
|
|
7881
|
-
id,
|
|
7882
|
-
type: "number",
|
|
7883
|
-
inputMode: "numeric",
|
|
7884
|
-
"aria-label": ariaLabel,
|
|
7885
|
-
value: draft,
|
|
7886
|
-
className,
|
|
7887
|
-
onChange: (e) => {
|
|
7888
|
-
const raw = e.target.value;
|
|
7889
|
-
setDraft(raw);
|
|
7890
|
-
if (raw === "" || raw === "-" || raw === "." || raw === "-.") {
|
|
7891
|
-
return;
|
|
7892
|
-
}
|
|
7893
|
-
const next = Number(raw);
|
|
7894
|
-
if (!Number.isNaN(next)) {
|
|
7895
|
-
onCommit(next);
|
|
7896
|
-
}
|
|
7897
|
-
},
|
|
7898
|
-
onBlur: () => {
|
|
7899
|
-
const next = Number(draft);
|
|
7900
|
-
const safe = draft.trim() === "" || Number.isNaN(next) ? 0 : next;
|
|
7901
|
-
onCommit(safe);
|
|
7902
|
-
setDraft(String(safe));
|
|
7903
|
-
}
|
|
7904
|
-
}
|
|
7905
|
-
);
|
|
7906
|
-
}
|
|
7907
8302
|
function CartesianFields({ chart, onChange }) {
|
|
7908
8303
|
const series = chart.series;
|
|
7909
8304
|
const categories = chart.axis_config?.categories && chart.axis_config.categories.length > 0 ? chart.axis_config.categories : series[0]?.data.map((d) => d.label) ?? [];
|
|
@@ -9446,45 +9841,13 @@ function ImageAccessoryFields({ image, onChange }) {
|
|
|
9446
9841
|
] });
|
|
9447
9842
|
}
|
|
9448
9843
|
var ALIGN_OPTIONS = ["left", "center", "right"];
|
|
9449
|
-
function
|
|
9450
|
-
|
|
9451
|
-
return cell.text;
|
|
9452
|
-
}
|
|
9453
|
-
return "[rich_text]";
|
|
9844
|
+
function alignColumnSettings(settings, edit) {
|
|
9845
|
+
return edit.kind === "add" ? [...settings, null] : settings.filter((_, c) => c !== edit.index);
|
|
9454
9846
|
}
|
|
9455
9847
|
function TableEditor({ block, onChange }) {
|
|
9456
9848
|
const rows = block.rows ?? [];
|
|
9457
9849
|
const columnCount = rows[0]?.length ?? 0;
|
|
9458
9850
|
const columnSettings = block.column_settings ?? [];
|
|
9459
|
-
const setCell = (rowIdx, colIdx, text) => {
|
|
9460
|
-
const nextRows = rows.map(
|
|
9461
|
-
(row, r) => r === rowIdx ? row.map((cell, c) => c === colIdx ? { type: "raw_text", text } : cell) : row
|
|
9462
|
-
);
|
|
9463
|
-
onChange({ ...block, rows: nextRows });
|
|
9464
|
-
};
|
|
9465
|
-
const addRow = () => {
|
|
9466
|
-
const blankRow = Array.from({ length: columnCount || 1 }, () => ({ type: "raw_text", text: "" }));
|
|
9467
|
-
onChange({ ...block, rows: [...rows, blankRow] });
|
|
9468
|
-
};
|
|
9469
|
-
const removeRow = (rowIdx) => {
|
|
9470
|
-
if (rows.length <= 1) {
|
|
9471
|
-
return;
|
|
9472
|
-
}
|
|
9473
|
-
onChange({ ...block, rows: rows.filter((_, r) => r !== rowIdx) });
|
|
9474
|
-
};
|
|
9475
|
-
const addColumn = () => {
|
|
9476
|
-
const nextRows = rows.map((row) => [...row, { type: "raw_text", text: "" }]);
|
|
9477
|
-
const nextSettings = [...columnSettings, null];
|
|
9478
|
-
onChange({ ...block, rows: nextRows, column_settings: nextSettings });
|
|
9479
|
-
};
|
|
9480
|
-
const removeColumn = (colIdx) => {
|
|
9481
|
-
if (columnCount <= 1) {
|
|
9482
|
-
return;
|
|
9483
|
-
}
|
|
9484
|
-
const nextRows = rows.map((row) => row.filter((_, c) => c !== colIdx));
|
|
9485
|
-
const nextSettings = columnSettings.filter((_, c) => c !== colIdx);
|
|
9486
|
-
onChange({ ...block, rows: nextRows, column_settings: nextSettings });
|
|
9487
|
-
};
|
|
9488
9851
|
const setColumnAlign = (colIdx, align) => {
|
|
9489
9852
|
const next = Array.from({ length: columnCount }, (_, i) => columnSettings[i] ?? null);
|
|
9490
9853
|
if (align === "") {
|
|
@@ -9495,81 +9858,45 @@ function TableEditor({ block, onChange }) {
|
|
|
9495
9858
|
}
|
|
9496
9859
|
onChange({ ...block, column_settings: next });
|
|
9497
9860
|
};
|
|
9498
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
type: "button",
|
|
9538
|
-
"aria-label": `Remove row ${r + 1}`,
|
|
9539
|
-
onClick: () => removeRow(r),
|
|
9540
|
-
disabled: rows.length <= 1,
|
|
9541
|
-
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",
|
|
9542
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-3 w-3" })
|
|
9543
|
-
}
|
|
9544
|
-
),
|
|
9545
|
-
row.map((cell, c) => {
|
|
9546
|
-
const isRichText = cell.type === "rich_text";
|
|
9547
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-[120px] flex-1 flex-col gap-0.5", children: [
|
|
9548
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
9549
|
-
Input,
|
|
9550
|
-
{
|
|
9551
|
-
value: cellAsText(cell),
|
|
9552
|
-
placeholder: r === 0 ? `Header ${c + 1}` : "Cell text",
|
|
9553
|
-
onChange: (e) => setCell(r, c, e.target.value),
|
|
9554
|
-
className: "h-8 text-xs"
|
|
9555
|
-
}
|
|
9556
|
-
),
|
|
9557
|
-
isRichText ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: "Was rich-text; editing replaces with plain text." }) : null
|
|
9558
|
-
] }, c);
|
|
9559
|
-
})
|
|
9560
|
-
] }, r))
|
|
9561
|
-
] }) }),
|
|
9562
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
|
|
9563
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addRow, disabled: rows.length >= 100, children: [
|
|
9564
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
9565
|
-
" Add row"
|
|
9566
|
-
] }),
|
|
9567
|
-
/* @__PURE__ */ jsxRuntime.jsxs(Button, { type: "button", size: "sm", onClick: addColumn, disabled: columnCount >= 20, children: [
|
|
9568
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { className: "h-3.5 w-3.5" }),
|
|
9569
|
-
" Add column"
|
|
9570
|
-
] })
|
|
9571
|
-
] })
|
|
9572
|
-
] });
|
|
9861
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
9862
|
+
CellGrid,
|
|
9863
|
+
{
|
|
9864
|
+
label: "Cells",
|
|
9865
|
+
help: "Up to 100 rows and 20 columns. Slack allows one table per message.",
|
|
9866
|
+
rows,
|
|
9867
|
+
minRows: 1,
|
|
9868
|
+
maxRows: 100,
|
|
9869
|
+
maxColumns: 20,
|
|
9870
|
+
blankCell: () => ({ type: "raw_text", text: "" }),
|
|
9871
|
+
onChange: (nextRows, edit) => onChange({
|
|
9872
|
+
...block,
|
|
9873
|
+
rows: nextRows,
|
|
9874
|
+
...edit ? { column_settings: alignColumnSettings(columnSettings, edit) } : {}
|
|
9875
|
+
}),
|
|
9876
|
+
renderColumnControl: (c) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9877
|
+
"select",
|
|
9878
|
+
{
|
|
9879
|
+
"aria-label": `Column ${c + 1} alignment`,
|
|
9880
|
+
value: columnSettings[c]?.align ?? "",
|
|
9881
|
+
onChange: (e) => setColumnAlign(c, e.target.value),
|
|
9882
|
+
className: "h-7 flex-1 rounded-sm border border-input bg-background px-1.5 text-[11px] text-muted-foreground",
|
|
9883
|
+
children: [
|
|
9884
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Default" }),
|
|
9885
|
+
ALIGN_OPTIONS.map((a) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: a, children: a }, a))
|
|
9886
|
+
]
|
|
9887
|
+
}
|
|
9888
|
+
),
|
|
9889
|
+
renderCell: (cell, { row, col, label }, update) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
9890
|
+
CellTextInput,
|
|
9891
|
+
{
|
|
9892
|
+
cell,
|
|
9893
|
+
label,
|
|
9894
|
+
placeholder: row === 0 ? `Header ${col + 1}` : "Cell text",
|
|
9895
|
+
onChange: update
|
|
9896
|
+
}
|
|
9897
|
+
)
|
|
9898
|
+
}
|
|
9899
|
+
);
|
|
9573
9900
|
}
|
|
9574
9901
|
var STATUSES2 = ["pending", "in_progress", "complete", "error"];
|
|
9575
9902
|
function TaskCardEditor({ block, onChange }) {
|
|
@@ -9910,6 +10237,8 @@ function dispatch(block, onChange) {
|
|
|
9910
10237
|
return /* @__PURE__ */ jsxRuntime.jsx(DataVisualizationEditor, { block, onChange: (next) => onChange(next) });
|
|
9911
10238
|
case "container":
|
|
9912
10239
|
return /* @__PURE__ */ jsxRuntime.jsx(ContainerEditor, { block, onChange: (next) => onChange(next) });
|
|
10240
|
+
case "data_table":
|
|
10241
|
+
return /* @__PURE__ */ jsxRuntime.jsx(DataTableEditor, { block, onChange: (next) => onChange(next) });
|
|
9913
10242
|
default:
|
|
9914
10243
|
return null;
|
|
9915
10244
|
}
|
|
@@ -9933,7 +10262,8 @@ var BLOCK_TYPE_LABELS = {
|
|
|
9933
10262
|
plan: "Plan",
|
|
9934
10263
|
task_card: "Task Card",
|
|
9935
10264
|
data_visualization: "Data Visualization",
|
|
9936
|
-
container: "Container"
|
|
10265
|
+
container: "Container",
|
|
10266
|
+
data_table: "Data Table"
|
|
9937
10267
|
};
|
|
9938
10268
|
function BlockRow({
|
|
9939
10269
|
builderBlock,
|