@activecollab/components 2.0.450 → 2.0.452

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/cjs/presentation/whiteboard/elements.js +146 -191
  2. package/dist/cjs/presentation/whiteboard/elements.js.map +1 -1
  3. package/dist/cjs/presentation/whiteboard/entityCardActions.js +4 -1
  4. package/dist/cjs/presentation/whiteboard/entityCardActions.js.map +1 -1
  5. package/dist/cjs/presentation/whiteboard/fileElement.js +2 -2
  6. package/dist/cjs/presentation/whiteboard/fileElement.js.map +1 -1
  7. package/dist/cjs/presentation/whiteboard/inspector.js +2 -2
  8. package/dist/cjs/presentation/whiteboard/inspector.js.map +1 -1
  9. package/dist/esm/presentation/whiteboard/elements.d.ts +5 -19
  10. package/dist/esm/presentation/whiteboard/elements.d.ts.map +1 -1
  11. package/dist/esm/presentation/whiteboard/elements.js +129 -168
  12. package/dist/esm/presentation/whiteboard/elements.js.map +1 -1
  13. package/dist/esm/presentation/whiteboard/entityCardActions.d.ts.map +1 -1
  14. package/dist/esm/presentation/whiteboard/entityCardActions.js +4 -1
  15. package/dist/esm/presentation/whiteboard/entityCardActions.js.map +1 -1
  16. package/dist/esm/presentation/whiteboard/fileElement.js +3 -3
  17. package/dist/esm/presentation/whiteboard/fileElement.js.map +1 -1
  18. package/dist/esm/presentation/whiteboard/inspector.js +3 -3
  19. package/dist/esm/presentation/whiteboard/inspector.js.map +1 -1
  20. package/package.json +1 -1
  21. package/dist/cjs/presentation/whiteboard/glyphs.js +0 -67
  22. package/dist/cjs/presentation/whiteboard/glyphs.js.map +0 -1
  23. package/dist/esm/presentation/whiteboard/glyphs.d.ts +0 -32
  24. package/dist/esm/presentation/whiteboard/glyphs.d.ts.map +0 -1
  25. package/dist/esm/presentation/whiteboard/glyphs.js +0 -50
  26. package/dist/esm/presentation/whiteboard/glyphs.js.map +0 -1
@@ -1,12 +1,13 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import React, { useState } from "react";
3
3
  import styled from "styled-components";
4
- import { MinusGlyph, PlusGlyph, SquareGlyph } from "./glyphs";
5
4
  import { Dot } from "../../components/Dot";
6
5
  import { IconButton } from "../../components/IconButton";
7
6
  import { ArrowRefreshIcon, CircleIcon, CircleSlashIcon, LockIcon, RoundedRectangleIcon, TextAlignCenterIcon, TextAlignJustifyIcon, TextAlignLeftIcon, TextAlignRightIcon, TextStyleBoldIcon, TextStyleItalicIcon, TextStyleStrikeIcon, TextStyleUnderlineIcon, TrashIcon, TriangleIcon } from "../../components/Icons";
8
7
  import { List, ListItem } from "../../components/List";
9
8
  import { Menu } from "../../components/Menu";
9
+ import { Select } from "../../components/Select";
10
+ import { SelectTrigger } from "../../components/SelectTrigger";
10
11
  import { Tooltip } from "../../components/Tooltip";
11
12
  import { colors } from "../../utils/colors";
12
13
 
@@ -24,9 +25,6 @@ export const ELEMENT_TEXT = "#1f2937";
24
25
  export const STICKY_FILL = "#fbbf24";
25
26
  export const SELECTION_BLUE = "#3b82f6";
26
27
 
27
- /* COLOR_PALETTE from toolbar/colorPalette.js (submenu swatch rows) */
28
- export const COLOR_PALETTE = ["#ffffff", "#3b82f6", "#ef4444", "#10b981", "#f59e0b", "#8b5cf6", "#f97316", "#06b6d4", "#84cc16", "#ec4899", "#6b7280"];
29
-
30
28
  /* Discrete option sets for the right Inspector — mirror the app's fixed
31
29
  font-size ladder and the border-thickness steps offered in the toolbar. */
