hs-uix 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -0
- package/common-components.d.ts +127 -0
- package/dist/common-components.js +491 -16
- package/dist/common-components.mjs +465 -10
- package/dist/form.js +18 -1
- package/dist/form.mjs +18 -1
- package/dist/index.js +1743 -15
- package/dist/index.mjs +1753 -14
- package/dist/kanban.js +1410 -0
- package/dist/kanban.mjs +1408 -0
- package/dist/utils.js +60 -0
- package/dist/utils.mjs +58 -0
- package/form.d.ts +1 -0
- package/index.d.ts +65 -0
- package/kanban.d.ts +1 -0
- package/package.json +7 -1
|
@@ -156,12 +156,189 @@ var AutoStatusTag = ({
|
|
|
156
156
|
);
|
|
157
157
|
};
|
|
158
158
|
|
|
159
|
-
// src/common-components/
|
|
159
|
+
// src/common-components/AvatarStack.js
|
|
160
160
|
import React3 from "react";
|
|
161
|
+
import { Image } from "@hubspot/ui-extensions";
|
|
162
|
+
|
|
163
|
+
// src/common-components/svgDefaults.js
|
|
164
|
+
var HS_FONT_FAMILY = '"Lexend Deca", Helvetica, Arial, sans-serif';
|
|
165
|
+
var HS_TEXT_COLOR = "#33475b";
|
|
166
|
+
var HS_SUBTLE_BG = "#F5F8FA";
|
|
167
|
+
var HS_MUTED_TEXT = "#7C98B6";
|
|
168
|
+
var HS_NEUTRAL_CHIP = "#CBD6E2";
|
|
169
|
+
var HS_TAG_SUBTLE_BORDER = "#7C98B6";
|
|
170
|
+
var HS_TAG_TEXT_COLOR = HS_TEXT_COLOR;
|
|
171
|
+
var HS_TAG_FONT_SIZE = 12;
|
|
172
|
+
var HS_TAG_LINE_HEIGHT = 22;
|
|
173
|
+
var HS_TAG_PADDING_X = 8;
|
|
174
|
+
var HS_TAG_PADDING_Y = 0;
|
|
175
|
+
var HS_TAG_BORDER_RADIUS = 0;
|
|
176
|
+
var HS_TAG_BORDER_WIDTH = 1;
|
|
177
|
+
var DEFAULT_SVG_FONT_WEIGHT = 600;
|
|
178
|
+
|
|
179
|
+
// src/common-components/AvatarStack.js
|
|
180
|
+
var DEFAULT_COLORS = [
|
|
181
|
+
"#0091ae",
|
|
182
|
+
"#8B0000",
|
|
183
|
+
"#ff5c35",
|
|
184
|
+
"#00bda5",
|
|
185
|
+
"#fdcc00",
|
|
186
|
+
"#516f90",
|
|
187
|
+
"#003366",
|
|
188
|
+
"#8e7cc3"
|
|
189
|
+
];
|
|
190
|
+
var SIZE_TOKENS = {
|
|
191
|
+
xs: 16,
|
|
192
|
+
"extra-small": 16,
|
|
193
|
+
sm: 20,
|
|
194
|
+
"small": 20,
|
|
195
|
+
md: 24,
|
|
196
|
+
"med": 24,
|
|
197
|
+
"medium": 24,
|
|
198
|
+
lg: 32,
|
|
199
|
+
"large": 32,
|
|
200
|
+
xl: 40,
|
|
201
|
+
"extra-large": 40
|
|
202
|
+
};
|
|
203
|
+
var resolveSize = (size) => {
|
|
204
|
+
if (typeof size === "number") return size;
|
|
205
|
+
if (typeof size === "string" && SIZE_TOKENS[size] != null) return SIZE_TOKENS[size];
|
|
206
|
+
return 24;
|
|
207
|
+
};
|
|
208
|
+
var isImageUri = (s) => typeof s === "string" && /^(https?:|data:image\/)/i.test(s);
|
|
209
|
+
var escapeXmlAttr = (s) => String(s).replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
210
|
+
var pickColor = (key, palette, index) => {
|
|
211
|
+
if (!key) return palette[index % palette.length];
|
|
212
|
+
const code = String(key).charCodeAt(0) || 0;
|
|
213
|
+
return palette[(code + index) % palette.length];
|
|
214
|
+
};
|
|
215
|
+
var normalizeEntry = (entry) => {
|
|
216
|
+
if (entry == null) return null;
|
|
217
|
+
if (typeof entry === "string") {
|
|
218
|
+
if (entry.length === 0) return null;
|
|
219
|
+
if (isImageUri(entry)) return { src: entry };
|
|
220
|
+
return { letter: entry.slice(0, 2).toUpperCase() };
|
|
221
|
+
}
|
|
222
|
+
if (typeof entry === "object") {
|
|
223
|
+
if (entry.src) return { src: entry.src, letter: entry.letter };
|
|
224
|
+
if (entry.letter) return { letter: String(entry.letter).slice(0, 2).toUpperCase(), color: entry.color };
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
};
|
|
228
|
+
var makeAvatarStackDataUri = (rawEntries, opts = {}) => {
|
|
229
|
+
const {
|
|
230
|
+
size: sizeProp = "medium",
|
|
231
|
+
step: stepProp,
|
|
232
|
+
overlap: overlapProp,
|
|
233
|
+
maxVisible = 4,
|
|
234
|
+
colors = DEFAULT_COLORS,
|
|
235
|
+
overflowBg = HS_NEUTRAL_CHIP,
|
|
236
|
+
overflowColor = HS_TEXT_COLOR,
|
|
237
|
+
fontFamily = HS_FONT_FAMILY
|
|
238
|
+
} = opts;
|
|
239
|
+
const size = resolveSize(sizeProp);
|
|
240
|
+
let step;
|
|
241
|
+
if (stepProp != null) {
|
|
242
|
+
step = stepProp;
|
|
243
|
+
} else if (overlapProp != null) {
|
|
244
|
+
const clampedOverlap = Math.max(0, Math.min(size - 1, overlapProp));
|
|
245
|
+
step = size - clampedOverlap;
|
|
246
|
+
} else {
|
|
247
|
+
step = Math.round(size * 0.65);
|
|
248
|
+
}
|
|
249
|
+
const entries = (rawEntries || []).map(normalizeEntry).filter(Boolean);
|
|
250
|
+
if (entries.length === 0) return null;
|
|
251
|
+
const visible = entries.slice(0, maxVisible);
|
|
252
|
+
const overflowCount = entries.length - visible.length;
|
|
253
|
+
const slots = overflowCount > 0 ? [...entries.slice(0, maxVisible - 1), { overflow: overflowCount }] : visible;
|
|
254
|
+
const count = slots.length;
|
|
255
|
+
const r = size / 2;
|
|
256
|
+
const haloR = r + 1;
|
|
257
|
+
const width = size + (count - 1) * step;
|
|
258
|
+
const height = size;
|
|
259
|
+
const defs = `<defs><clipPath id="hsuixAvatarClip"><circle cx="${r}" cy="${r}" r="${r}"/></clipPath></defs>`;
|
|
260
|
+
const fontFamilyAttr = fontFamily.replace(/"/g, """);
|
|
261
|
+
const pieces = slots.map((slot, i) => {
|
|
262
|
+
const cx = r + i * step;
|
|
263
|
+
const tx = i * step;
|
|
264
|
+
const halo = i > 0 ? `<circle cx="${cx}" cy="${r}" r="${haloR}" fill="#ffffff" />` : "";
|
|
265
|
+
if (slot.overflow) {
|
|
266
|
+
return halo + `<circle cx="${cx}" cy="${r}" r="${r}" fill="${overflowBg}" /><text x="${cx}" y="${r + 1}" text-anchor="middle" dominant-baseline="central" font-family="${fontFamilyAttr}" font-size="${Math.round(size * 0.42)}" font-weight="700" fill="${overflowColor}">+${slot.overflow}</text>`;
|
|
267
|
+
}
|
|
268
|
+
if (slot.src) {
|
|
269
|
+
return halo + `<g transform="translate(${tx}, 0)"><image href="${escapeXmlAttr(slot.src)}" x="0" y="0" width="${size}" height="${size}" preserveAspectRatio="xMidYMid slice" clip-path="url(#hsuixAvatarClip)" /></g>`;
|
|
270
|
+
}
|
|
271
|
+
const letter = slot.letter || "?";
|
|
272
|
+
const bgColor = slot.color || pickColor(letter, colors, i);
|
|
273
|
+
return halo + `<circle cx="${cx}" cy="${r}" r="${r}" fill="${bgColor}" /><text x="${cx}" y="${r + 1}" text-anchor="middle" dominant-baseline="central" font-family="${fontFamilyAttr}" font-size="${Math.round(size * 0.46)}" font-weight="700" fill="#ffffff">${escapeXmlAttr(letter)}</text>`;
|
|
274
|
+
});
|
|
275
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${width}" height="${height}">` + defs + pieces.join("") + `</svg>`;
|
|
276
|
+
return {
|
|
277
|
+
src: `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`,
|
|
278
|
+
width,
|
|
279
|
+
height,
|
|
280
|
+
count
|
|
281
|
+
};
|
|
282
|
+
};
|
|
283
|
+
var AvatarStack = ({
|
|
284
|
+
items,
|
|
285
|
+
size,
|
|
286
|
+
overlap,
|
|
287
|
+
step,
|
|
288
|
+
maxVisible,
|
|
289
|
+
colors,
|
|
290
|
+
overflowBg,
|
|
291
|
+
overflowColor,
|
|
292
|
+
fontFamily,
|
|
293
|
+
alt
|
|
294
|
+
}) => {
|
|
295
|
+
const stack = makeAvatarStackDataUri(items, {
|
|
296
|
+
size,
|
|
297
|
+
overlap,
|
|
298
|
+
step,
|
|
299
|
+
maxVisible,
|
|
300
|
+
colors,
|
|
301
|
+
overflowBg,
|
|
302
|
+
overflowColor,
|
|
303
|
+
fontFamily
|
|
304
|
+
});
|
|
305
|
+
if (!stack) return null;
|
|
306
|
+
return React3.createElement(Image, {
|
|
307
|
+
src: stack.src,
|
|
308
|
+
width: stack.width,
|
|
309
|
+
height: stack.height,
|
|
310
|
+
alt: alt ?? `${items.length} associated records`
|
|
311
|
+
});
|
|
312
|
+
};
|
|
313
|
+
|
|
314
|
+
// src/common-components/datePresets.js
|
|
315
|
+
var HS_DATE_PRESETS = [
|
|
316
|
+
{ label: "Today", value: "today" },
|
|
317
|
+
{ label: "Yesterday", value: "yesterday" },
|
|
318
|
+
{ label: "Tomorrow", value: "tomorrow" },
|
|
319
|
+
{ label: "This week", value: "this_week" },
|
|
320
|
+
{ label: "Last week", value: "last_week" },
|
|
321
|
+
{ label: "Last 7 days", value: "7d" },
|
|
322
|
+
{ label: "Last 30 days", value: "30d" },
|
|
323
|
+
{ label: "Last 90 days", value: "90d" },
|
|
324
|
+
{ label: "This month", value: "this_month" },
|
|
325
|
+
{ label: "Last month", value: "last_month" },
|
|
326
|
+
{ label: "This quarter", value: "this_quarter" },
|
|
327
|
+
{ label: "Last quarter", value: "last_quarter" },
|
|
328
|
+
{ label: "This year", value: "this_year" },
|
|
329
|
+
{ label: "Last year", value: "last_year" }
|
|
330
|
+
];
|
|
331
|
+
var HS_DATE_DIRECTION_LABELS = {
|
|
332
|
+
asc: "Ascending",
|
|
333
|
+
desc: "Descending"
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
// src/common-components/KeyValueList.js
|
|
337
|
+
import React4 from "react";
|
|
161
338
|
import { DescriptionList, DescriptionListItem, Flex } from "@hubspot/ui-extensions";
|
|
162
339
|
var KeyValueList = ({ items = [], direction = "row", gap = "sm" }) => {
|
|
163
340
|
const rows = items.map(
|
|
164
|
-
(item, index) =>
|
|
341
|
+
(item, index) => React4.createElement(
|
|
165
342
|
DescriptionListItem,
|
|
166
343
|
{
|
|
167
344
|
key: item.key ?? item.label ?? `kv-${index}`,
|
|
@@ -170,15 +347,15 @@ var KeyValueList = ({ items = [], direction = "row", gap = "sm" }) => {
|
|
|
170
347
|
item.value
|
|
171
348
|
)
|
|
172
349
|
);
|
|
173
|
-
return
|
|
350
|
+
return React4.createElement(
|
|
174
351
|
Flex,
|
|
175
352
|
{ direction: "column", gap },
|
|
176
|
-
|
|
353
|
+
React4.createElement(DescriptionList, { direction }, ...rows)
|
|
177
354
|
);
|
|
178
355
|
};
|
|
179
356
|
|
|
180
357
|
// src/common-components/SectionHeader.js
|
|
181
|
-
import
|
|
358
|
+
import React5 from "react";
|
|
182
359
|
import { Flex as Flex2, Heading, Text } from "@hubspot/ui-extensions";
|
|
183
360
|
var SectionHeader = ({
|
|
184
361
|
title,
|
|
@@ -190,11 +367,11 @@ var SectionHeader = ({
|
|
|
190
367
|
}) => {
|
|
191
368
|
const body = [];
|
|
192
369
|
if (title != null) {
|
|
193
|
-
body.push(
|
|
370
|
+
body.push(React5.createElement(Heading, { key: "title", as: titleAs }, title));
|
|
194
371
|
}
|
|
195
372
|
if (description != null) {
|
|
196
373
|
body.push(
|
|
197
|
-
|
|
374
|
+
React5.createElement(
|
|
198
375
|
Text,
|
|
199
376
|
{ key: "description", variant: "microcopy" },
|
|
200
377
|
description
|
|
@@ -204,18 +381,296 @@ var SectionHeader = ({
|
|
|
204
381
|
if (children != null) {
|
|
205
382
|
body.push(children);
|
|
206
383
|
}
|
|
207
|
-
const content =
|
|
384
|
+
const content = React5.createElement(Flex2, { direction: "column", gap }, ...body);
|
|
208
385
|
if (actions == null) return content;
|
|
209
|
-
return
|
|
386
|
+
return React5.createElement(
|
|
210
387
|
Flex2,
|
|
211
388
|
{ direction: "row", justify: "between", align: "start", gap: "sm" },
|
|
212
389
|
content,
|
|
213
390
|
actions
|
|
214
391
|
);
|
|
215
392
|
};
|
|
393
|
+
|
|
394
|
+
// src/common-components/StyledText.js
|
|
395
|
+
import React6 from "react";
|
|
396
|
+
import { Image as Image2, Tag as Tag2 } from "@hubspot/ui-extensions";
|
|
397
|
+
var VARIANT_PRESETS = {
|
|
398
|
+
bodytext: { fontSize: 14, lineHeight: 24, fontWeight: 400 },
|
|
399
|
+
microcopy: { fontSize: 12, lineHeight: 18, fontWeight: 400 }
|
|
400
|
+
};
|
|
401
|
+
var WEIGHT_ALIASES = {
|
|
402
|
+
bold: 700,
|
|
403
|
+
demibold: 600,
|
|
404
|
+
regular: 400
|
|
405
|
+
};
|
|
406
|
+
var LINE_DECORATION = {
|
|
407
|
+
strikethrough: "line-through",
|
|
408
|
+
underline: "underline"
|
|
409
|
+
};
|
|
410
|
+
var ORIENTATION_ROTATION = {
|
|
411
|
+
horizontal: 0,
|
|
412
|
+
"vertical-up": -90,
|
|
413
|
+
"vertical-down": 90
|
|
414
|
+
};
|
|
415
|
+
var BACKGROUND_PRESETS = {
|
|
416
|
+
tag: {
|
|
417
|
+
color: HS_SUBTLE_BG,
|
|
418
|
+
borderColor: HS_TAG_SUBTLE_BORDER,
|
|
419
|
+
borderWidth: HS_TAG_BORDER_WIDTH,
|
|
420
|
+
radius: HS_TAG_BORDER_RADIUS,
|
|
421
|
+
paddingX: HS_TAG_PADDING_X,
|
|
422
|
+
paddingY: HS_TAG_PADDING_Y,
|
|
423
|
+
height: HS_TAG_LINE_HEIGHT,
|
|
424
|
+
textColor: HS_TAG_TEXT_COLOR,
|
|
425
|
+
fontSize: HS_TAG_FONT_SIZE,
|
|
426
|
+
canvasPaddingX: 0,
|
|
427
|
+
canvasPaddingY: 0
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
var TAG_VARIANTS = {
|
|
431
|
+
default: {
|
|
432
|
+
color: HS_SUBTLE_BG,
|
|
433
|
+
borderColor: HS_TAG_SUBTLE_BORDER,
|
|
434
|
+
textColor: HS_TAG_TEXT_COLOR
|
|
435
|
+
},
|
|
436
|
+
success: {
|
|
437
|
+
color: "#E5F8F6",
|
|
438
|
+
borderColor: "#00BDA5",
|
|
439
|
+
textColor: "#00BDA5"
|
|
440
|
+
},
|
|
441
|
+
warning: {
|
|
442
|
+
color: "#FEF8F0",
|
|
443
|
+
borderColor: "#F5C26B",
|
|
444
|
+
textColor: "#D39913"
|
|
445
|
+
},
|
|
446
|
+
error: {
|
|
447
|
+
color: "#FDEDEE",
|
|
448
|
+
borderColor: "#F2545B",
|
|
449
|
+
textColor: "#F2545B"
|
|
450
|
+
},
|
|
451
|
+
danger: {
|
|
452
|
+
color: "#FDEDEE",
|
|
453
|
+
borderColor: "#F2545B",
|
|
454
|
+
textColor: "#F2545B"
|
|
455
|
+
},
|
|
456
|
+
info: {
|
|
457
|
+
color: "#E5F5F8",
|
|
458
|
+
borderColor: "#00A4BD",
|
|
459
|
+
textColor: "#00A4BD"
|
|
460
|
+
}
|
|
461
|
+
};
|
|
462
|
+
var NATIVE_TAG_VARIANT_ALIASES = {
|
|
463
|
+
danger: "error"
|
|
464
|
+
};
|
|
465
|
+
var escapeSvgText = (s) => String(s).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
466
|
+
var applyTextTransform = (text, transform) => {
|
|
467
|
+
if (!transform || transform === "none") return String(text);
|
|
468
|
+
const s = String(text);
|
|
469
|
+
switch (transform) {
|
|
470
|
+
case "uppercase":
|
|
471
|
+
return s.toUpperCase();
|
|
472
|
+
case "lowercase":
|
|
473
|
+
return s.toLowerCase();
|
|
474
|
+
case "capitalize":
|
|
475
|
+
return s.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
476
|
+
case "sentenceCase":
|
|
477
|
+
return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
|
|
478
|
+
default:
|
|
479
|
+
return s;
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
var estimateTextWidth = (text, fontSize) => Math.max(fontSize, Math.round(String(text).length * fontSize * 0.58));
|
|
483
|
+
var resolveBackground = (background) => {
|
|
484
|
+
if (!background) return null;
|
|
485
|
+
const preset = background.preset ? BACKGROUND_PRESETS[background.preset] : null;
|
|
486
|
+
const variant = background.preset === "tag" && background.variant ? TAG_VARIANTS[background.variant] || null : null;
|
|
487
|
+
return {
|
|
488
|
+
...preset || {},
|
|
489
|
+
...variant || {},
|
|
490
|
+
...background
|
|
491
|
+
};
|
|
492
|
+
};
|
|
493
|
+
var buildBackgroundRect = ({ background, x, y, width, height }) => {
|
|
494
|
+
const radius = (background == null ? void 0 : background.radius) ?? 3;
|
|
495
|
+
const fill = (background == null ? void 0 : background.color) ?? "transparent";
|
|
496
|
+
const borderWidth = (background == null ? void 0 : background.borderWidth) ?? 0;
|
|
497
|
+
const borderColor = background == null ? void 0 : background.borderColor;
|
|
498
|
+
if (!borderColor || borderWidth <= 0) {
|
|
499
|
+
return `<rect x="${x}" y="${y}" width="${width}" height="${height}" rx="${radius}" fill="${fill}" />`;
|
|
500
|
+
}
|
|
501
|
+
const isTagPreset = (background == null ? void 0 : background.preset) === "tag";
|
|
502
|
+
const fillRect = `<rect x="${x}" y="${y}" width="${width}" height="${height}" rx="${radius}" fill="${fill}" />`;
|
|
503
|
+
const strokeInset = borderWidth / 2;
|
|
504
|
+
const strokeX = x + strokeInset;
|
|
505
|
+
const strokeY = y + strokeInset;
|
|
506
|
+
const strokeW = Math.max(0, width - borderWidth);
|
|
507
|
+
const strokeH = Math.max(0, height - borderWidth);
|
|
508
|
+
return fillRect + `<rect x="${strokeX}" y="${strokeY}" width="${strokeW}" height="${strokeH}" rx="${Math.max(
|
|
509
|
+
0,
|
|
510
|
+
radius - strokeInset
|
|
511
|
+
)}" fill="none" stroke="${borderColor}" stroke-width="${borderWidth}"${isTagPreset ? ` shape-rendering="crispEdges"` : ""} />`;
|
|
512
|
+
};
|
|
513
|
+
var canUseNativeTag = ({
|
|
514
|
+
background,
|
|
515
|
+
orientation,
|
|
516
|
+
color,
|
|
517
|
+
fontFamily,
|
|
518
|
+
fontSize,
|
|
519
|
+
width,
|
|
520
|
+
height,
|
|
521
|
+
paddingX,
|
|
522
|
+
paddingY,
|
|
523
|
+
format = {}
|
|
524
|
+
}) => {
|
|
525
|
+
if (!background || background.preset !== "tag") return false;
|
|
526
|
+
const resolvedOrientation = typeof orientation === "number" ? orientation : ORIENTATION_ROTATION[orientation ?? "horizontal"] ?? 0;
|
|
527
|
+
if (resolvedOrientation !== 0) return false;
|
|
528
|
+
if (color != null || fontFamily != null || fontSize != null) return false;
|
|
529
|
+
if (width != null || height != null || paddingX != null || paddingY != null) return false;
|
|
530
|
+
if (background.color != null || background.textColor != null) return false;
|
|
531
|
+
if (background.borderColor != null || background.borderWidth != null) return false;
|
|
532
|
+
if (background.radius != null || background.height != null) return false;
|
|
533
|
+
if (background.paddingX != null || background.paddingY != null) return false;
|
|
534
|
+
if (background.canvasPaddingX != null || background.canvasPaddingY != null) return false;
|
|
535
|
+
if (format.italic || format.lineDecoration) return false;
|
|
536
|
+
if (format.textTransform && format.textTransform !== "none") return false;
|
|
537
|
+
return true;
|
|
538
|
+
};
|
|
539
|
+
var makeStyledTextDataUri = (text, opts = {}) => {
|
|
540
|
+
const {
|
|
541
|
+
variant = "bodytext",
|
|
542
|
+
format = {},
|
|
543
|
+
orientation = "horizontal",
|
|
544
|
+
color: colorProp = HS_TEXT_COLOR,
|
|
545
|
+
fontFamily = HS_FONT_FAMILY,
|
|
546
|
+
background: backgroundProp = null,
|
|
547
|
+
paddingX: paddingXProp = 4,
|
|
548
|
+
paddingY: paddingYProp = 2,
|
|
549
|
+
width: widthOverride,
|
|
550
|
+
height: heightOverride,
|
|
551
|
+
fontSize: fontSizeOverride
|
|
552
|
+
} = opts;
|
|
553
|
+
const preset = VARIANT_PRESETS[variant] || VARIANT_PRESETS.bodytext;
|
|
554
|
+
const background = resolveBackground(backgroundProp);
|
|
555
|
+
const fontSize = fontSizeOverride ?? (background == null ? void 0 : background.fontSize) ?? preset.fontSize;
|
|
556
|
+
const rawWeight = format.fontWeight;
|
|
557
|
+
const fontWeight = rawWeight ? WEIGHT_ALIASES[rawWeight] ?? rawWeight : preset.fontWeight;
|
|
558
|
+
const fontStyle = format.italic ? "italic" : "normal";
|
|
559
|
+
const textDecoration = LINE_DECORATION[format.lineDecoration] || "none";
|
|
560
|
+
const transformed = applyTextTransform(text, format.textTransform);
|
|
561
|
+
const lineHeight = (background == null ? void 0 : background.height) ?? preset.lineHeight ?? fontSize;
|
|
562
|
+
const color = (background == null ? void 0 : background.textColor) ?? colorProp;
|
|
563
|
+
const paddingX = (background == null ? void 0 : background.canvasPaddingX) ?? paddingXProp;
|
|
564
|
+
const paddingY = (background == null ? void 0 : background.canvasPaddingY) ?? paddingYProp;
|
|
565
|
+
const rotate = typeof orientation === "number" ? orientation : ORIENTATION_ROTATION[orientation] ?? 0;
|
|
566
|
+
const textW = estimateTextWidth(transformed, fontSize);
|
|
567
|
+
let pillW = 0;
|
|
568
|
+
let pillH = 0;
|
|
569
|
+
if (background) {
|
|
570
|
+
const bgPadX = background.paddingX ?? 6;
|
|
571
|
+
const bgPadY = background.paddingY ?? 3;
|
|
572
|
+
pillW = textW + bgPadX * 2;
|
|
573
|
+
pillH = background.height ?? Math.max(lineHeight, fontSize + bgPadY * 2);
|
|
574
|
+
}
|
|
575
|
+
const intrinsicW = (background ? pillW : textW) + paddingX * 2;
|
|
576
|
+
const intrinsicH = (background ? pillH : lineHeight) + paddingY * 2;
|
|
577
|
+
const isOrthoRotation = rotate === 90 || rotate === -90 || rotate === 270;
|
|
578
|
+
const canvasW = widthOverride ?? (isOrthoRotation ? intrinsicH : intrinsicW);
|
|
579
|
+
const canvasH = heightOverride ?? (isOrthoRotation ? intrinsicW : intrinsicH);
|
|
580
|
+
const cx = canvasW / 2;
|
|
581
|
+
const cy = canvasH / 2;
|
|
582
|
+
const rectX = cx - pillW / 2;
|
|
583
|
+
const rectY = cy - pillH / 2;
|
|
584
|
+
const group = (background ? buildBackgroundRect({
|
|
585
|
+
background,
|
|
586
|
+
x: rectX,
|
|
587
|
+
y: rectY,
|
|
588
|
+
width: pillW,
|
|
589
|
+
height: pillH
|
|
590
|
+
}) : "") + `<text x="${cx}" y="${cy}" text-anchor="middle" dominant-baseline="central" font-family="${fontFamily.replace(/"/g, """)}" font-size="${fontSize}" font-weight="${fontWeight}" font-style="${fontStyle}" text-decoration="${textDecoration}" fill="${color}">${escapeSvgText(transformed)}</text>`;
|
|
591
|
+
const wrapped = rotate ? `<g transform="rotate(${rotate} ${cx} ${cy})">${group}</g>` : group;
|
|
592
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${canvasW}" height="${canvasH}">` + wrapped + `</svg>`;
|
|
593
|
+
return {
|
|
594
|
+
src: `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`,
|
|
595
|
+
width: canvasW,
|
|
596
|
+
height: canvasH
|
|
597
|
+
};
|
|
598
|
+
};
|
|
599
|
+
var StyledText = ({
|
|
600
|
+
children,
|
|
601
|
+
text,
|
|
602
|
+
alt,
|
|
603
|
+
variant,
|
|
604
|
+
format,
|
|
605
|
+
orientation,
|
|
606
|
+
color,
|
|
607
|
+
background,
|
|
608
|
+
fontFamily,
|
|
609
|
+
fontSize,
|
|
610
|
+
paddingX,
|
|
611
|
+
paddingY,
|
|
612
|
+
width,
|
|
613
|
+
height
|
|
614
|
+
}) => {
|
|
615
|
+
const resolvedText = text ?? (typeof children === "string" ? children : "");
|
|
616
|
+
if (canUseNativeTag({
|
|
617
|
+
background,
|
|
618
|
+
orientation,
|
|
619
|
+
color,
|
|
620
|
+
fontFamily,
|
|
621
|
+
fontSize,
|
|
622
|
+
width,
|
|
623
|
+
height,
|
|
624
|
+
paddingX,
|
|
625
|
+
paddingY,
|
|
626
|
+
format
|
|
627
|
+
})) {
|
|
628
|
+
const nativeVariant = NATIVE_TAG_VARIANT_ALIASES[background == null ? void 0 : background.variant] ?? (background == null ? void 0 : background.variant) ?? "default";
|
|
629
|
+
return React6.createElement(Tag2, { variant: nativeVariant }, resolvedText);
|
|
630
|
+
}
|
|
631
|
+
const { src, width: w, height: h } = makeStyledTextDataUri(resolvedText, {
|
|
632
|
+
variant,
|
|
633
|
+
format,
|
|
634
|
+
orientation,
|
|
635
|
+
color,
|
|
636
|
+
background,
|
|
637
|
+
fontFamily,
|
|
638
|
+
fontSize,
|
|
639
|
+
paddingX,
|
|
640
|
+
paddingY,
|
|
641
|
+
width,
|
|
642
|
+
height
|
|
643
|
+
});
|
|
644
|
+
return React6.createElement(Image2, {
|
|
645
|
+
src,
|
|
646
|
+
width: w,
|
|
647
|
+
height: h,
|
|
648
|
+
alt: alt ?? String(resolvedText)
|
|
649
|
+
});
|
|
650
|
+
};
|
|
216
651
|
export {
|
|
217
652
|
AutoStatusTag,
|
|
218
653
|
AutoTag,
|
|
654
|
+
AvatarStack,
|
|
655
|
+
DEFAULT_SVG_FONT_WEIGHT,
|
|
656
|
+
HS_DATE_DIRECTION_LABELS,
|
|
657
|
+
HS_DATE_PRESETS,
|
|
658
|
+
HS_FONT_FAMILY,
|
|
659
|
+
HS_MUTED_TEXT,
|
|
660
|
+
HS_NEUTRAL_CHIP,
|
|
661
|
+
HS_SUBTLE_BG,
|
|
662
|
+
HS_TAG_BORDER_RADIUS,
|
|
663
|
+
HS_TAG_BORDER_WIDTH,
|
|
664
|
+
HS_TAG_FONT_SIZE,
|
|
665
|
+
HS_TAG_LINE_HEIGHT,
|
|
666
|
+
HS_TAG_PADDING_X,
|
|
667
|
+
HS_TAG_PADDING_Y,
|
|
668
|
+
HS_TAG_SUBTLE_BORDER,
|
|
669
|
+
HS_TAG_TEXT_COLOR,
|
|
670
|
+
HS_TEXT_COLOR,
|
|
219
671
|
KeyValueList,
|
|
220
|
-
SectionHeader
|
|
672
|
+
SectionHeader,
|
|
673
|
+
StyledText,
|
|
674
|
+
makeAvatarStackDataUri,
|
|
675
|
+
makeStyledTextDataUri
|
|
221
676
|
};
|
package/dist/form.js
CHANGED
|
@@ -2014,6 +2014,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2014
2014
|
}
|
|
2015
2015
|
};
|
|
2016
2016
|
const getFieldColSpan = (field) => {
|
|
2017
|
+
if (field.colSpan === "full") return columns;
|
|
2017
2018
|
if (field.colSpan != null) return Math.min(field.colSpan, columns);
|
|
2018
2019
|
if (field.width === "full" && columns > 1) return columns;
|
|
2019
2020
|
if (columns > 1 && (field.type === "display" || field.type === "slot" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return columns;
|
|
@@ -2039,6 +2040,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2039
2040
|
let currentRowSpan = 0;
|
|
2040
2041
|
const gridColumnWidth = 200;
|
|
2041
2042
|
const colSpan = (field) => {
|
|
2043
|
+
if (field.colSpan === "full") return cols;
|
|
2042
2044
|
if (field.colSpan != null) return Math.min(field.colSpan, cols);
|
|
2043
2045
|
if (field.width === "full" && cols > 1) return cols;
|
|
2044
2046
|
if (cols > 1 && (field.type === "display" || field.type === "slot" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return cols;
|
|
@@ -2172,8 +2174,16 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2172
2174
|
}
|
|
2173
2175
|
batch = [];
|
|
2174
2176
|
};
|
|
2177
|
+
const isFullSpan = (f) => f.colSpan === "full" || typeof f.colSpan === "number" && f.colSpan > 1;
|
|
2175
2178
|
for (const field of fieldList) {
|
|
2176
2179
|
if (isDependent(field)) continue;
|
|
2180
|
+
if (isFullSpan(field)) {
|
|
2181
|
+
flushBatch();
|
|
2182
|
+
elements.push(
|
|
2183
|
+
/* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, { key: `full-${field.name}` }, renderField(field))
|
|
2184
|
+
);
|
|
2185
|
+
continue;
|
|
2186
|
+
}
|
|
2177
2187
|
batch.push(field);
|
|
2178
2188
|
const dependents = getDependents(field);
|
|
2179
2189
|
if (dependents.length > 0) {
|
|
@@ -2185,6 +2195,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2185
2195
|
return elements;
|
|
2186
2196
|
};
|
|
2187
2197
|
const wrapWithGroups = (fieldList, renderFn) => {
|
|
2198
|
+
const formatGroupLabel = (groupName) => String(groupName || "").replace(/[_-]+/g, " ").replace(/\s+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
2188
2199
|
const hasGroups = fieldList.some((f) => f.group);
|
|
2189
2200
|
if (!hasGroups) return renderFn(fieldList);
|
|
2190
2201
|
const chunks = [];
|
|
@@ -2206,6 +2217,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2206
2217
|
for (let i = 0; i < chunks.length; i++) {
|
|
2207
2218
|
const chunk = chunks[i];
|
|
2208
2219
|
const opts = chunk.group && groups && groups[chunk.group] || {};
|
|
2220
|
+
const resolvedGroupLabel = opts.label || formatGroupLabel(chunk.group);
|
|
2209
2221
|
const showDivider = opts.showDivider !== false;
|
|
2210
2222
|
const showLabel = opts.showLabel !== false;
|
|
2211
2223
|
if (i > 0 && showDivider) {
|
|
@@ -2219,8 +2231,13 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2219
2231
|
);
|
|
2220
2232
|
} else {
|
|
2221
2233
|
elements.push(
|
|
2222
|
-
/* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Text, { key: `group-label-${i}`, format: { fontWeight: "demibold" } },
|
|
2234
|
+
/* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Text, { key: `group-label-${i}`, format: { fontWeight: "demibold" } }, resolvedGroupLabel)
|
|
2223
2235
|
);
|
|
2236
|
+
if (opts.description) {
|
|
2237
|
+
elements.push(
|
|
2238
|
+
/* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Text, { key: `group-description-${i}`, variant: "microcopy" }, opts.description)
|
|
2239
|
+
);
|
|
2240
|
+
}
|
|
2224
2241
|
}
|
|
2225
2242
|
}
|
|
2226
2243
|
const chunkElements = renderFn(chunk.fields);
|
package/dist/form.mjs
CHANGED
|
@@ -2018,6 +2018,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2018
2018
|
}
|
|
2019
2019
|
};
|
|
2020
2020
|
const getFieldColSpan = (field) => {
|
|
2021
|
+
if (field.colSpan === "full") return columns;
|
|
2021
2022
|
if (field.colSpan != null) return Math.min(field.colSpan, columns);
|
|
2022
2023
|
if (field.width === "full" && columns > 1) return columns;
|
|
2023
2024
|
if (columns > 1 && (field.type === "display" || field.type === "slot" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return columns;
|
|
@@ -2043,6 +2044,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2043
2044
|
let currentRowSpan = 0;
|
|
2044
2045
|
const gridColumnWidth = 200;
|
|
2045
2046
|
const colSpan = (field) => {
|
|
2047
|
+
if (field.colSpan === "full") return cols;
|
|
2046
2048
|
if (field.colSpan != null) return Math.min(field.colSpan, cols);
|
|
2047
2049
|
if (field.width === "full" && cols > 1) return cols;
|
|
2048
2050
|
if (cols > 1 && (field.type === "display" || field.type === "slot" || field.type === "crmPropertyList" || field.type === "crmAssociationPropertyList")) return cols;
|
|
@@ -2176,8 +2178,16 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2176
2178
|
}
|
|
2177
2179
|
batch = [];
|
|
2178
2180
|
};
|
|
2181
|
+
const isFullSpan = (f) => f.colSpan === "full" || typeof f.colSpan === "number" && f.colSpan > 1;
|
|
2179
2182
|
for (const field of fieldList) {
|
|
2180
2183
|
if (isDependent(field)) continue;
|
|
2184
|
+
if (isFullSpan(field)) {
|
|
2185
|
+
flushBatch();
|
|
2186
|
+
elements.push(
|
|
2187
|
+
/* @__PURE__ */ React.createElement(React.Fragment, { key: `full-${field.name}` }, renderField(field))
|
|
2188
|
+
);
|
|
2189
|
+
continue;
|
|
2190
|
+
}
|
|
2181
2191
|
batch.push(field);
|
|
2182
2192
|
const dependents = getDependents(field);
|
|
2183
2193
|
if (dependents.length > 0) {
|
|
@@ -2189,6 +2199,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2189
2199
|
return elements;
|
|
2190
2200
|
};
|
|
2191
2201
|
const wrapWithGroups = (fieldList, renderFn) => {
|
|
2202
|
+
const formatGroupLabel = (groupName) => String(groupName || "").replace(/[_-]+/g, " ").replace(/\s+/g, " ").trim().replace(/\b\w/g, (char) => char.toUpperCase());
|
|
2192
2203
|
const hasGroups = fieldList.some((f) => f.group);
|
|
2193
2204
|
if (!hasGroups) return renderFn(fieldList);
|
|
2194
2205
|
const chunks = [];
|
|
@@ -2210,6 +2221,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2210
2221
|
for (let i = 0; i < chunks.length; i++) {
|
|
2211
2222
|
const chunk = chunks[i];
|
|
2212
2223
|
const opts = chunk.group && groups && groups[chunk.group] || {};
|
|
2224
|
+
const resolvedGroupLabel = opts.label || formatGroupLabel(chunk.group);
|
|
2213
2225
|
const showDivider = opts.showDivider !== false;
|
|
2214
2226
|
const showLabel = opts.showLabel !== false;
|
|
2215
2227
|
if (i > 0 && showDivider) {
|
|
@@ -2223,8 +2235,13 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2223
2235
|
);
|
|
2224
2236
|
} else {
|
|
2225
2237
|
elements.push(
|
|
2226
|
-
/* @__PURE__ */ React.createElement(Text, { key: `group-label-${i}`, format: { fontWeight: "demibold" } },
|
|
2238
|
+
/* @__PURE__ */ React.createElement(Text, { key: `group-label-${i}`, format: { fontWeight: "demibold" } }, resolvedGroupLabel)
|
|
2227
2239
|
);
|
|
2240
|
+
if (opts.description) {
|
|
2241
|
+
elements.push(
|
|
2242
|
+
/* @__PURE__ */ React.createElement(Text, { key: `group-description-${i}`, variant: "microcopy" }, opts.description)
|
|
2243
|
+
);
|
|
2244
|
+
}
|
|
2228
2245
|
}
|
|
2229
2246
|
}
|
|
2230
2247
|
const chunkElements = renderFn(chunk.fields);
|