@rowsncolumns/spreadsheet 10.4.1 → 10.4.2
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/cjs/components/filter-box/date-tree.d.ts +23 -5
- package/dist/cjs/components/filter-box/date-tree.d.ts.map +1 -1
- package/dist/cjs/components/filter-box/date-tree.js +76 -11
- package/dist/cjs/components/filter-box/filter-by-condition.d.ts +26 -1
- package/dist/cjs/components/filter-box/filter-by-condition.d.ts.map +1 -1
- package/dist/cjs/components/filter-box/filter-by-condition.js +108 -9
- package/dist/cjs/components/filter-box/index.d.ts.map +1 -1
- package/dist/cjs/components/filter-box/index.js +7 -2
- package/dist/cjs/components/formula-input/index.d.ts.map +1 -1
- package/dist/cjs/components/formula-input/index.js +26 -4
- package/dist/cjs/components/toolbar/table-style-editor.d.ts +85 -0
- package/dist/cjs/components/toolbar/table-style-editor.d.ts.map +1 -0
- package/dist/cjs/components/toolbar/table-style-editor.js +235 -0
- package/dist/cjs/components/toolbar/table-style-selector.d.ts +7 -7
- package/dist/cjs/components/toolbar/table-style-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/table-style-selector.js +77 -87
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +10 -0
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/components/filter-box/date-tree.d.ts +23 -5
- package/dist/esm/components/filter-box/date-tree.d.ts.map +1 -1
- package/dist/esm/components/filter-box/date-tree.js +62 -10
- package/dist/esm/components/filter-box/filter-by-condition.d.ts +26 -1
- package/dist/esm/components/filter-box/filter-by-condition.d.ts.map +1 -1
- package/dist/esm/components/filter-box/filter-by-condition.js +78 -12
- package/dist/esm/components/filter-box/index.d.ts.map +1 -1
- package/dist/esm/components/filter-box/index.js +7 -2
- package/dist/esm/components/formula-input/index.d.ts.map +1 -1
- package/dist/esm/components/formula-input/index.js +26 -4
- package/dist/esm/components/toolbar/table-style-editor.d.ts +85 -0
- package/dist/esm/components/toolbar/table-style-editor.d.ts.map +1 -0
- package/dist/esm/components/toolbar/table-style-editor.js +189 -0
- package/dist/esm/components/toolbar/table-style-selector.d.ts +7 -7
- package/dist/esm/components/toolbar/table-style-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/table-style-selector.js +74 -81
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +10 -0
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TableStylePreviewCard = exports.TableStyleEditor = exports.getTableStyleNameError = exports.getTableStyleColors = exports.buildCustomTableStyle = exports.DEFAULT_TABLE_STYLE_COLORS = exports.TABLE_STYLE_ELEMENTS = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var icons_1 = require("@rowsncolumns/icons");
|
|
6
|
+
var ui_1 = require("@rowsncolumns/ui");
|
|
7
|
+
var utils_1 = require("@rowsncolumns/utils");
|
|
8
|
+
var react_1 = tslib_1.__importStar(require("react"));
|
|
9
|
+
var banded_ranges_1 = require("../../api/banded-ranges");
|
|
10
|
+
var themes_1 = require("../../themes");
|
|
11
|
+
var color_selector_1 = require("./color-selector");
|
|
12
|
+
/**
|
|
13
|
+
* The style elements a custom table style can colour — the `rowProperties` fields the grid's
|
|
14
|
+
* banding resolves (`api/banded-ranges.ts`), in the order of Excel's New Table Style dialog.
|
|
15
|
+
* The first three are what the gallery swatches show and what every created style carries; the
|
|
16
|
+
* rest are only written when the user picks a colour for them.
|
|
17
|
+
*/
|
|
18
|
+
exports.TABLE_STYLE_ELEMENTS = [
|
|
19
|
+
{ key: "header", label: "Header row", property: "headerColor" },
|
|
20
|
+
{ key: "firstBand", label: "First row stripe", property: "firstBandColor" },
|
|
21
|
+
{ key: "secondBand", label: "Second row stripe", property: "secondBandColor" },
|
|
22
|
+
{ key: "firstColumn", label: "First column", property: "firstColumnColor" },
|
|
23
|
+
{ key: "lastColumn", label: "Last column", property: "lastColumnColor" },
|
|
24
|
+
{ key: "totalRow", label: "Total row", property: "totalRowColor" },
|
|
25
|
+
];
|
|
26
|
+
/** The colours a fresh style starts from (the default palette's accent 1 and its light tint). */
|
|
27
|
+
exports.DEFAULT_TABLE_STYLE_COLORS = {
|
|
28
|
+
header: "#4472c4",
|
|
29
|
+
firstBand: "#b4c6e7",
|
|
30
|
+
secondBand: "#ffffff",
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The banding a custom table style paints from its element colours. Header and the two stripes
|
|
34
|
+
* are always present (unset ones stay unpainted); the optional elements are written only when
|
|
35
|
+
* coloured, so a style that only picks the first three keeps its historical shape.
|
|
36
|
+
*/
|
|
37
|
+
var buildCustomTableStyle = function (name, colors) {
|
|
38
|
+
var rowProperties = {
|
|
39
|
+
headerColor: colors.header,
|
|
40
|
+
firstBandColor: colors.firstBand,
|
|
41
|
+
secondBandColor: colors.secondBand,
|
|
42
|
+
};
|
|
43
|
+
if (colors.firstColumn)
|
|
44
|
+
rowProperties.firstColumnColor = colors.firstColumn;
|
|
45
|
+
if (colors.lastColumn)
|
|
46
|
+
rowProperties.lastColumnColor = colors.lastColumn;
|
|
47
|
+
if (colors.totalRow)
|
|
48
|
+
rowProperties.totalRowColor = colors.totalRow;
|
|
49
|
+
return { name: name, bandedRange: { rowProperties: rowProperties } };
|
|
50
|
+
};
|
|
51
|
+
exports.buildCustomTableStyle = buildCustomTableStyle;
|
|
52
|
+
/** The element colours of an existing custom style (theme colours resolved to hex). */
|
|
53
|
+
var getTableStyleColors = function (style, theme) {
|
|
54
|
+
var e_1, _a;
|
|
55
|
+
var _b;
|
|
56
|
+
var rowProperties = (_b = style.bandedRange.rowProperties) !== null && _b !== void 0 ? _b : {};
|
|
57
|
+
var colors = {};
|
|
58
|
+
try {
|
|
59
|
+
for (var TABLE_STYLE_ELEMENTS_1 = tslib_1.__values(exports.TABLE_STYLE_ELEMENTS), TABLE_STYLE_ELEMENTS_1_1 = TABLE_STYLE_ELEMENTS_1.next(); !TABLE_STYLE_ELEMENTS_1_1.done; TABLE_STYLE_ELEMENTS_1_1 = TABLE_STYLE_ELEMENTS_1.next()) {
|
|
60
|
+
var _c = TABLE_STYLE_ELEMENTS_1_1.value, key = _c.key, property = _c.property;
|
|
61
|
+
var color = (0, themes_1.getStringifiedColor)((0, banded_ranges_1.parseTintedColor)(rowProperties[property]), theme);
|
|
62
|
+
if (color)
|
|
63
|
+
colors[key] = color;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
67
|
+
finally {
|
|
68
|
+
try {
|
|
69
|
+
if (TABLE_STYLE_ELEMENTS_1_1 && !TABLE_STYLE_ELEMENTS_1_1.done && (_a = TABLE_STYLE_ELEMENTS_1.return)) _a.call(TABLE_STYLE_ELEMENTS_1);
|
|
70
|
+
}
|
|
71
|
+
finally { if (e_1) throw e_1.error; }
|
|
72
|
+
}
|
|
73
|
+
return colors;
|
|
74
|
+
};
|
|
75
|
+
exports.getTableStyleColors = getTableStyleColors;
|
|
76
|
+
var BUILT_IN_STYLE_NAME = /^TableStyle(Light|Medium|Dark)\d+$/i;
|
|
77
|
+
/**
|
|
78
|
+
* Why a style name cannot be used, or `undefined` when it can: empty, a built-in style's name
|
|
79
|
+
* (the gallery tells the two apart by name), or another custom style's name (case-insensitive,
|
|
80
|
+
* like Excel). `currentName` is the style being edited, which may keep its own name.
|
|
81
|
+
*/
|
|
82
|
+
var getTableStyleNameError = function (name, existingNames, currentName) {
|
|
83
|
+
var trimmed = name.trim();
|
|
84
|
+
if (!trimmed)
|
|
85
|
+
return "Enter a name for the style.";
|
|
86
|
+
if (BUILT_IN_STYLE_NAME.test(trimmed)) {
|
|
87
|
+
return "That name belongs to a built-in style.";
|
|
88
|
+
}
|
|
89
|
+
var lower = trimmed.toLowerCase();
|
|
90
|
+
var taken = existingNames.some(function (existing) {
|
|
91
|
+
return existing.toLowerCase() === lower &&
|
|
92
|
+
existing.toLowerCase() !== (currentName === null || currentName === void 0 ? void 0 : currentName.toLowerCase());
|
|
93
|
+
});
|
|
94
|
+
return taken ? "A table style named \u201C".concat(trimmed, "\u201D already exists.") : undefined;
|
|
95
|
+
};
|
|
96
|
+
exports.getTableStyleNameError = getTableStyleNameError;
|
|
97
|
+
/**
|
|
98
|
+
* Excel's New Table Style / Modify Table Style dialog, laid out for the Format as Table gallery:
|
|
99
|
+
* name row, the table elements with a colour button each (the toolbar's colour popover), a live
|
|
100
|
+
* preview of the table the picks produce, and an Excel-ordered footer.
|
|
101
|
+
*/
|
|
102
|
+
var TableStyleEditor = function (_a) {
|
|
103
|
+
var _b;
|
|
104
|
+
var style = _a.style, _c = _a.defaultName, defaultName = _c === void 0 ? "" : _c, theme = _a.theme, _d = _a.existingNames, existingNames = _d === void 0 ? [] : _d, onSubmit = _a.onSubmit, onCancel = _a.onCancel, onDelete = _a.onDelete, className = _a.className;
|
|
105
|
+
var isEditing = !!style;
|
|
106
|
+
var nameId = (0, react_1.useId)();
|
|
107
|
+
var _e = tslib_1.__read((0, react_1.useState)((_b = style === null || style === void 0 ? void 0 : style.name) !== null && _b !== void 0 ? _b : defaultName), 2), name = _e[0], setName = _e[1];
|
|
108
|
+
var _f = tslib_1.__read((0, react_1.useState)(function () {
|
|
109
|
+
return style ? (0, exports.getTableStyleColors)(style, theme) : exports.DEFAULT_TABLE_STYLE_COLORS;
|
|
110
|
+
}), 2), colors = _f[0], setColors = _f[1];
|
|
111
|
+
var nameError = (0, exports.getTableStyleNameError)(name, existingNames, style === null || style === void 0 ? void 0 : style.name);
|
|
112
|
+
var preview = (0, react_1.useMemo)(function () { return (0, exports.buildCustomTableStyle)(name.trim(), colors); }, [name, colors]);
|
|
113
|
+
var setColor = function (key, color) {
|
|
114
|
+
return setColors(function (prev) {
|
|
115
|
+
var _a;
|
|
116
|
+
return (tslib_1.__assign(tslib_1.__assign({}, prev), (_a = {}, _a[key] = color, _a)));
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
var hasAnyColor = exports.TABLE_STYLE_ELEMENTS.some(function (_a) {
|
|
120
|
+
var key = _a.key;
|
|
121
|
+
return colors[key];
|
|
122
|
+
});
|
|
123
|
+
return (react_1.default.createElement("form", { "data-testid": "table-style-editor", "aria-label": isEditing ? "Edit table style" : "New table style", className: (0, ui_1.cn)("m-0 p-2 flex flex-col gap-3 font-system text-xs", className),
|
|
124
|
+
// The gallery is a Radix menu: keep typing in the fields from driving its typeahead.
|
|
125
|
+
onKeyDown: function (event) { return event.stopPropagation(); }, onSubmit: function (event) {
|
|
126
|
+
event.preventDefault();
|
|
127
|
+
if (!nameError) {
|
|
128
|
+
onSubmit(preview);
|
|
129
|
+
}
|
|
130
|
+
} },
|
|
131
|
+
react_1.default.createElement("div", { className: "font-medium text-sm" }, isEditing ? "Edit table style" : "New table style"),
|
|
132
|
+
react_1.default.createElement("div", { className: "grid grid-cols-[6rem_minmax(0,1fr)] items-center gap-x-3 gap-y-1" },
|
|
133
|
+
react_1.default.createElement("label", { htmlFor: nameId, className: "truncate whitespace-nowrap" }, "Name"),
|
|
134
|
+
react_1.default.createElement(ui_1.Input, { id: nameId, value: name, onChange: function (event) { return setName(event.target.value); }, autoComplete: "off", "aria-invalid": nameError ? true : undefined, "aria-describedby": nameError ? "".concat(nameId, "-error") : undefined, className: "text-xs" }),
|
|
135
|
+
nameError ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
136
|
+
react_1.default.createElement("span", { "aria-hidden": "true" }),
|
|
137
|
+
react_1.default.createElement("p", { id: "".concat(nameId, "-error"), role: "alert", className: "m-0 text-rnc-destructive" }, nameError))) : null),
|
|
138
|
+
react_1.default.createElement("div", { className: "flex items-start gap-4" },
|
|
139
|
+
react_1.default.createElement("div", { role: "group", "aria-label": "Table elements", className: "flex-1 min-w-0 flex flex-col gap-1.5" },
|
|
140
|
+
react_1.default.createElement("div", { className: "text-rnc-muted-foreground" }, "Table element"),
|
|
141
|
+
exports.TABLE_STYLE_ELEMENTS.map(function (_a) {
|
|
142
|
+
var key = _a.key, label = _a.label;
|
|
143
|
+
return (react_1.default.createElement("div", { key: key, className: "grid grid-cols-[minmax(0,1fr)_auto] items-center gap-3 h-7" },
|
|
144
|
+
react_1.default.createElement("span", { className: "truncate whitespace-nowrap", title: label }, label),
|
|
145
|
+
react_1.default.createElement(ElementColorButton, { label: label, color: colors[key], theme: theme, onChange: function (color) { return setColor(key, color); } })));
|
|
146
|
+
})),
|
|
147
|
+
react_1.default.createElement("div", { className: "w-[180px] shrink-0 flex flex-col gap-1.5" },
|
|
148
|
+
react_1.default.createElement("div", { className: "text-rnc-muted-foreground" }, "Preview"),
|
|
149
|
+
react_1.default.createElement(exports.TableStylePreviewCard, { rowProperties: preview.bandedRange.rowProperties, theme: theme }),
|
|
150
|
+
react_1.default.createElement(ui_1.Button, { type: "button", variant: "link", size: "xs", className: "self-start no-underline hover:underline", disabled: !hasAnyColor, onClick: function () { return setColors({}); } }, "Clear all colors"))),
|
|
151
|
+
react_1.default.createElement(ui_1.Separator, null),
|
|
152
|
+
react_1.default.createElement("div", { className: "flex items-center gap-2" },
|
|
153
|
+
isEditing && onDelete ? (react_1.default.createElement(ui_1.Button, { type: "button", variant: "ghost", size: "xs", className: "text-rnc-destructive hover:text-rnc-destructive", onClick: function () { return onDelete(style); } }, "Delete style")) : null,
|
|
154
|
+
react_1.default.createElement("div", { className: "ml-auto flex items-center gap-2" },
|
|
155
|
+
react_1.default.createElement(ui_1.Button, { type: "button", variant: "ghost", size: "xs", onClick: onCancel }, "Cancel"),
|
|
156
|
+
react_1.default.createElement(ui_1.Button, { type: "submit", variant: "primary", size: "xs", disabled: !!nameError }, isEditing ? "Save" : "Create")))));
|
|
157
|
+
};
|
|
158
|
+
exports.TableStyleEditor = TableStyleEditor;
|
|
159
|
+
/** "No colour" swatch: a red diagonal on the popover background, as the toolbar's fill button. */
|
|
160
|
+
var NO_COLOR_BACKGROUND = "linear-gradient(to top right, transparent 44%, #d32f2f 44%, #d32f2f 56%, transparent 56%)";
|
|
161
|
+
/**
|
|
162
|
+
* One element's colour: a swatch button (current colour + chevron) opening the shared colour
|
|
163
|
+
* popover the toolbar's fill / text colour buttons use (theme colours, standard colours, custom,
|
|
164
|
+
* and "No color").
|
|
165
|
+
*/
|
|
166
|
+
var ElementColorButton = function (_a) {
|
|
167
|
+
var label = _a.label, color = _a.color, theme = _a.theme, onChange = _a.onChange;
|
|
168
|
+
var _b = tslib_1.__read((0, react_1.useState)(false), 2), isOpen = _b[0], setIsOpen = _b[1];
|
|
169
|
+
return (react_1.default.createElement(ui_1.Popover, { modal: false, open: isOpen, onOpenChange: setIsOpen },
|
|
170
|
+
react_1.default.createElement(ui_1.PopoverTrigger, { asChild: true },
|
|
171
|
+
react_1.default.createElement(ui_1.Button, { type: "button", variant: "outline", size: "xs", "aria-label": "".concat(label, " color: ").concat(color ? color.toUpperCase() : "No color"), "aria-haspopup": "dialog", "aria-expanded": isOpen, className: "h-7 w-14 px-1 py-0 gap-1 justify-between rounded-sm" },
|
|
172
|
+
react_1.default.createElement("span", { "data-testid": "element-color-swatch", "aria-hidden": "true", className: "block w-5 h-5 rounded-sm border border-solid border-rnc-border", style: color
|
|
173
|
+
? { backgroundColor: color }
|
|
174
|
+
: { backgroundImage: NO_COLOR_BACKGROUND } }),
|
|
175
|
+
react_1.default.createElement(icons_1.ChevronDownIcon, { className: "w-3 h-3 text-rnc-muted-foreground" }))),
|
|
176
|
+
react_1.default.createElement(ui_1.PopoverContent, { align: "end" },
|
|
177
|
+
react_1.default.createElement(color_selector_1.ColorSelector, { color: color, theme: theme, resetButtonTitle: "No color", onChange: function (next) {
|
|
178
|
+
onChange(next ? (0, themes_1.getStringifiedColor)(next, theme) : undefined);
|
|
179
|
+
setIsOpen(false);
|
|
180
|
+
} }))));
|
|
181
|
+
};
|
|
182
|
+
var PREVIEW_COLUMNS = 5;
|
|
183
|
+
var PREVIEW_BODY_ROWS = 4;
|
|
184
|
+
/**
|
|
185
|
+
* The table a style paints: a header row over four banded rows, with the first / last column and
|
|
186
|
+
* total row emphasis when the style colours them. Uses the grid's banding rules
|
|
187
|
+
* (`api/banded-ranges.ts`): the first body row is the first stripe, the last body row is the
|
|
188
|
+
* total row, and an edge column's colour outranks the stripe under it.
|
|
189
|
+
*/
|
|
190
|
+
var TableStylePreviewCard = function (_a) {
|
|
191
|
+
var rowProperties = _a.rowProperties, theme = _a.theme;
|
|
192
|
+
var resolve = function (color) { var _a; return (_a = (0, themes_1.getStringifiedColor)((0, banded_ranges_1.parseTintedColor)(color), theme)) !== null && _a !== void 0 ? _a : undefined; };
|
|
193
|
+
var headerColor = resolve(rowProperties === null || rowProperties === void 0 ? void 0 : rowProperties.headerColor);
|
|
194
|
+
var firstBand = resolve(rowProperties === null || rowProperties === void 0 ? void 0 : rowProperties.firstBandColor);
|
|
195
|
+
var secondBand = resolve(rowProperties === null || rowProperties === void 0 ? void 0 : rowProperties.secondBandColor);
|
|
196
|
+
var firstColumn = resolve(rowProperties === null || rowProperties === void 0 ? void 0 : rowProperties.firstColumnColor);
|
|
197
|
+
var lastColumn = resolve(rowProperties === null || rowProperties === void 0 ? void 0 : rowProperties.lastColumnColor);
|
|
198
|
+
var totalRow = resolve(rowProperties === null || rowProperties === void 0 ? void 0 : rowProperties.totalRowColor);
|
|
199
|
+
var dark = (0, themes_1.getStringifiedColor)({ theme: 1 }, theme);
|
|
200
|
+
var light = (0, themes_1.getStringifiedColor)({ theme: 0 }, theme);
|
|
201
|
+
var barColor = function (background) {
|
|
202
|
+
return background ? (0, utils_1.getContrastColor)(background, dark, light) : undefined;
|
|
203
|
+
};
|
|
204
|
+
var cellClass = "table-cell border border-solid border-rnc-border/70 align-middle px-1.5";
|
|
205
|
+
return (react_1.default.createElement("div", { "data-testid": "table-style-preview", className: "table border-collapse table-fixed w-full h-[108px] rounded-sm bg-rnc-popover" },
|
|
206
|
+
react_1.default.createElement("div", { className: "table-row", "data-testid": "preview-header-row" }, Array.from({ length: PREVIEW_COLUMNS }, function (_, column) {
|
|
207
|
+
var _a;
|
|
208
|
+
return (react_1.default.createElement("div", { key: column, className: cellClass, style: { backgroundColor: headerColor } },
|
|
209
|
+
react_1.default.createElement("span", { className: "block h-1.5 w-3/4 rounded-full", style: {
|
|
210
|
+
backgroundColor: (_a = barColor(headerColor)) !== null && _a !== void 0 ? _a : dark,
|
|
211
|
+
opacity: headerColor ? 0.9 : 0.6,
|
|
212
|
+
} })));
|
|
213
|
+
})),
|
|
214
|
+
Array.from({ length: PREVIEW_BODY_ROWS }, function (_, row) {
|
|
215
|
+
var isTotalRow = row === PREVIEW_BODY_ROWS - 1;
|
|
216
|
+
var stripe = row % 2 === 0 ? firstBand : secondBand;
|
|
217
|
+
var rowBackground = isTotalRow ? totalRow !== null && totalRow !== void 0 ? totalRow : stripe : stripe;
|
|
218
|
+
return (react_1.default.createElement("div", { className: "table-row", key: row, "data-testid": "preview-body-row" }, Array.from({ length: PREVIEW_COLUMNS }, function (_, column) {
|
|
219
|
+
var _a;
|
|
220
|
+
var edge = column === 0
|
|
221
|
+
? firstColumn
|
|
222
|
+
: column === PREVIEW_COLUMNS - 1
|
|
223
|
+
? lastColumn
|
|
224
|
+
: undefined;
|
|
225
|
+
var background = edge !== null && edge !== void 0 ? edge : rowBackground;
|
|
226
|
+
return (react_1.default.createElement("div", { key: column, className: cellClass, style: { backgroundColor: background } },
|
|
227
|
+
react_1.default.createElement("span", { className: "block h-1 rounded-full", style: {
|
|
228
|
+
width: "".concat(55 + ((row * 3 + column * 5) % 4) * 10, "%"),
|
|
229
|
+
backgroundColor: (_a = barColor(background)) !== null && _a !== void 0 ? _a : dark,
|
|
230
|
+
opacity: 0.35,
|
|
231
|
+
} })));
|
|
232
|
+
})));
|
|
233
|
+
})));
|
|
234
|
+
};
|
|
235
|
+
exports.TableStylePreviewCard = TableStylePreviewCard;
|
|
@@ -2,6 +2,7 @@ import type { CellInterface, SelectionArea } from "@rowsncolumns/grid";
|
|
|
2
2
|
import { findMatchingBandProperty } from "@rowsncolumns/utils";
|
|
3
3
|
import React from "react";
|
|
4
4
|
export { findMatchingBandProperty };
|
|
5
|
+
export { buildCustomTableStyle } from "./table-style-editor";
|
|
5
6
|
import type { BandedDefinition, CustomTableStyle, TableStylePreview, TableTheme, TableView } from "../../types";
|
|
6
7
|
import type { CanvasGridProps, SelectionAttributes, SpreadsheetTheme } from "../canvas-grid/typings";
|
|
7
8
|
export type TableStyleSelectorProps = {
|
|
@@ -26,6 +27,11 @@ export type TableStyleSelectorProps = {
|
|
|
26
27
|
* without it the selector keeps the styles it created for the session.
|
|
27
28
|
*/
|
|
28
29
|
onCreateCustomTableStyle?(style: CustomTableStyle): void;
|
|
30
|
+
/**
|
|
31
|
+
* Called with a host-kept custom style the user deletes from the style editor (right-click a
|
|
32
|
+
* Custom swatch → Delete style); without it host-kept styles cannot be deleted from the gallery.
|
|
33
|
+
*/
|
|
34
|
+
onDeleteCustomTableStyle?(style: CustomTableStyle): void;
|
|
29
35
|
};
|
|
30
36
|
/** Excel's Table Style Options (Table Design tab), in ribbon order. */
|
|
31
37
|
declare const STYLE_OPTIONS: Array<{
|
|
@@ -39,12 +45,6 @@ declare const STYLE_OPTIONS: Array<{
|
|
|
39
45
|
* does); a custom style has no palette to re-resolve from and keeps its banding.
|
|
40
46
|
*/
|
|
41
47
|
export declare const getStyleOptionUpdate: (table: TableView, key: (typeof STYLE_OPTIONS)[number]["key"], checked: boolean) => Partial<TableView>;
|
|
42
|
-
/** The banding a New Table Style paints from its three colours (unset elements stay unpainted). */
|
|
43
|
-
export declare const buildCustomTableStyle: (name: string, colors: {
|
|
44
|
-
header?: string;
|
|
45
|
-
firstBand?: string;
|
|
46
|
-
secondBand?: string;
|
|
47
|
-
}) => CustomTableStyle;
|
|
48
48
|
type TableStyleList = [
|
|
49
49
|
theme: TableTheme,
|
|
50
50
|
firtBandStripeTint: number | undefined,
|
|
@@ -57,5 +57,5 @@ type TableStyleList = [
|
|
|
57
57
|
* importers and both engines resolve a theme name into) plus a per-swatch preview style.
|
|
58
58
|
*/
|
|
59
59
|
export declare const getTableBorderStyles: (showRowStripes: boolean | undefined, showColumnStripes: boolean | undefined, theme?: SpreadsheetTheme) => Map<string, TableStyleList[]>;
|
|
60
|
-
export declare const TableStyleSelector: React.MemoExoticComponent<({ tables, sheetId, theme, activeCell, selections, onUpdateTable, onCreateTable, onRequestCreateTable, onPreviewTableStyle, customTableStyles, onCreateCustomTableStyle, }: TableStyleSelectorProps) => React.JSX.Element>;
|
|
60
|
+
export declare const TableStyleSelector: React.MemoExoticComponent<({ tables, sheetId, theme, activeCell, selections, onUpdateTable, onCreateTable, onRequestCreateTable, onPreviewTableStyle, customTableStyles, onCreateCustomTableStyle, onDeleteCustomTableStyle, }: TableStyleSelectorProps) => React.JSX.Element>;
|
|
61
61
|
//# sourceMappingURL=table-style-selector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-style-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/table-style-selector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"table-style-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/table-style-selector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAevE,OAAO,EACL,wBAAwB,EAGzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAuD,MAAM,OAAO,CAAC;AAG5E,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAK7D,OAAO,KAAK,EACV,gBAAgB,EAEhB,gBAAgB,EAEhB,iBAAiB,EACjB,UAAU,EACV,SAAS,EACV,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAGhC,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,aAAa,CAAC,mBAAmB,CAAC,EAAE,CAAC;IACjD,UAAU,EAAE,aAAa,CAAC;IAC1B,aAAa,CAAC,CACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,SAAS,CAAC,IAAI,CAAC,EACxB,YAAY,EAAE,OAAO,CAAC,SAAS,CAAC,GAC/B,IAAI,CAAC;IACR,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAChD,4FAA4F;IAC5F,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D;;;OAGG;IACH,mBAAmB,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI,CAAC;IAC9D,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC;;;OAGG;IACH,wBAAwB,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACzD;;;OAGG;IACH,wBAAwB,CAAC,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAC1D,CAAC;AAEF,uEAAuE;AACvE,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC;IACzB,GAAG,EACC,WAAW,GACX,UAAU,GACV,gBAAgB,GAChB,mBAAmB,GACnB,iBAAiB,GACjB,gBAAgB,GAChB,cAAc,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;CACvB,CAQA,CAAC;AAKF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,OAAO,SAAS,EAChB,KAAK,CAAC,OAAO,aAAa,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,EAC1C,SAAS,OAAO,KACf,OAAO,CAAC,SAAS,CAqBnB,CAAC;AAEF,KAAK,cAAc,GAAG;IACpB,KAAK,EAAE,UAAU;IACjB,kBAAkB,EAAE,MAAM,GAAG,SAAS;IACtC,cAAc,EAAE,MAAM,GAAG,SAAS;IAClC,cAAc,EAAE,gBAAgB,GAAG,SAAS;IAC5C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa;CAC5B,CAAC;AAKF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,gBAAgB,OAAO,GAAG,SAAS,EACnC,mBAAmB,OAAO,GAAG,SAAS,EACtC,QAAQ,gBAAgB,kCAoBzB,CAAC;AAEF,eAAO,MAAM,kBAAkB,kOAc1B,uBAAuB,uBA+W3B,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TableStyleSelector = exports.getTableBorderStyles = exports.
|
|
3
|
+
exports.TableStyleSelector = exports.getTableBorderStyles = exports.getStyleOptionUpdate = exports.buildCustomTableStyle = exports.findMatchingBandProperty = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var grid_1 = require("@rowsncolumns/grid");
|
|
6
6
|
var icons_1 = require("@rowsncolumns/icons");
|
|
@@ -8,9 +8,12 @@ var ui_1 = require("@rowsncolumns/ui");
|
|
|
8
8
|
var utils_1 = require("@rowsncolumns/utils");
|
|
9
9
|
Object.defineProperty(exports, "findMatchingBandProperty", { enumerable: true, get: function () { return utils_1.findMatchingBandProperty; } });
|
|
10
10
|
var react_1 = tslib_1.__importStar(require("react"));
|
|
11
|
+
var table_style_editor_1 = require("./table-style-editor");
|
|
12
|
+
Object.defineProperty(exports, "buildCustomTableStyle", { enumerable: true, get: function () { return table_style_editor_1.buildCustomTableStyle; } });
|
|
11
13
|
var banded_ranges_1 = require("../../api/banded-ranges");
|
|
12
14
|
var sheet_context_atom_1 = require("../../atoms/sheet-context.atom");
|
|
13
15
|
var themes_1 = require("../../themes");
|
|
16
|
+
var table_style_editor_2 = require("./table-style-editor");
|
|
14
17
|
/** Excel's Table Style Options (Table Design tab), in ribbon order. */
|
|
15
18
|
var STYLE_OPTIONS = [
|
|
16
19
|
{ key: "headerRow", label: "Header Row", defaultValue: true },
|
|
@@ -45,37 +48,6 @@ var getStyleOptionUpdate = function (table, key, checked) {
|
|
|
45
48
|
return update;
|
|
46
49
|
};
|
|
47
50
|
exports.getStyleOptionUpdate = getStyleOptionUpdate;
|
|
48
|
-
/** The colours "New Table Style…" offers for each element (the workbook palette's accents). */
|
|
49
|
-
var NEW_STYLE_COLORS = [
|
|
50
|
-
"#000000",
|
|
51
|
-
"#595959",
|
|
52
|
-
"#a6a6a6",
|
|
53
|
-
"#d9d9d9",
|
|
54
|
-
"#ffffff",
|
|
55
|
-
"#4472c4",
|
|
56
|
-
"#b4c6e7",
|
|
57
|
-
"#ed7d31",
|
|
58
|
-
"#f8cbad",
|
|
59
|
-
"#a5a5a5",
|
|
60
|
-
"#ffc000",
|
|
61
|
-
"#ffe699",
|
|
62
|
-
"#5b9bd5",
|
|
63
|
-
"#bdd7ee",
|
|
64
|
-
"#70ad47",
|
|
65
|
-
"#c6e0b4",
|
|
66
|
-
];
|
|
67
|
-
/** The banding a New Table Style paints from its three colours (unset elements stay unpainted). */
|
|
68
|
-
var buildCustomTableStyle = function (name, colors) { return ({
|
|
69
|
-
name: name,
|
|
70
|
-
bandedRange: {
|
|
71
|
-
rowProperties: {
|
|
72
|
-
headerColor: colors.header,
|
|
73
|
-
firstBandColor: colors.firstBand,
|
|
74
|
-
secondBandColor: colors.secondBand,
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
}); };
|
|
78
|
-
exports.buildCustomTableStyle = buildCustomTableStyle;
|
|
79
51
|
/** Gallery groups whose swatch is outlined in the style's accent colour (filled-header styles). */
|
|
80
52
|
var OUTLINED_SWATCH_THEMES = /^TableStyle(?:Light(?:[89]|1[0-4])|Medium(?:1[5-9]|2[01]))$/;
|
|
81
53
|
/**
|
|
@@ -110,7 +82,8 @@ var getTableBorderStyles = function (showRowStripes, showColumnStripes, theme) {
|
|
|
110
82
|
};
|
|
111
83
|
exports.getTableBorderStyles = getTableBorderStyles;
|
|
112
84
|
exports.TableStyleSelector = (0, react_1.memo)(function (_a) {
|
|
113
|
-
var
|
|
85
|
+
var _b, _c;
|
|
86
|
+
var tables = _a.tables, sheetId = _a.sheetId, theme = _a.theme, activeCell = _a.activeCell, selections = _a.selections, onUpdateTable = _a.onUpdateTable, onCreateTable = _a.onCreateTable, onRequestCreateTable = _a.onRequestCreateTable, onPreviewTableStyle = _a.onPreviewTableStyle, customTableStyles = _a.customTableStyles, onCreateCustomTableStyle = _a.onCreateCustomTableStyle, onDeleteCustomTableStyle = _a.onDeleteCustomTableStyle;
|
|
114
87
|
var shouldFocusSheetRef = (0, react_1.useRef)(true);
|
|
115
88
|
var focusSheet = (0, sheet_context_atom_1.useFocusSheet)();
|
|
116
89
|
var table = (0, react_1.useMemo)(function () {
|
|
@@ -124,9 +97,14 @@ exports.TableStyleSelector = (0, react_1.memo)(function (_a) {
|
|
|
124
97
|
// Default showColumnStripes
|
|
125
98
|
var showColumnStripes = table ? Boolean(table.showColumnStripes) : false;
|
|
126
99
|
// Styles created here when the host does not keep them.
|
|
127
|
-
var
|
|
100
|
+
var _d = tslib_1.__read((0, react_1.useState)([]), 2), sessionCustomStyles = _d[0], setSessionCustomStyles = _d[1];
|
|
128
101
|
var allCustomStyles = (0, react_1.useMemo)(function () { return tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read((customTableStyles !== null && customTableStyles !== void 0 ? customTableStyles : [])), false), tslib_1.__read(sessionCustomStyles), false); }, [customTableStyles, sessionCustomStyles]);
|
|
129
|
-
|
|
102
|
+
/**
|
|
103
|
+
* The style editor: `{}` creates a new style, `{ style }` edits an existing custom one, `null`
|
|
104
|
+
* shows the "New Table Style…" item.
|
|
105
|
+
*/
|
|
106
|
+
var _e = tslib_1.__read((0, react_1.useState)(null), 2), styleEditor = _e[0], setStyleEditor = _e[1];
|
|
107
|
+
var isSessionStyle = (0, react_1.useCallback)(function (style) { return sessionCustomStyles.includes(style); }, [sessionCustomStyles]);
|
|
130
108
|
// Classes
|
|
131
109
|
var hoverClass = "rounded-none hover:outline-solid hover:outline-1 hover:outline hover:outline-offset-1 hover:outline-rnc-primary focus:outline focus:outline-offset-1 focus:outline-rnc-primary hover:bg-transparent focus:bg-transparent text-rnc-foreground p-1";
|
|
132
110
|
var headingClass = "text-xs font-system pt-2 pb-1 text-rnc-foreground";
|
|
@@ -178,27 +156,59 @@ exports.TableStyleSelector = (0, react_1.memo)(function (_a) {
|
|
|
178
156
|
onUpdateTable === null || onUpdateTable === void 0 ? void 0 : onUpdateTable(sheetId, table.id, (0, exports.getStyleOptionUpdate)(table, key, checked));
|
|
179
157
|
}
|
|
180
158
|
}, [table, sheetId, onUpdateTable]);
|
|
181
|
-
/**
|
|
182
|
-
var
|
|
159
|
+
/** Remove a custom style: the host's when it keeps them, otherwise this session's. */
|
|
160
|
+
var onDeleteStyle = (0, react_1.useCallback)(function (style) {
|
|
161
|
+
if (isSessionStyle(style)) {
|
|
162
|
+
setSessionCustomStyles(function (prev) { return prev.filter(function (s) { return s !== style; }); });
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
onDeleteCustomTableStyle === null || onDeleteCustomTableStyle === void 0 ? void 0 : onDeleteCustomTableStyle(style);
|
|
166
|
+
}
|
|
167
|
+
setStyleEditor(null);
|
|
168
|
+
}, [isSessionStyle, onDeleteCustomTableStyle]);
|
|
169
|
+
/**
|
|
170
|
+
* The style editor created or saved a style: keep it (a same-named style is replaced; a
|
|
171
|
+
* renamed one replaces the style being edited) and apply it like a picked swatch.
|
|
172
|
+
*/
|
|
173
|
+
var onSubmitStyle = (0, react_1.useCallback)(function (style) {
|
|
174
|
+
var previous = styleEditor === null || styleEditor === void 0 ? void 0 : styleEditor.style;
|
|
183
175
|
if (onCreateCustomTableStyle) {
|
|
176
|
+
if (previous && previous.name !== style.name) {
|
|
177
|
+
onDeleteCustomTableStyle === null || onDeleteCustomTableStyle === void 0 ? void 0 : onDeleteCustomTableStyle(previous);
|
|
178
|
+
}
|
|
184
179
|
onCreateCustomTableStyle(style);
|
|
185
180
|
}
|
|
186
181
|
else {
|
|
187
|
-
setSessionCustomStyles(function (prev) {
|
|
182
|
+
setSessionCustomStyles(function (prev) {
|
|
183
|
+
var next = prev.filter(function (s) { return s !== previous && s.name !== style.name; });
|
|
184
|
+
var index = previous ? prev.indexOf(previous) : -1;
|
|
185
|
+
if (index === -1) {
|
|
186
|
+
next.push(style);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
next.splice(index, 0, style);
|
|
190
|
+
}
|
|
191
|
+
return next;
|
|
192
|
+
});
|
|
188
193
|
}
|
|
189
|
-
|
|
194
|
+
setStyleEditor(null);
|
|
190
195
|
onSelectStyle(style.name, style.bandedRange);
|
|
191
|
-
}, [
|
|
196
|
+
}, [
|
|
197
|
+
styleEditor,
|
|
198
|
+
onCreateCustomTableStyle,
|
|
199
|
+
onDeleteCustomTableStyle,
|
|
200
|
+
onSelectStyle,
|
|
201
|
+
]);
|
|
192
202
|
/**
|
|
193
203
|
* Get all table border styles
|
|
194
204
|
*/
|
|
195
205
|
var tableBorderstyles = (0, react_1.useMemo)(function () { return tslib_1.__spreadArray([], tslib_1.__read((0, exports.getTableBorderStyles)(showRowStripes, showColumnStripes, theme).entries()), false); }, [showRowStripes, showColumnStripes, theme]);
|
|
196
|
-
var swatch = function (key, tableTheme, bandProperties, style) { return (react_1.default.createElement(ui_1.DropdownMenuItem, { key: key, onClick: function () { return onSelectStyle(tableTheme, bandProperties); }, onPointerEnter: function () { return previewStyle(tableTheme, bandProperties); }, onPointerLeave: clearPreview, onFocus: function () { return previewStyle(tableTheme, bandProperties); }, onBlur: clearPreview, className: hoverClass, title: tableTheme },
|
|
206
|
+
var swatch = function (key, tableTheme, bandProperties, style, onContextMenu) { return (react_1.default.createElement(ui_1.DropdownMenuItem, { key: key, onClick: function () { return onSelectStyle(tableTheme, bandProperties); }, onContextMenu: onContextMenu, onPointerEnter: function () { return previewStyle(tableTheme, bandProperties); }, onPointerLeave: clearPreview, onFocus: function () { return previewStyle(tableTheme, bandProperties); }, onBlur: clearPreview, className: hoverClass, title: tableTheme },
|
|
197
207
|
react_1.default.createElement(TableSkeleton, { rowProperties: bandProperties === null || bandProperties === void 0 ? void 0 : bandProperties.rowProperties, columnProperties: bandProperties === null || bandProperties === void 0 ? void 0 : bandProperties.columnProperties, theme: theme, style: style }))); };
|
|
198
208
|
return (react_1.default.createElement(ui_1.DropdownMenu, { modal: false, onOpenChange: function (open) {
|
|
199
209
|
if (!open) {
|
|
200
210
|
clearPreview();
|
|
201
|
-
|
|
211
|
+
setStyleEditor(null);
|
|
202
212
|
}
|
|
203
213
|
} },
|
|
204
214
|
react_1.default.createElement(ui_1.DropdownMenuTrigger, { asChild: true },
|
|
@@ -233,10 +243,18 @@ exports.TableStyleSelector = (0, react_1.memo)(function (_a) {
|
|
|
233
243
|
label));
|
|
234
244
|
})))) : null,
|
|
235
245
|
allCustomStyles.length ? (react_1.default.createElement("div", null,
|
|
236
|
-
react_1.default.createElement("div", { className: headingClass
|
|
246
|
+
react_1.default.createElement("div", { className: (0, ui_1.cn)(headingClass, "flex items-baseline gap-2") },
|
|
247
|
+
"Custom",
|
|
248
|
+
react_1.default.createElement("span", { className: "ml-auto text-rnc-muted-foreground" }, "Right-click a style to edit it")),
|
|
237
249
|
react_1.default.createElement(ui_1.Separator, { className: "mb-2" }),
|
|
238
250
|
react_1.default.createElement("div", { className: gridClass }, allCustomStyles.map(function (style, index) {
|
|
239
|
-
return swatch("custom-".concat(index), style.name, style.bandedRange
|
|
251
|
+
return swatch("custom-".concat(index), style.name, style.bandedRange, undefined,
|
|
252
|
+
// Excel: right-click a custom style → Modify Table Style… / Delete.
|
|
253
|
+
function (event) {
|
|
254
|
+
event.preventDefault();
|
|
255
|
+
clearPreview();
|
|
256
|
+
setStyleEditor({ style: style });
|
|
257
|
+
});
|
|
240
258
|
})))) : null,
|
|
241
259
|
tableBorderstyles.map(function (_a) {
|
|
242
260
|
var _b = tslib_1.__read(_a, 2), category = _b[0], tableStyles = _b[1];
|
|
@@ -253,53 +271,25 @@ exports.TableStyleSelector = (0, react_1.memo)(function (_a) {
|
|
|
253
271
|
}))));
|
|
254
272
|
}),
|
|
255
273
|
react_1.default.createElement(ui_1.Separator, { className: "my-1" }),
|
|
256
|
-
|
|
257
|
-
|
|
274
|
+
styleEditor ? (react_1.default.createElement(table_style_editor_2.TableStyleEditor
|
|
275
|
+
// Remount per style so the fields seed from the style being edited.
|
|
276
|
+
, {
|
|
277
|
+
// Remount per style so the fields seed from the style being edited.
|
|
278
|
+
key: (_c = (_b = styleEditor.style) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : "", style: styleEditor.style, defaultName: "Table Style ".concat(allCustomStyles.length + 1), existingNames: allCustomStyles.map(function (style) { return style.name; }), theme: theme, onSubmit: onSubmitStyle, onCancel: function () { return setStyleEditor(null); }, onDelete: styleEditor.style &&
|
|
279
|
+
(isSessionStyle(styleEditor.style) ||
|
|
280
|
+
onDeleteCustomTableStyle)
|
|
281
|
+
? onDeleteStyle
|
|
282
|
+
: undefined })) : (react_1.default.createElement(ui_1.DropdownMenuItem, { className: "text-xs",
|
|
283
|
+
// Keep the menu open: the editor replaces this item in place.
|
|
258
284
|
onSelect: function (event) {
|
|
259
285
|
event.preventDefault();
|
|
260
|
-
|
|
286
|
+
setStyleEditor({});
|
|
261
287
|
} }, "New Table Style\u2026")),
|
|
262
|
-
|
|
288
|
+
styleEditor ? null : (
|
|
289
|
+
// Clear (no table style) belongs to the gallery, not to the style editor: while
|
|
290
|
+
// the editor is open its footer ends the panel.
|
|
291
|
+
react_1.default.createElement(ui_1.DropdownMenuItem, { className: "text-xs", onClick: function () { return onSelectStyle("None", undefined); }, onPointerEnter: function () { return previewStyle("None", undefined); }, onPointerLeave: clearPreview, onFocus: function () { return previewStyle("None", undefined); }, onBlur: clearPreview }, "Clear")))))));
|
|
263
292
|
});
|
|
264
|
-
/**
|
|
265
|
-
* "New Table Style…" — Excel's dialog reduced to the three elements the gallery swatches show:
|
|
266
|
-
* header, first banded row, second banded row. Inline in the gallery so the picked colours
|
|
267
|
-
* preview in the same place they will be offered.
|
|
268
|
-
*/
|
|
269
|
-
var NewTableStyleForm = function (_a) {
|
|
270
|
-
var defaultName = _a.defaultName, theme = _a.theme, onCreate = _a.onCreate, onCancel = _a.onCancel;
|
|
271
|
-
var _b = tslib_1.__read((0, react_1.useState)(defaultName), 2), name = _b[0], setName = _b[1];
|
|
272
|
-
var _c = tslib_1.__read((0, react_1.useState)("#4472c4"), 2), header = _c[0], setHeader = _c[1];
|
|
273
|
-
var _d = tslib_1.__read((0, react_1.useState)("#b4c6e7"), 2), firstBand = _d[0], setFirstBand = _d[1];
|
|
274
|
-
var _e = tslib_1.__read((0, react_1.useState)("#ffffff"), 2), secondBand = _e[0], setSecondBand = _e[1];
|
|
275
|
-
var preview = (0, react_1.useMemo)(function () { return (0, exports.buildCustomTableStyle)(name, { header: header, firstBand: firstBand, secondBand: secondBand }); }, [name, header, firstBand, secondBand]);
|
|
276
|
-
var rows = [
|
|
277
|
-
["Header Row", header, setHeader],
|
|
278
|
-
["First Row Stripe", firstBand, setFirstBand],
|
|
279
|
-
["Second Row Stripe", secondBand, setSecondBand],
|
|
280
|
-
];
|
|
281
|
-
return (react_1.default.createElement("form", { "data-testid": "new-table-style-form", className: "m-0 p-1 flex flex-col gap-2",
|
|
282
|
-
// The gallery is a Radix menu: keep typing in the fields from driving its typeahead.
|
|
283
|
-
onKeyDown: function (event) { return event.stopPropagation(); }, onSubmit: function (event) {
|
|
284
|
-
event.preventDefault();
|
|
285
|
-
if (name.trim()) {
|
|
286
|
-
onCreate((0, exports.buildCustomTableStyle)(name.trim(), { header: header, firstBand: firstBand, secondBand: secondBand }));
|
|
287
|
-
}
|
|
288
|
-
} },
|
|
289
|
-
react_1.default.createElement("div", { className: "flex items-center gap-2" },
|
|
290
|
-
react_1.default.createElement("label", { className: "font-system text-xs w-24", htmlFor: "rnc-new-table-style-name" }, "Name"),
|
|
291
|
-
react_1.default.createElement(ui_1.Input, { id: "rnc-new-table-style-name", value: name, onChange: function (event) { return setName(event.target.value); }, required: true }),
|
|
292
|
-
react_1.default.createElement(TableSkeleton, { rowProperties: preview.bandedRange.rowProperties, theme: theme })),
|
|
293
|
-
rows.map(function (_a) {
|
|
294
|
-
var _b = tslib_1.__read(_a, 3), label = _b[0], value = _b[1], setValue = _b[2];
|
|
295
|
-
return (react_1.default.createElement("div", { className: "flex items-center gap-2", key: label },
|
|
296
|
-
react_1.default.createElement("span", { className: "font-system text-xs w-24" }, label),
|
|
297
|
-
react_1.default.createElement(ui_1.ColorPicker, { colors: NEW_STYLE_COLORS, value: value, onChange: setValue, size: 14, className: "flex-wrap", direction: "horizontal" })));
|
|
298
|
-
}),
|
|
299
|
-
react_1.default.createElement("div", { className: "flex gap-1" },
|
|
300
|
-
react_1.default.createElement(ui_1.Button, { type: "submit", variant: "primary", size: "xs", disabled: !name.trim() }, "Create"),
|
|
301
|
-
react_1.default.createElement(ui_1.Button, { size: "xs", type: "button", onClick: onCancel }, "Cancel"))));
|
|
302
|
-
};
|
|
303
293
|
/**
|
|
304
294
|
* Table skeleton
|
|
305
295
|
* @param param0
|