32
30
  export const FONT_SIZE_OPTIONS = [10, 13, 16, 20, 24, 30, 36, 48, 72, 96, 144, 216, 288];
@@ -232,13 +230,17 @@ export const ResizeHandles = () => /*#__PURE__*/React.createElement(StyledHandle
232
230
  export const StyledFormattingToolbar = styled.div.withConfig({
233
231
  displayName: "elements__StyledFormattingToolbar",
234
232
  componentId: "sc-ohnju4-4"
235
- })(["position:absolute;bottom:calc(100% + 10px);left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:4px;padding:8px;border-radius:8px;background-color:var(--page-paper-main);box-shadow:var(--shadow-tertiary);white-space:nowrap;cursor:auto;z-index:20;.tb-group{position:relative;display:flex;align-items:center;gap:4px;padding-right:8px;margin-right:8px;border-right:1px solid var(--border-primary);}.tb-rel{position:relative;display:inline-flex;}.divider{width:1px;height:20px;background-color:var(--border-primary);margin:0 4px;flex-shrink:0;}"]);
233
+ })(["position:absolute;bottom:calc(100% + 10px);left:50%;transform:translateX(-50%);display:flex;align-items:center;gap:4px;padding:8px;border-radius:8px;background-color:var(--page-paper-main);box-shadow:var(--shadow-tertiary);white-space:nowrap;cursor:auto;z-index:20;.tb-group{position:relative;display:flex;align-items:center;gap:4px;padding-right:8px;margin-right:8px;border-right:1px solid var(--border-primary);}.tb-rel{position:relative;display:inline-flex;}.tb-color-value{display:inline-flex;align-items:center;justify-content:center;width:100%;}.divider{width:1px;height:20px;background-color:var(--border-primary);margin:0 4px;flex-shrink:0;}"]);
236
234
 
237
- /* Button variant="option" (idle) / "tertiary" (active), h-8 px-2 gap-1 */
235
+ /* The app's toolbar buttons are DS `Button` / `IconButton` variant="option",
236
+ size small, h-8 px-2: grey text (theme-700) that darkens on hover over a
237
+ theme-300 wash, and the primary colour only for a PRESSED state (an armed
238
+ lock, an active text style). Same palette here, so the story's bars read as
239
+ the app's and not as a row of links. */
238
240
  export const StyledToolbarButton = styled.button.withConfig({
239
241
  displayName: "elements__StyledToolbarButton",
240
242
  componentId: "sc-ohnju4-5"
241
- })(["display:inline-flex;align-items:center;justify-content:center;gap:4px;height:32px;box-sizing:border-box;padding:0 8px;border:0;border-radius:8px;background-color:transparent;color:var(--color-secondary);font-family:-apple-system,BlinkMacSystemFont,\"Roboto\",\"Helvetica Neue\",Arial,sans-serif;font-size:14px;cursor:pointer;&:hover{background-color:var(--color-theme-200);}&.active{background-color:var(--color-theme-300);}&.icon-only{width:32px;padding:0;}&:disabled{opacity:0.45;cursor:default;&:hover{background-color:transparent;}}svg{fill:currentColor;flex-shrink:0;}svg.i16{width:16px;height:16px;}svg.i12{width:12px;height:12px;}"]);
243
+ })(["display:inline-flex;align-items:center;justify-content:center;gap:4px;height:32px;box-sizing:border-box;padding:0 8px;border:0;border-radius:var(--ac-br-6);background-color:transparent;color:var(--color-theme-700);font-family:-apple-system,BlinkMacSystemFont,\"Roboto\",\"Helvetica Neue\",Arial,sans-serif;font-size:14px;font-weight:500;cursor:pointer;&:hover,&:focus-visible{background-color:var(--color-theme-300);color:var(--color-theme-900);}&.active,&.active:hover{color:var(--color-primary);}&.icon-only{width:32px;padding:0;}&:disabled{opacity:0.45;cursor:default;&:hover{background-color:transparent;}}svg{fill:currentColor;flex-shrink:0;}svg.i16{width:16px;height:16px;}svg.i12{width:12px;height:12px;}"]);
242
244
 
