ng-hub-ui-utils 22.18.0 → 22.20.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 CHANGED
@@ -385,7 +385,8 @@ export class ExampleComponent {}
385
385
  > ```
386
386
 
387
387
  Inputs: `hubTooltip` (text), `hubTooltipPlacement` (`top` | `bottom` | `left` | `right`,
388
- default `top`), `hubTooltipDelay` (fade ms, default `150`), `hubTooltipOffset` (px, default `8`).
388
+ default `top`), `hubTooltipDelay` (fade ms, default `150`), `hubTooltipShowDelay` (ms a hover has to last before
389
+ the tooltip opens, default `0`; keyboard focus always opens it at once), `hubTooltipOffset` (px, default `8`).
389
390
 
390
391
  **The placement is a preference, not an instruction (since 22.16.0).** A tooltip that would open
391
392
  off the edge of the window opens on the opposite side instead, at all four edges, and one centred
@@ -539,6 +540,11 @@ Also exported: `resolveGridEdge`, `isWithinGridRange`, `gridRangeCells`, `gridRa
539
540
  `HubGridCoords`, `HubGridBounds`, `HubGridRange`, `HubGridSpan`, `HubGridSpanMap`, `HubGridWrap`,
540
541
  `HubGridEdge`, `HubGridIntent`, `HubGridWindow` and `HubGridTrackSizes`.
541
542
 
543
+ Also exported for a selection of several rectangles: `isWithinGridSelection`, `addGridRange`,
544
+ `gridSelectionCells`, `gridSelectionSize`, `gridSelectionBounds`, `clampGridSelection` and
545
+ `gridSelectionTable` — the last of which decides whether a disjoint selection can be copied at all
546
+ (it can when the rectangles line up, and returns `null` when there is no honest table to write).
547
+
542
548
  ## 🚀 Installation
543
549
 