243
245
  /* Same chrome as a toolbar button, but an <a> — used where the action is a real
244
246
  navigation (Visit). `withComponent` keeps the styles and swaps the element, so
@@ -247,93 +249,27 @@ export const StyledToolbarLink = styled(StyledToolbarButton.withComponent("a")).
247
249
  displayName: "elements__StyledToolbarLink",
248
250
  componentId: "sc-ohnju4-6"
249
251
  })(["text-decoration:none;"]);
250
-
251
- /* font-mono min-w-[24px] text-xs readout between the stepper buttons */
252
- export const StyledFontSizeValue = styled.span.withConfig({
253
- displayName: "elements__StyledFontSizeValue",
254
- componentId: "sc-ohnju4-7"
255
- })(["min-width:24px;text-align:center;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--color-secondary);"]);
256
252
  export const stopClick = event => event.stopPropagation();
257
253
 
258
- /* Shared drop shadow for the colour swatch popover / colour wheel that the
259
- compact toolbar swatch trigger opens. */
260
- export const SUBMENU_SHADOW = "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1)";
261
-
262
- /* ColorWheelPopover: beside the submenu (SHAPE_POPOVER_CLASS) or below
263
- a toolbar trigger (sticky default class) */
264
- export const StyledColorPopover = styled.div.withConfig({
265
- displayName: "elements__StyledColorPopover",
266
- componentId: "sc-ohnju4-8"
267
- })(["position:absolute;box-sizing:border-box;padding:12px;background-color:var(--page-paper-main);border:1px solid var(--border-primary);border-radius:8px;box-shadow:", ";z-index:70;cursor:auto;&.beside{top:0;left:100%;margin-left:8px;}&.below{top:40px;left:0;}"], SUBMENU_SHADOW);
268
-
269
- /* ImprovedColorWheel: hue = angle from east (atan2), saturation = distance,
270
- lightness 50 — the canvas wheel replicated with CSS gradients */
271
- export const WHEEL_SIZE = 200;
272
- export const WHEEL_RADIUS = WHEEL_SIZE / 2 - 5;
273
- export const StyledColorWheel = styled.button.withConfig({
274
- displayName: "elements__StyledColorWheel",
275
- componentId: "sc-ohnju4-9"
276
- })(["display:block;width:", "px;height:", "px;padding:0;border:0;border-radius:50%;cursor:crosshair;box-shadow:", ";background:radial-gradient( circle closest-side,#ffffff,rgba(255,255,255,0) ),conic-gradient( from 90deg,#ff0000,#ffff00,#00ff00,#00ffff,#0000ff,#ff00ff,#ff0000 );"], WHEEL_SIZE, WHEEL_SIZE, SUBMENU_SHADOW);
277
- export const ColorWheel = _ref => {
278
- let onColorChange = _ref.onColorChange;
279
- return /*#__PURE__*/React.createElement(StyledColorWheel, {
280
- onClick: event => {
281
- const rect = event.currentTarget.getBoundingClientRect();
282
- const dx = event.clientX - rect.left - WHEEL_SIZE / 2;
283
- const dy = event.clientY - rect.top - WHEEL_SIZE / 2;
284
- const distance = Math.sqrt(dx * dx + dy * dy);
285
- if (distance > WHEEL_RADIUS) {
286
- return;
287
- }
288
- let angle = Math.atan2(dy, dx);
289
- if (angle < 0) {
290
- angle += 2 * Math.PI;
291
- }
292
- const hue = Math.round(angle * 180 / Math.PI);
293
- const saturation = Math.round(Math.min(100, distance / WHEEL_RADIUS * 100));
294
- onColorChange("hsl(" + hue + ", " + saturation + "%, 50%)");
295
- }
296
- });
297
- };
254
+ /* The trigger widths the app gives its toolbar selects: `tw-w-20` for the font
255
+ size ("16 pt"), `tw-w-16 tw-px-2` for the swatch-only colour trigger. */
256
+ const TOOLBAR_SELECT_WIDTH = 80;
257
+ const TOOLBAR_COLOR_TRIGGER_WIDTH = 64;
298
258
 