544
550
  ```bash
@@ -811,7 +817,7 @@ library, because their selectors and data models differ.
811
817
 
812
818
  ### Directives
813
819
 
814
- - `HubTooltipDirective` (`[hubTooltip]`) - Tooltip on hover/focus, flipped away from the window edges. Inputs: `hubTooltip`, `hubTooltipPlacement`, `hubTooltipDelay`, `hubTooltipOffset`
820
+ - `HubTooltipDirective` (`[hubTooltip]`) - Tooltip on hover/focus, flipped away from the window edges. Inputs: `hubTooltip`, `hubTooltipPlacement`, `hubTooltipDelay`, `hubTooltipShowDelay`, `hubTooltipOffset`
815
821
  - `HubOverflowTooltipDirective` (`[hubOverflowTooltip]`) - Tooltip shown only while the label is truncated. Inputs: `hubOverflowTooltip`, `placement`, `hubOverflowTooltipMeasure` (CSS selector, resolved inside the host, naming the box whose truncation decides it; defaults to the host)
816
822
  - `provideHubTooltip(adapter: HubTooltipAdapter)` and `HUB_TOOLTIP_ADAPTER` - Swap the implementation behind `[hubOverflowTooltip]`, app-wide or per subtree; defaults to `hubTooltipAdapter`
817
823
 
@@ -2183,6 +2183,127 @@ function between(value, length) {
2183
2183
  return Math.max(0, Math.min(length - 1, Math.trunc(value)));
2184
2184
  }
2185
2185
 
2186
+ /**
2187
+ * A selection made of several rectangles, which is what a grid has the moment somebody holds
2188
+ * `Ctrl` and clicks a second block.
2189
+ *
2190
+ * Kept as a list of rectangles rather than as a set of cells, for the same reason one rectangle is
2191
+ * kept as two corners: a reader picking four blocks of a thousand rows has picked four rectangles,
2192
+ * and turning that into four thousand coordinates to answer "is this cell selected" is how a sheet
2193
+ * starts feeling slow.
2194
+ *
2195
+ * The one rule worth knowing before reading the rest: **a disjoint selection cannot always be
2196
+ * copied.** Two blocks side by side make a table; two blocks that overlap nothing and line up with
2197
+ * nothing make no table at all, and a spreadsheet says so rather than inventing one. That is what
2198
+ * {@link gridSelectionTable} decides, and it is the same rule Excel applies when it refuses with
2199
+ * "that command cannot be used on multiple selections".
2200
+ */
2201
+ /** Whether a cell falls inside any rectangle of the selection. */
2202
+ function isWithinGridSelection(coords, ranges) {
2203
+ return ranges.some((range) => isWithinGridRange(coords, range));
2204
+ }
2205
+ /** Whether one rectangle holds another whole. */
2206
+ function contains(outer, inner) {
2207
+ return inner.top >= outer.top && inner.bottom <= outer.bottom && inner.left >= outer.left && inner.right <= outer.right;
2208
+ }
2209
+ /**
2210
+ * Adds a rectangle to a selection.
2211
+ *
2212
+ * Rectangles already swallowed by the newcomer are dropped, and a newcomer already inside one is
2213
+ * not added: without that, clicking about with `Ctrl` held quietly grows a list of rectangles that
2214
+ * all say the same thing, and every later answer — the cell count, the clipboard, the clearing —
2215
+ * has to de-duplicate what should never have been stored twice. Overlaps that are *partial* are
2216
+ * kept as they are, because they are two decisions the reader made and neither contains the other.
2217
+ */
2218
+ function addGridRange(ranges, range) {
2219
+ if (ranges.some((existing) => contains(existing, range))) {
2220
+ return [...ranges];
2221
+ }
2222
+ return [...ranges.filter((existing) => !contains(range, existing)), range];
2223
+ }
2224
+ /** Every rectangle trimmed to the grid, with the ones that no longer land anywhere dropped. */
2225
+ function clampGridSelection(ranges, bounds) {
2226
+ return ranges.map((range) => clampGridRange(range, bounds)).filter((range) => !!range);
2227
+ }
2228
+ /**
2229
+ * Every cell of the selection, each one once, row by row and left to right.
2230
+ *
2231
+ * The order matters as much as it does for a single rectangle: it is the order a paste reads and the
2232
+ * order a clearing reports, so a host can walk it without sorting anything.
2233
+ */
2234
+ function gridSelectionCells(ranges) {
2235
+ const seen = new Set();
2236
+ const cells = [];
2237
+ for (const range of ranges) {
2238
+ for (const cell of gridRangeCells(range)) {
2239
+ const key = `${cell.row}\t${cell.col}`;
2240
+ if (!seen.has(key)) {
2241
+ seen.add(key);
2242
+ cells.push(cell);
2243
+ }
2244
+ }
2245
+ }
2246
+ return cells.sort((a, b) => a.row - b.row || a.col - b.col);
2247
+ }
2248
+ /** How many cells the selection covers, counting a cell in two rectangles once. */
2249
+ function gridSelectionSize(ranges) {
2250
+ return gridSelectionCells(ranges).length;
2251
+ }
2252
+ /** The smallest rectangle holding every rectangle of the selection. */
2253
+ function gridSelectionBounds(ranges) {
2254
+ if (!ranges.length) {
2255
+ return null;
2256
+ }
2257
+ return ranges.reduce((all, range) => ({
2258
+ top: Math.min(all.top, range.top),
2259
+ bottom: Math.max(all.bottom, range.bottom),
2260
+ left: Math.min(all.left, range.left),
2261
+ right: Math.max(all.right, range.right)
2262
+ }));
2263
+ }
2264
+ /**
2265
+ * The rows and columns a copy of this selection would write, or null when it cannot be copied.
2266
+ *
2267
+ * A selection of one rectangle is always copyable. Several are copyable only when they line up: all
2268
+ * of them covering the same columns, so they stack into one table, or all of them covering the same
2269
+ * rows, so they sit side by side. Anything else has no rectangle to write — the blocks would have to
2270
+ * be squashed together and the reader would get a table whose shape they never chose.
2271
+ *
2272
+ * @returns The row indices and the column indices of the table, in the order they go out, or null
2273
+ * when the selection has no honest table.
2274
+ */
2275
+ function gridSelectionTable(ranges) {
2276
+ if (!ranges.length) {
2277
+ return null;
2278
+ }
2279
+ const sequence = (from, to) => Array.from({ length: to - from + 1 }, (_, index) => from + index);
2280
+ if (ranges.length === 1) {
2281
+ return { rows: sequence(ranges[0].top, ranges[0].bottom), cols: sequence(ranges[0].left, ranges[0].right) };
2282
+ }
2283
+ const [first] = ranges;
2284
+ const sameColumns = ranges.every((range) => range.left === first.left && range.right === first.right);
2285
+ if (sameColumns) {
2286
+ const stacked = [...ranges].sort((a, b) => a.top - b.top);
2287
+ return {
2288
+ rows: unique(stacked.flatMap((range) => sequence(range.top, range.bottom))),
2289
+ cols: sequence(first.left, first.right)
2290
+ };
2291
+ }
2292
+ const sameRows = ranges.every((range) => range.top === first.top && range.bottom === first.bottom);
2293
+ if (sameRows) {
2294
+ const beside = [...ranges].sort((a, b) => a.left - b.left);
2295
+ return {
2296
+ rows: sequence(first.top, first.bottom),
2297
+ cols: unique(beside.flatMap((range) => sequence(range.left, range.right)))
2298
+ };
2299
+ }
2300
+ return null;
2301
+ }
2302
+ /** Keeps the first occurrence of each index, so overlapping rectangles do not repeat a row. */
2303
+ function unique(values) {
2304
+ return [...new Set(values)];
2305
+ }
2306
+
2186
2307
  /**
2187
2308
  * Merged blocks, and what the rest of the grid has to know about them.
2188
2309
  *
@@ -3947,11 +4068,13 @@ let nextTooltipId = 0;
3947
4068
  class HubTooltipController {
3948
4069
  host;
3949
4070
  tooltipEl = null;
4071
+ showTimeout = null;
3950
4072
  hideTimeout = null;
3951
4073
  leaveTimeout = null;
3952
4074
  text = '';
3953
4075
  placement = 'top';
3954
4076
  delay = 150;
4077
+ showDelay = 0;
3955
4078
  offset = 8;
3956
4079
  /**
3957
4080
  * Side the bubble is actually on, which is the requested placement until the window says
@@ -3964,6 +4087,7 @@ class HubTooltipController {
3964
4087
  /** Id of this controller's bubble, minted once so the host can be described by it. */
3965
4088
  tooltipId = `hub-tooltip-${++nextTooltipId}`;
3966
4089
  onShow = () => this.show();
4090
+ onPointerEnter = () => this.scheduleShow();
3967
4091
  onHide = () => this.hide();
3968
4092
  onPointerLeave = () => this.scheduleHide();
3969
4093
  onTooltipEnter = () => this.retain();
@@ -3994,7 +4118,7 @@ class HubTooltipController {
3994
4118
  this.doc = host.ownerDocument;
3995
4119
  this.view = this.doc.defaultView;
3996
4120
  this.setOptions(options);
3997
- this.host.addEventListener('mouseenter', this.onShow);
4121
+ this.host.addEventListener('mouseenter', this.onPointerEnter);
3998
4122
  this.host.addEventListener('focus', this.onShow);
3999
4123
  this.host.addEventListener('mouseleave', this.onPointerLeave);
4000
4124
  this.host.addEventListener('blur', this.onHide);
@@ -4030,21 +4154,34 @@ class HubTooltipController {
4030
4154
  if (options.delay != null) {
4031
4155
  this.delay = options.delay;
4032
4156
  }
4157
+ if (options.showDelay != null) {
4158
+ this.showDelay = Math.max(0, options.showDelay);
4159
+ }
4033
4160
  if (options.offset != null) {
4034
4161
  this.offset = options.offset;
4035
4162
  }
4036
4163
  }
4037
4164
  /** Detaches listeners and removes any live tooltip element. */
4038
4165
  destroy() {
4039
- this.host.removeEventListener('mouseenter', this.onShow);
4166
+ this.host.removeEventListener('mouseenter', this.onPointerEnter);
4040
4167
  this.host.removeEventListener('focus', this.onShow);
4041
4168
  this.host.removeEventListener('mouseleave', this.onPointerLeave);
4042
4169
  this.host.removeEventListener('blur', this.onHide);
4043
4170
  this.host.removeEventListener('click', this.onHide);
4044
4171
  this.removeElement();
4045
4172
  }
4173
+ /** Waits for a sustained hover before opening, while retaining an already visible bubble. */
4174
+ scheduleShow() {
4175
+ this.clearShowTimeout();
4176
+ if (this.tooltipEl || this.showDelay === 0) {
4177
+ this.show();
4178
+ return;
4179
+ }
4180
+ this.showTimeout = setTimeout(() => this.show(), this.showDelay);
4181
+ }
4046
4182
  /** Creates, positions and reveals the tooltip element. */
4047
4183
  show() {
4184
+ this.clearShowTimeout();
4048
4185
  if (!this.text) {
4049
4186
  return;
4050
4187
  }
@@ -4097,6 +4234,7 @@ class HubTooltipController {
4097
4234
  * offset opens between host and bubble without the label vanishing on the way.
4098
4235
  */
4099
4236
  scheduleHide() {
4237
+ this.clearShowTimeout();
4100
4238
  if (!this.tooltipEl) {
4101
4239
  return;
4102
4240
  }
@@ -4114,6 +4252,7 @@ class HubTooltipController {
4114
4252
  }
4115
4253
  /** Fades the tooltip out and removes it after the fade completes. */
4116
4254
  hide() {
4255
+ this.clearShowTimeout();
4117
4256
  this.clearLeaveTimeout();
4118
4257
  if (!this.tooltipEl) {
4119
4258
  return;
@@ -4127,6 +4266,7 @@ class HubTooltipController {
4127
4266
  }
4128
4267
  /** Removes the tooltip element immediately. */
4129
4268
  removeElement() {
4269
+ this.clearShowTimeout();
4130
4270
  this.clearHideTimeout();
4131
4271
  this.clearLeaveTimeout();
4132
4272
  if (this.tooltipEl) {
@@ -4183,6 +4323,13 @@ class HubTooltipController {
4183
4323
  }
4184
4324
  }
4185
4325
  }
4326
+ /** Cancels hover work when the pointer leaves or the host is destroyed. */
4327
+ clearShowTimeout() {
4328
+ if (this.showTimeout !== null) {
4329
+ clearTimeout(this.showTimeout);
4330
+ this.showTimeout = null;
4331
+ }
4332
+ }
4186
4333
  clearHideTimeout() {
4187
4334
  if (this.hideTimeout !== null) {
4188
4335
  clearTimeout(this.hideTimeout);
@@ -4350,6 +4497,8 @@ class HubTooltipDirective {
4350
4497
  placement = input('top', { ...(ngDevMode ? { debugName: "placement" } : /* istanbul ignore next */ {}), alias: 'hubTooltipPlacement' });
4351
4498
  /** Fade duration in milliseconds, also used as the removal delay on hide. */
4352
4499
  delay = input(150, { ...(ngDevMode ? { debugName: "delay" } : /* istanbul ignore next */ {}), alias: 'hubTooltipDelay' });
4500
+ /** Pointer hover wait in milliseconds; keyboard focus remains immediate. */
4501
+ showDelay = input(0, { ...(ngDevMode ? { debugName: "showDelay" } : /* istanbul ignore next */ {}), alias: 'hubTooltipShowDelay' });
4353
4502
  /** Gap in pixels between the host and the tooltip. */
4354
4503
  offset = input(8, { ...(ngDevMode ? { debugName: "offset" } : /* istanbul ignore next */ {}), alias: 'hubTooltipOffset' });
4355
4504
  host = inject(ElementRef);
@@ -4359,6 +4508,7 @@ class HubTooltipDirective {
4359
4508
  this.controller.setOptions({
4360
4509
  placement: this.placement(),
4361
4510
  delay: this.delay(),
4511
+ showDelay: this.showDelay(),
4362
4512
  offset: this.offset()
4363
4513
  });
4364
4514
  this.controller.setText(this.text());
@@ -4369,14 +4519,14 @@ class HubTooltipDirective {
4369
4519
  this.controller.destroy();
4370
4520
  }
4371
4521
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4372
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: HubTooltipDirective, isStandalone: true, selector: "[hubTooltip]", inputs: { text: { classPropertyName: "text", publicName: "hubTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "hubTooltipPlacement", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "hubTooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "hubTooltipOffset", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
4522
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: HubTooltipDirective, isStandalone: true, selector: "[hubTooltip]", inputs: { text: { classPropertyName: "text", publicName: "hubTooltip", isSignal: true, isRequired: true, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "hubTooltipPlacement", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "hubTooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, showDelay: { classPropertyName: "showDelay", publicName: "hubTooltipShowDelay", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "hubTooltipOffset", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
4373
4523
  }
4374
4524
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubTooltipDirective, decorators: [{
4375
4525
  type: Directive,
4376
4526
  args: [{
4377
4527
  selector: '[hubTooltip]'
4378
4528
  }]
4379
- }], ctorParameters: () => [], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltip", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipPlacement", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipDelay", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipOffset", required: false }] }] } });
4529
+ }], ctorParameters: () => [], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltip", required: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipPlacement", required: false }] }], delay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipDelay", required: false }] }], showDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipShowDelay", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "hubTooltipOffset", required: false }] }] } });
4380
4530
 
4381
4531
  /**
4382
4532
  * Shows a tooltip with the given text **only while the host element is truncated**
@@ -4530,5 +4680,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4530
4680
  * Generated bundle index. Do not edit.
4531
4681
  */
4532
4682
 
4533
- export { ContentRef, FOCUSABLE_ELEMENTS_SELECTOR, GetPipe, HUB_DROPDOWN_POSITIONS, HUB_INK_LIGHTNESS_THRESHOLD, HUB_MAX_HUE_SHIFT, HUB_MAX_NEUTRAL_CHROMA, HUB_NAMED_COLORS, HUB_NEUTRAL_ANCHORS, HUB_SEMANTIC_ANCHORS, HUB_TOOLTIP_ADAPTER, HUB_TRANSLATION_CONFIG, HUB_TRANSLATION_PREFIX, HUB_TRANSLATION_SOURCE, HubDragDropService, HubGetPipe, HubIsObjectPipe, HubIsObservablePipe, HubIsStringPipe, HubOverflowTooltipDirective, HubTooltipController, HubTooltipDirective, HubTranslatePipe, HubTranslationService, HubUnwrapAsyncPipe, IsObjectPipe, IsObservablePipe, IsStringPipe, OverlayPosition, OverlayRef, OverlayService, PopupService, ScrollBar, TranslatePipe, UcfirstPipe, UnwrapAsyncPipe, anchorOf, buildSpanMap, clamp$1 as clamp, clampGridRange, clampToSrgbGamut, closest, compositeOver, computeTargetIndex, containsNode, contrastAPCA, contrastRatio, copyArrayItem, coversRange, createNativeDragImage, createPointerDragSession, debouncedSignal, equals, generateUniqueId, getActiveElement, getFocusableBoundaryElements, getValue, getValueInRange, gridCellTabIndex, gridRangeBetween, gridRangeCells, gridRangeSize, gridWindow, growWindowToSpans, harmoniseSemantics, hubAnchorToViewport, hubClampToViewport, hubCompleteTransition, hubFitsInViewport, hubFocusTrap, hubOppositeSide, hubRunTransition, hubToAnchorSide, hubToPhysicalSide, hubTooltipAdapter, hubViewportOf, interpolateString, isCovered, isDefined, isInSrgbGamut, isInteger, isNumber, isObject, isPromise, isString, isValidColor, isWithinGridRange, maxSrgbChroma, mergeDeep, moveGridFocus, moveItemInArray, oklchToRgb, padNumber, parseColor, provideHubTooltip, provideHubTranslation, provideHubTranslationAdapter, readableOn, reflow, regExpEscape, registerOverlayKeydown, relativeLuminance, removeAccents, resolveDropPosition, resolveGridEdge, resolveGridIntent, resolveHubAccent, rgbToOklch, runInZone, spanAt, tintNeutrals, toAbsoluteIndex, toHex, toInteger, toRgb, toString, transferArrayItem };
4683
+ export { ContentRef, FOCUSABLE_ELEMENTS_SELECTOR, GetPipe, HUB_DROPDOWN_POSITIONS, HUB_INK_LIGHTNESS_THRESHOLD, HUB_MAX_HUE_SHIFT, HUB_MAX_NEUTRAL_CHROMA, HUB_NAMED_COLORS, HUB_NEUTRAL_ANCHORS, HUB_SEMANTIC_ANCHORS, HUB_TOOLTIP_ADAPTER, HUB_TRANSLATION_CONFIG, HUB_TRANSLATION_PREFIX, HUB_TRANSLATION_SOURCE, HubDragDropService, HubGetPipe, HubIsObjectPipe, HubIsObservablePipe, HubIsStringPipe, HubOverflowTooltipDirective, HubTooltipController, HubTooltipDirective, HubTranslatePipe, HubTranslationService, HubUnwrapAsyncPipe, IsObjectPipe, IsObservablePipe, IsStringPipe, OverlayPosition, OverlayRef, OverlayService, PopupService, ScrollBar, TranslatePipe, UcfirstPipe, UnwrapAsyncPipe, addGridRange, anchorOf, buildSpanMap, clamp$1 as clamp, clampGridRange, clampGridSelection, clampToSrgbGamut, closest, compositeOver, computeTargetIndex, containsNode, contrastAPCA, contrastRatio, copyArrayItem, coversRange, createNativeDragImage, createPointerDragSession, debouncedSignal, equals, generateUniqueId, getActiveElement, getFocusableBoundaryElements, getValue, getValueInRange, gridCellTabIndex, gridRangeBetween, gridRangeCells, gridRangeSize, gridSelectionBounds, gridSelectionCells, gridSelectionSize, gridSelectionTable, gridWindow, growWindowToSpans, harmoniseSemantics, hubAnchorToViewport, hubClampToViewport, hubCompleteTransition, hubFitsInViewport, hubFocusTrap, hubOppositeSide, hubRunTransition, hubToAnchorSide, hubToPhysicalSide, hubTooltipAdapter, hubViewportOf, interpolateString, isCovered, isDefined, isInSrgbGamut, isInteger, isNumber, isObject, isPromise, isString, isValidColor, isWithinGridRange, isWithinGridSelection, maxSrgbChroma, mergeDeep, moveGridFocus, moveItemInArray, oklchToRgb, padNumber, parseColor, provideHubTooltip, provideHubTranslation, provideHubTranslationAdapter, readableOn, reflow, regExpEscape, registerOverlayKeydown, relativeLuminance, removeAccents, resolveDropPosition, resolveGridEdge, resolveGridIntent, resolveHubAccent, rgbToOklch, runInZone, spanAt, tintNeutrals, toAbsoluteIndex, toHex, toInteger, toRgb, toString, transferArrayItem };
4534
4684
  //# sourceMappingURL=ng-hub-ui-utils.mjs.map