299
- /* ColorSwatchRow.jsx: 32px swatches + a "+" that opens the color wheel */
300
- export const StyledSwatchRow = styled.div.withConfig({
301
- displayName: "elements__StyledSwatchRow",
302
- componentId: "sc-ohnju4-10"
303
- })(["display:flex;flex-wrap:wrap;gap:8px;.swatch{width:32px;height:32px;box-sizing:border-box;padding:0;border:2px solid var(--border-primary);border-radius:4px;cursor:pointer;&:hover{border-color:var(--color-theme-500);}&.selected{box-shadow:0 0 0 2px ", ";}}.swatch-add{display:flex;align-items:center;justify-content:center;background-color:var(--color-theme-200);color:var(--color-secondary);}"], SELECTION_BLUE);
304
- export const ColorSwatchRow = _ref2 => {
305
- let selectedColor = _ref2.selectedColor,
306
- includeTransparent = _ref2.includeTransparent,
307
- onSelect = _ref2.onSelect,
308
- onAddClick = _ref2.onAddClick;
309
- return /*#__PURE__*/React.createElement(StyledSwatchRow, null, includeTransparent ? /*#__PURE__*/React.createElement("button", {
310
- type: "button",
311
- className: selectedColor === "transparent" ? "swatch swatch-add selected" : "swatch swatch-add",
312
- "aria-label": "Transparent",
313
- onClick: () => onSelect("transparent")
314
- }, /*#__PURE__*/React.createElement(CircleSlashIcon, {
315
- width: 20,
316
- height: 20,
317
- fill: "currentColor"
318
- })) : null, COLOR_PALETTE.map(color => /*#__PURE__*/React.createElement("button", {
319
- key: color,
320
- type: "button",
321
- className: selectedColor === color ? "swatch selected" : "swatch",
322
- style: {
323
- backgroundColor: color
324
- },
325
- onClick: () => onSelect(color)
326
- })), /*#__PURE__*/React.createElement("button", {
327
- type: "button",
328
- className: "swatch swatch-add",
329
- onClick: onAddClick
330
- }, /*#__PURE__*/React.createElement(PlusGlyph, null)));
331
- };
259
+ /* Hollow rounded rectangle, the app's own glyph for the "Rounded Rectangle"
260
+ shape option (its ShapeTypeMenu draws a bordered span, because the icon set
261
+ has one rectangle glyph and it is already taken by "Rectangle"). */
262
+ const RoundedRectangleOutline = styled.span.withConfig({
263
+ displayName: "elements__RoundedRectangleOutline",
264
+ componentId: "sc-ohnju4-7"
265
+ })(["display:block;width:16px;height:16px;box-sizing:border-box;border:1px solid currentColor;border-radius:4px;"]);
332
266
  export const SHAPE_TYPE_ICON = {
333
- rectangle: /*#__PURE__*/React.createElement(SquareGlyph, null),
334
- roundedRectangle: /*#__PURE__*/React.createElement(RoundedRectangleIcon, {
267
+ rectangle: /*#__PURE__*/React.createElement(RoundedRectangleIcon, {
335
268
  className: "i16"
336
269
  }),
270
+ roundedRectangle: /*#__PURE__*/React.createElement(RoundedRectangleOutline, {
271
+ "aria-hidden": "true"
272
+ }),
337
273
  circle: /*#__PURE__*/React.createElement(CircleIcon, {
338
274
  className: "i16"
339
275
  }),
@@ -382,10 +318,10 @@ export const BORDER_STYLE_OPTIONS = [{
382
318
  separator → Lock → Delete, in the standard control colour (not red). Mirrors
383
319
  app `toolbar/ToolbarActions.jsx`. */
384
320
 
385
- export const ToolbarActions = _ref3 => {
386
- let locked = _ref3.locked,
387
- onToggleLock = _ref3.onToggleLock,
388
- onDelete = _ref3.onDelete;
321
+ export const ToolbarActions = _ref => {
322
+ let locked = _ref.locked,
323
+ onToggleLock = _ref.onToggleLock,
324
+ onDelete = _ref.onDelete;
389
325
  return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("span", {
390
326
  className: "divider"
391
327
  }), /*#__PURE__*/React.createElement(Tooltip, {
@@ -410,9 +346,9 @@ export const ToolbarActions = _ref3 => {
410
346
  current shape, opening a dropdown of the four types. Modeled on the app's
411
347
  ShapeTypeMenu (DS Menu + List). */
412
348
 
413
- export const ShapeTypeMenu = _ref4 => {
414
- let value = _ref4.value,
415
- onChange = _ref4.onChange;
349
+ export const ShapeTypeMenu = _ref2 => {
350
+ let value = _ref2.value,
351
+ onChange = _ref2.onChange;
416
352
  const _useState = useState(false),
417
353
  open = _useState[0],
418
354
  setOpen = _useState[1];
@@ -423,7 +359,7 @@ export const ShapeTypeMenu = _ref4 => {
423
359
  position: "bottom-start",
424
360
  target: /*#__PURE__*/React.createElement(IconButton, {
425
361
  type: "button",
426
- variant: "text gray",
362
+ variant: "option",
427
363
  active: open,
428
364
  "aria-label": "Shape"
429
365
  }, SHAPE_TYPE_ICON[value])
@@ -446,11 +382,11 @@ export const ShapeTypeMenu = _ref4 => {
446
382
  compact-toolbar counterpart to the Inspector's expanded four-button row.
447
383
  Mirrors the app's AlignmentMenu. */
448
384
 
449
- export const AlignmentMenu = _ref5 => {
385
+ export const AlignmentMenu = _ref3 => {
450
386
  var _ALIGN_OPTIONS$find;
451
- let value = _ref5.value,
452
- onChange = _ref5.onChange,
453
- disabled = _ref5.disabled;
387
+ let value = _ref3.value,
388
+ onChange = _ref3.onChange,
389
+ disabled = _ref3.disabled;
454
390
  const _useState2 = useState(false),
455
391
  open = _useState2[0],
456
392
  setOpen = _useState2[1];
@@ -462,7 +398,7 @@ export const AlignmentMenu = _ref5 => {
462
398
  position: "bottom-start",
463
399
  target: /*#__PURE__*/React.createElement(IconButton, {
464
400
  type: "button",
465
- variant: "text gray",
401
+ variant: "option",
466
402
  active: open,
467
403
  disabled: disabled,
468
404
  "aria-label": "Alignment"
@@ -482,63 +418,101 @@ export const AlignmentMenu = _ref5 => {
482
418
  }, option.icon, option.label))));
483
419
  };
484
420
 
485
- /* Compact swatch-only colour trigger: a single dot (or a CircleSlash chip when
486
- transparent) that opens a swatch popover. The Inspector's ColorPickerField
487
- keeps the swatch + name; the floating toolbars use this swatch-only variant.
488
- `includeTransparent` is passed through to the swatch row shape fill opts
489
- in, sticky fill and text colour do not. */
490
-
491
- export const ToolbarColorSwatch = _ref6 => {
492
- let value = _ref6.value,
493
- includeTransparent = _ref6.includeTransparent,
494
- label = _ref6.label,
495
- onChange = _ref6.onChange;
496
- const _useState3 = useState(false),
497
- open = _useState3[0],
498
- setOpen = _useState3[1];
499
- const _useState4 = useState(false),
500
- wheelOpen = _useState4[0],
501
- setWheelOpen = _useState4[1];
502
- const isTransparent = value === "transparent";
503
- return /*#__PURE__*/React.createElement("span", {
504
- className: "tb-rel"
505
- }, /*#__PURE__*/React.createElement(Tooltip, {
506
- title: label
507
- }, /*#__PURE__*/React.createElement(StyledToolbarButton, {
508
- className: open ? "icon-only active" : "icon-only",
509
- "aria-label": label,
510
- onClick: () => {
511
- setOpen(current => !current);
512
- setWheelOpen(false);
513
- }
514
- }, isTransparent ? /*#__PURE__*/React.createElement(CircleSlashIcon, {
421
+ /* The app's compact `ColorPicker`: a DS `Select` whose trigger is the swatch
422
+ alone (a Dot, or the CircleSlash chip when transparent) and whose menu is the
423
+ standard dot-and-name list the same control the Inspector's colour field
424
+ uses, minus the name on the trigger. `includeTransparent` adds "Transparent"
425
+ first: shape fill opts in, sticky fill and text colour do not. */
426
+
427
+ const TOOLBAR_TRANSPARENT_OPTION = {
428
+ id: "transparent",
429
+ name: "Transparent",
430
+ color: "transparent",
431
+ textColor: "transparent"
432
+ };
433
+ const sameHex = (a, b) => a.toLowerCase() === b.toLowerCase();
434
+ const ColorDot = _ref4 => {
435
+ let color = _ref4.color;
436
+ return sameHex(color, "transparent") ? /*#__PURE__*/React.createElement(CircleSlashIcon, {
515
437
  width: 16,
516
438
  height: 16,
517
439
  fill: "currentColor"
518
440
  }) : /*#__PURE__*/React.createElement(Dot, {
519
- color: value,
441
+ color: color,
520
442
  size: 16
521
- }))), open ? /*#__PURE__*/React.createElement(StyledColorPopover, {
522
- className: "below"
523
- }, /*#__PURE__*/React.createElement(ColorSwatchRow, {
524
- selectedColor: value,
525
- includeTransparent: includeTransparent,
526
- onSelect: color => {
527
- onChange(color);
528
- setOpen(false);
529
- },
530
- onAddClick: () => setWheelOpen(current => !current)
531
- }), wheelOpen ? /*#__PURE__*/React.createElement(StyledColorPopover, {
532
- className: "beside"
533
- }, /*#__PURE__*/React.createElement(ColorWheel, {
534
- onColorChange: color => {
535
- onChange(color);
536
- setOpen(false);
537
- }
538
- })) : null) : null);
443
+ });
444
+ };
445
+ export const ToolbarColorSwatch = _ref5 => {
446
+ var _options$find$id, _options$find;
447
+ let value = _ref5.value,
448
+ includeTransparent = _ref5.includeTransparent,
449
+ label = _ref5.label,
450
+ onChange = _ref5.onChange;
451
+ const options = includeTransparent ? [TOOLBAR_TRANSPARENT_OPTION, ...COLOR_OPTIONS] : COLOR_OPTIONS;
452
+ const selected = (_options$find$id = (_options$find = options.find(option => sameHex(option.id, value))) == null ? void 0 : _options$find.id) != null ? _options$find$id : value;
453
+ return /*#__PURE__*/React.createElement(Tooltip, {
454
+ title: label
455
+ }, /*#__PURE__*/React.createElement("span", {
456
+ className: "tb-rel"
457
+ }, /*#__PURE__*/React.createElement(Select, {
458
+ type: "single",
459
+ disableSearch: true,
460
+ forceCloseMenu: true,
461
+ keepSameOptionsOrder: true,
462
+ options: options,
463
+ selected: selected,
464
+ onChange: next => onChange(String(Array.isArray(next) ? next[0] : next)),
465
+ renderOption: option => /*#__PURE__*/React.createElement("span", {
466
+ className: "tb-color-option"
467
+ }, /*#__PURE__*/React.createElement(ColorDot, {
468
+ color: String(option.id)
469
+ }), option.name),
470
+ target: /*#__PURE__*/React.createElement(SelectTrigger, {
471
+ "aria-label": label,
472
+ style: {
473
+ width: TOOLBAR_COLOR_TRIGGER_WIDTH,
474
+ paddingLeft: 8,
475
+ paddingRight: 8
476
+ }
477
+ }, /*#__PURE__*/React.createElement("span", {
478
+ className: "tb-color-value"
479
+ }, /*#__PURE__*/React.createElement(ColorDot, {
480
+ color: value
481
+ })))
482
+ })));
483
+ };
484
+
485
+ /* The app's `ValuePicker` for the font size: a DS `Select` over the fixed size
486
+ ladder, its trigger reading "16 pt". */
487
+
488
+ export const ToolbarFontSizeSelect = _ref6 => {
489
+ let value = _ref6.value,
490
+ onChange = _ref6.onChange;
491
+ return /*#__PURE__*/React.createElement(Tooltip, {
492
+ title: "Font Size"
493
+ }, /*#__PURE__*/React.createElement("span", {
494
+ className: "tb-rel"
495
+ }, /*#__PURE__*/React.createElement(Select, {
496
+ type: "single",
497
+ disableSearch: true,
498
+ forceCloseMenu: true,
499
+ keepSameOptionsOrder: true,
500
+ options: FONT_SIZE_OPTIONS.map(size => ({
501
+ id: size,
502
+ name: size + " pt"
503
+ })),
504
+ selected: value,
505
+ onChange: next => onChange(Number(Array.isArray(next) ? next[0] : next)),
506
+ target: /*#__PURE__*/React.createElement(SelectTrigger, {
507
+ "aria-label": "Font Size",
508
+ style: {
509
+ width: TOOLBAR_SELECT_WIDTH
510
+ }
511
+ }, value, " pt")
512
+ })));
539
513
  };
540
514
 
541
- /* The text controls shared by the shape and sticky toolbars: font-size stepper,
515
+ /* The text controls shared by the shape and sticky toolbars: font-size select,
542
516
  B / I / U / S, and the collapsed alignment menu. Same set the app's sticky
543
517
  and shape toolbars share (font-size picker, TextStyleButtons, AlignmentMenu).
544
518
  Kept generic so both element shapes can drive it. */
@@ -550,23 +524,10 @@ export const ToolbarTextControls = _ref7 => {
550
524
  onFontSize = _ref7.onFontSize,
551
525
  onToggleStyle = _ref7.onToggleStyle,
552
526
  onAlign = _ref7.onAlign;
553
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Tooltip, {
554
- title: "Decrease font size"
555
- }, /*#__PURE__*/React.createElement(StyledToolbarButton, {
556
- className: "icon-only",
557
- "aria-label": "Decrease font size",
558
- onClick: () => onFontSize(Math.max(8, fontSize - 2))
559
- }, /*#__PURE__*/React.createElement(MinusGlyph, {
560
- className: "i16"
561
- }))), /*#__PURE__*/React.createElement(StyledFontSizeValue, null, fontSize), /*#__PURE__*/React.createElement(Tooltip, {
562
- title: "Increase font size"
563
- }, /*#__PURE__*/React.createElement(StyledToolbarButton, {
564
- className: "icon-only",
565
- "aria-label": "Increase font size",
566
- onClick: () => onFontSize(Math.min(96, fontSize + 2))
567
- }, /*#__PURE__*/React.createElement(PlusGlyph, {
568
- className: "i16"
569
- }))), STYLE_OPTIONS.map(option => /*#__PURE__*/React.createElement(Tooltip, {
527
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ToolbarFontSizeSelect, {
528
+ value: fontSize,
529
+ onChange: onFontSize
530
+ }), STYLE_OPTIONS.map(option => /*#__PURE__*/React.createElement(Tooltip, {
570
531
  key: option.key,
571
532
  title: option.label
572
533
  }, /*#__PURE__*/React.createElement(StyledToolbarButton, {