@powerportalspro/react-fluent 5.0.0-beta.3 → 5.0.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/dist/index.d.ts CHANGED
@@ -1,25 +1,120 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ColumnValidator, Localizer, ViewDataSource, RecordContextProps } from '@powerportalspro/react';
3
1
  import * as react from 'react';
4
2
  import { CSSProperties, MouseEvent, ReactNode, ReactElement, JSX, ComponentType, HTMLAttributes, RefAttributes, RefObject } from 'react';
3
+ import { InputProps, Theme, FluentProviderProps, ButtonProps } from '@fluentui/react-components';
4
+ import { MaskMode, NumericOptions, ColumnValidator, Localizer, ViewDataSource, RecordContextProps } from '@powerportalspro/react';
5
+ import * as react_jsx_runtime from 'react/jsx-runtime';
5
6
  import { components, ResolvedColumn, TableSecurityPermission, TableRecordReference as TableRecordReference$1, ViewMetadata as ViewMetadata$1, TableRecord as TableRecord$8 } from '@powerportalspro/core';
6
- import { Theme, FluentProviderProps, ButtonProps } from '@fluentui/react-components';
7
7
  import { DataPoint, ChartType, ChartDataset, ChartLegendPosition, ChartOrientation, ChartClickEventArgs, ChartHandle, DataverseChartDataSource } from '@powerportalspro/react-charts';
8
8
 
9
+ interface MaskedTextFieldHandle {
10
+ /**
11
+ * Force a value into the field even while it has focus, parking the caret
12
+ * at the end. Used by an owning editor's spinner / stepper controls, which
13
+ * change the value without the user touching the input.
14
+ * `MaskedTextField.ForceValueAsync`.
15
+ *
16
+ * On the fast (no-mask) path this collapses to invoking `onValueChange`
17
+ * the input is controlled, so the new value flows back through props.
18
+ */
19
+ forceValue: (value: string | null) => void;
20
+ /** Focus the underlying `<input>` element. */
21
+ focus: () => void;
22
+ /** Blur the underlying `<input>` element. */
23
+ blur: () => void;
24
+ }
25
+ interface MaskedTextFieldProps {
26
+ /** Current logical value. Pass `null` for empty. */
27
+ value: string | null | undefined;
28
+ /**
29
+ * Fires when the user edits the value. Receives the unmasked logical value
30
+ * when {@link valueIncludesMask} is `false` (the default), or the masked
31
+ * display string when `true`.
32
+ */
33
+ onValueChange: (value: string | null) => void;
34
+ /** Fires when the input gains focus. */
35
+ onFocus?: (() => void) | undefined;
36
+ /** Fires when the input loses focus, carrying the final reported value. */
37
+ onBlur?: ((value: string | null) => void) | undefined;
38
+ /** Masking strategy. Defaults to {@link MaskMode.None}. */
39
+ mode?: MaskMode | undefined;
40
+ /** Slotted template for {@link MaskMode.Pattern} (e.g. `(000) 000-0000`). */
41
+ pattern?: string | null | undefined;
42
+ /** Per-character allow regex for {@link MaskMode.Regex} (e.g. `[A-Za-z]`). */
43
+ allowedPattern?: string | null | undefined;
44
+ /** Numeric options for {@link MaskMode.Numeric}. */
45
+ numeric?: NumericOptions | null | undefined;
46
+ /**
47
+ * When `true`, the value reported by `onValueChange` is the masked display
48
+ * string; when `false` (default), the unmasked logical value. No effect when
49
+ * `mode` is `'none'`.
50
+ */
51
+ valueIncludesMask?: boolean | undefined;
52
+ /**
53
+ * When `true`, the field commits on every keystroke even with no mask
54
+ * (forces the hook path). When `false` (default) and no mask is active,
55
+ * the fast path's controlled `<Input>` is used.
56
+ */
57
+ immediate?: boolean | undefined;
58
+ /** Element id forwarded onto the underlying `<input>`. */
59
+ id?: string | undefined;
60
+ /** Fluent input size. */
61
+ size?: InputProps['size'] | undefined;
62
+ /** Fluent input appearance. */
63
+ appearance?: InputProps['appearance'] | undefined;
64
+ /** Underlying `<input type=…>` value. Defaults to `'text'`. */
65
+ type?: InputProps['type'] | undefined;
66
+ /** Placeholder text shown when empty. */
67
+ placeholder?: string | undefined;
68
+ /** Disables the field. */
69
+ disabled?: boolean | undefined;
70
+ /** Makes the field read-only. */
71
+ readOnly?: boolean | undefined;
72
+ /** Maximum character length. */
73
+ maxLength?: number | undefined;
74
+ /** Browser autocomplete attribute. */
75
+ autoComplete?: string | undefined;
76
+ /**
77
+ * `inputmode` attribute on the underlying `<input>` — drives the
78
+ * touch-keyboard layout on mobile (`'decimal'` / `'numeric'` / `'tel'`).
79
+ */
80
+ inputMode?: 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search' | undefined;
81
+ /** Accessible label when no visible label is wired via a surrounding Field. */
82
+ ariaLabel?: string | undefined;
83
+ /**
84
+ * Optional text-alignment applied to the inner `<input>`.
85
+ * `MaskedTextField.TextAlign` parameter — set to `'right'` for numeric
86
+ * editors so digits hug the trailing edge as they're typed.
87
+ */
88
+ textAlign?: 'left' | 'right' | 'center' | undefined;
89
+ /**
90
+ * Slot rendered before the input (icon, currency symbol, etc.). Typed as
91
+ * Fluent's own slot value so MoneyEdit's currency badge / a search-icon
92
+ * adornment / etc. flow through without coercion.
93
+ */
94
+ contentBefore?: InputProps['contentBefore'] | undefined;
95
+ /** Slot rendered after the input. */
96
+ contentAfter?: InputProps['contentAfter'] | undefined;
97
+ /** CSS class applied to the `<Input>` root. */
98
+ className?: string | undefined;
99
+ /** Inline style applied to the `<Input>` root. */
100
+ style?: CSSProperties | undefined;
101
+ }
102
+ declare const MaskedTextField: react.ForwardRefExoticComponent<MaskedTextFieldProps & react.RefAttributes<MaskedTextFieldHandle>>;
103
+
9
104
  /**
10
105
  * Where the description (hint text) is rendered, when one is present. React
11
- * version of Blazor's `DisplayTooltipWhenAvailable: bool` — same intent but
106
+ * version of — same intent but
12
107
  * three-way:
13
108
  *
14
109
  * - `'tooltip'` (default) — renders a clickable Info icon next to the label
15
- * that opens a Fluent `Popover` containing the description on click.
16
- * Mirrors Blazor's `BaseFluentColumnEdit.GetLabelTemplate()` pattern.
17
- * Doesn't take vertical space and keeps long form layouts compact.
110
+ * that opens a Fluent `Popover` containing the description on click.
111
+ * Mirrors pattern.
112
+ * Doesn't take vertical space and keeps long form layouts compact.
18
113
  * - `'belowControl'` — renders the description inline below the input via
19
- * Fluent `Field`'s hint slot. Always visible; takes up vertical space.
20
- * Matches Blazor's older field-hint behavior.
114
+ * Fluent `Field`'s hint slot. Always visible; takes up vertical space.
115
+ *
21
116
  * - `'none'` — suppresses the description entirely, even when one is
22
- * provided by metadata or props.
117
+ * provided by metadata or props.
23
118
  */
24
119
  declare const DescriptionLocation: {
25
120
  readonly None: "none";
@@ -28,29 +123,18 @@ declare const DescriptionLocation: {
28
123
  };
29
124
  type DescriptionLocation = (typeof DescriptionLocation)[keyof typeof DescriptionLocation];
30
125
  /**
31
- * Shared props for every column-bound edit component. Mirrors the parameter
32
- * set Blazor's `BaseEdit` / `BaseColumnEdit` expose, minus a few Blazor-specific
33
- * concepts that don't translate (see notes at bottom).
126
+ * Shared props for every column-bound edit component.
34
127
  *
35
128
  * Most metadata-driven defaults are wired up — `label`, `description`,
36
- * `maxLength`, `min`, `max`, `required`, `readOnly` all auto-resolve from the
37
- * parent RecordContext's table metadata when the consumer doesn't pass them.
38
- * Consumer-passed props always win.
129
+ * `maxLength`, `min`, `max`, `required`, `readOnly` all auto-resolve from
130
+ * the parent RecordContext's table metadata when the consumer doesn't
131
+ * pass them. Consumer-passed props always win.
39
132
  *
40
- * Per-component subtypes (`TextEditProps`, `BoolEditProps`, etc.) extend this
41
- * with their type-specific props (Rows, EditorType, Precision, …).
133
+ * Per-component subtypes (`TextEditProps`, `BoolEditProps`, etc.) extend
134
+ * this with their type-specific props (Rows, EditorType, Precision, …).
42
135
  *
43
- * **Currently no-op props (kept for parity, will activate downstream):**
136
+ * **Currently no-op props (will activate downstream):**
44
137
  * - `displayValidationErrorMessage` — pending the form-validation layer.
45
- *
46
- * **Blazor props NOT mirrored** (Blazor-specific or non-applicable):
47
- * - `ChildContent` — Blazor's `RenderFragment` for slot composition. React
48
- * has `children` natively; declaring it on a shared base is misleading
49
- * when most edits don't render children. Per-component types add it where
50
- * it actually makes sense.
51
- * - `Rows` on TextEdit — Blazor exposes it but FluentTextField is single-line
52
- * so it has no effect. {@link MemoEdit} is the multi-line variant where
53
- * `rows` belongs.
54
138
  */
55
139
  interface BaseColumnEditProps {
56
140
  /** Logical name of the column on the parent {@link RecordContext}'s record (e.g. `"firstname"`). Required. */
@@ -123,6 +207,33 @@ interface TextEditProps extends BaseColumnEditProps {
123
207
  autoComplete?: boolean;
124
208
  /** Optional placeholder shown when the field is empty. */
125
209
  placeholder?: string;
210
+ /**
211
+ * Masking strategy. Defaults to {@link MaskMode.None}. Set to
212
+ * {@link MaskMode.Pattern} (with `pattern`), {@link MaskMode.Regex} (with
213
+ * `allowedPattern`), or {@link MaskMode.Numeric} (with `numeric`) for
214
+ * caret-safe live masking.
215
+ */
216
+ mask?: MaskMode | undefined;
217
+ /** Slotted template for {@link MaskMode.Pattern} (e.g. `(000) 000-0000`). */
218
+ pattern?: string | undefined;
219
+ /** Per-character allow regex for {@link MaskMode.Regex} (e.g. `[A-Za-z]`). */
220
+ allowedPattern?: string | undefined;
221
+ /** Numeric options for {@link MaskMode.Numeric}. */
222
+ numeric?: NumericOptions | undefined;
223
+ /**
224
+ * Controls whether a masked value is stored with or without the mask. When
225
+ * `true`, the column stores the masked text including literals / separators
226
+ * (e.g. `(555) 123-4567`); when `false` (default), the unmasked logical
227
+ * value (e.g. `5551234567`). No effect when `mask` is `'none'`. Mirrors
228
+ *.
229
+ */
230
+ storeMaskedValue?: boolean | undefined;
231
+ /**
232
+ * When `true`, the editor commits on every keystroke (the DOM `input`
233
+ * event); when `false` (default), on blur (the DOM `change` event).
234
+ *
235
+ */
236
+ immediate?: boolean | undefined;
126
237
  }
127
238
  /**
128
239
  * Single-line text input bound to a `StringValue` ($type 14) on the parent
@@ -138,7 +249,7 @@ interface TextEditProps extends BaseColumnEditProps {
138
249
  * deliberately not used here because Dataverse decimal/money fields have
139
250
  * different wire-format requirements than plain string columns.
140
251
  */
141
- declare function TextEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, type, minLength, maxLength, autoComplete, placeholder, validate, }: TextEditProps): react_jsx_runtime.JSX.Element | null;
252
+ declare function TextEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, type, minLength, maxLength, autoComplete, placeholder, mask, pattern, allowedPattern, numeric, storeMaskedValue, immediate, validate, }: TextEditProps): react_jsx_runtime.JSX.Element | null;
142
253
 
143
254
  interface MemoEditProps extends BaseColumnEditProps {
144
255
  /** Minimum allowed character count. */
@@ -162,14 +273,14 @@ interface MemoEditProps extends BaseColumnEditProps {
162
273
  */
163
274
  declare function MemoEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, minLength, maxLength, rows, placeholder, resize, validate, }: MemoEditProps): react_jsx_runtime.JSX.Element | null;
164
275
 
165
- /** Mirrors Blazor's `BoolEditorType` enum — picks the rendered control. */
276
+ /** Mirrors enum — picks the rendered control. */
166
277
  declare const BoolEditorType: {
167
278
  readonly Checkbox: "checkbox";
168
279
  readonly Switch: "switch";
169
280
  };
170
281
  type BoolEditorType = (typeof BoolEditorType)[keyof typeof BoolEditorType];
171
282
  /**
172
- * Mirrors Blazor's `LabelPosition` enum on `BoolEdit`. Controls whether the
283
+ * Mirrors enum on `BoolEdit`. Controls whether the
173
284
  * label appears beside the control (the default) or above it (wrapping the
174
285
  * control in a Field).
175
286
  */
@@ -224,7 +335,7 @@ type Schemas$1 = components['schemas'];
224
335
  * what TextEdit / MemoEdit / BoolEdit / NumberEdit / MoneyEdit need.
225
336
  *
226
337
  * `setValue(undefined | null)` clears the column from `record.properties`,
227
- * which is the correct way to send "this field has no value" to Dataverse
338
+ * which is the correct way to send "this field has no value" to Dataverse
228
339
  * different from sending an empty string or `0`.
229
340
  *
230
341
  * Returns `value: undefined` when the record hasn't loaded yet OR when the
@@ -248,10 +359,10 @@ type NumberValueType = 'int' | 'decimal' | 'double' | 'bigint';
248
359
  * `ColumnValueBase` subtype to write back so the server-side deserializer
249
360
  * binds to the right Dataverse field type:
250
361
  *
251
- * - `int` → IntValue, $type 5
362
+ * - `int` → IntValue, $type 5
252
363
  * - `decimal` → DecimalValue, $type 3
253
- * - `double` → DoubleValue, $type 4
254
- * - `bigint` → BigIntValue, $type 18
364
+ * - `double` → DoubleValue, $type 4
365
+ * - `bigint` → BigIntValue, $type 18
255
366
  *
256
367
  * For very large `bigint` values exceeding `Number.MAX_SAFE_INTEGER`, the
257
368
  * generated wire schema accepts `number | string`. This v0 always sends
@@ -286,9 +397,9 @@ declare function useChoiceColumn(columnName: string): {
286
397
  *
287
398
  * `setValue(undefined | null | [])` all clear the column. Sending an empty
288
399
  * array would write `MultiSelectChoiceValue { value: [] }`, which the
289
- * server's `Update` path treats the same as clearing the column anyway
400
+ * server's `Update` path treats the same as clearing the column anyway
290
401
  * collapsing to `null` here keeps the wire payload smaller and matches
291
- * Blazor's `BaseMultiSelectChoiceEdit.Value` setter.
402
+ * setter.
292
403
  */
293
404
  declare function useMultiSelectChoiceColumn(columnName: string): {
294
405
  value: number[];
@@ -359,26 +470,26 @@ type FileColumnValue = Omit<Schemas$1['ColumnValueBaseFileValue'], '$type'>;
359
470
  * this hook normalizes into a single `FileColumnValue`:
360
471
  *
361
472
  * <list type="bullet">
362
- * <item><b>File columns</b> (Dataverse `FileMetadata`): the data column
363
- * itself surfaces post-fetch as a <c>GuidValue</c> ($type 15) holding
364
- * the assigned file id, with a sibling <c>{columnName}_name</c>
365
- * <c>StringValue</c> ($type 14) holding the original filename. Example
366
- * from a contact record: <c>ppp_contract = { $type: 15, value: "df94…" }</c>
367
- * plus <c>ppp_contract_name = { $type: 14, value: "archive.zip" }</c>.</item>
368
- * <item><b>Image columns</b> (Dataverse `ImageMetadata`): the data
369
- * column itself doesn't surface post-fetch; a sibling <c>{columnName}id</c>
370
- * <c>GuidValue</c> holds the file id (no `_name` companion since
371
- * images don't carry a meaningful original filename). Example:
372
- * <c>ppp_profileimageid = { $type: 15, value: "4fd5…" }</c>.</item>
373
- * <item><b>Client-side after upload</b> (both kinds): the data column
374
- * is replaced by a <c>FileValue</c> ($type "FileValue") carrying the
375
- * filename, an empty GUID, and the in-memory base64 bytes — that's the
376
- * shape `setValue` writes during an upload.</item>
473
+ * <item><b>File columns</b> (Dataverse `FileMetadata`): the data column
474
+ * itself surfaces post-fetch as a <c>GuidValue</c> ($type 15) holding
475
+ * the assigned file id, with a sibling <c>{columnName}_name</c>
476
+ * <c>StringValue</c> ($type 14) holding the original filename. Example
477
+ * from a contact record: <c>ppp_contract = { $type: 15, value: "df94…" }</c>
478
+ * plus <c>ppp_contract_name = { $type: 14, value: "archive.zip" }</c>.</item>
479
+ * <item><b>Image columns</b> (Dataverse `ImageMetadata`): the data
480
+ * column itself doesn't surface post-fetch; a sibling <c>{columnName}id</c>
481
+ * <c>GuidValue</c> holds the file id (no `_name` companion since
482
+ * images don't carry a meaningful original filename). Example:
483
+ * <c>ppp_profileimageid = { $type: 15, value: "4fd5…" }</c>.</item>
484
+ * <item><b>Client-side after upload</b> (both kinds): the data column
485
+ * is replaced by a <c>FileValue</c> ($type "FileValue") carrying the
486
+ * filename, an empty GUID, and the in-memory base64 bytes — that's the
487
+ * shape `setValue` writes during an upload.</item>
377
488
  * </list>
378
489
  *
379
490
  * The hook collapses all three onto a single <c>FileColumnValue</c>
380
491
  * (filename + id + optional binary) so consumers never have to branch.
381
- * Mirrors Blazor's `FileInputColumnEdit.OnParametersSetAsync` synthesis
492
+ * Mirrors synthesis
382
493
  * of the post-fetch GuidValue + `_name` pair into a `FileValue`.
383
494
  *
384
495
  * <c>setValue(null)</c> clears the column. The server's
@@ -417,7 +528,7 @@ interface NumberEditProps extends BaseColumnEditProps {
417
528
  * the editor was bound to incorrectly. Pass an explicit value to
418
529
  * override (e.g. force `decimal` round-tripping on an int column).
419
530
  *
420
- * Mirrors Blazor's `<NumberEdit>` which picks the right
531
+ * Mirrors which picks the right
421
532
  * `BaseNumberEdit<TNumber>` from metadata in NumberEdit.razor:7-82.
422
533
  *
423
534
  * For currency columns, use {@link MoneyEdit} instead — it binds to
@@ -437,11 +548,11 @@ interface NumberEditProps extends BaseColumnEditProps {
437
548
  */
438
549
  precision?: number;
439
550
  /**
440
- * Hide the browser's increment/decrement spinner buttons on the number
441
- * input. Implemented via a Griffel-generated CSS class targeting the
442
- * inner `<input>` (covers both Firefox via `-moz-appearance: textfield`
443
- * and WebKit via the `::-webkit-inner-spin-button` /
444
- * `-outer-spin-button` pseudo-elements).
551
+ * Hide the increment / decrement spinner buttons rendered alongside the
552
+ * input. When `false` (the default) the editor shows up / down chevrons in
553
+ * the input's `contentAfter` slot; press them to step by {@link step}
554
+ * (press-and-hold accelerates after a short delay).
555
+ * `BaseNumberEdit.HideStep`.
445
556
  */
446
557
  hideStep?: boolean;
447
558
  /**
@@ -453,7 +564,13 @@ interface NumberEditProps extends BaseColumnEditProps {
453
564
  * consumer code stays portable.
454
565
  */
455
566
  format?: string;
456
- /** Step interval. Pass-through to the underlying input's `step`. */
567
+ /**
568
+ * Amount added or subtracted when the user clicks the spinner chevrons
569
+ * (or, while pressing-and-holding, the amount per repeat tick). Defaults
570
+ * to `1`. Honors {@link min} /
571
+ * {@link max} clamping and {@link precision} rounding. Has no effect when
572
+ * {@link hideStep} is `true`.
573
+ */
457
574
  step?: number;
458
575
  /** Optional placeholder shown when the field is empty. */
459
576
  placeholder?: string;
@@ -480,48 +597,58 @@ interface MoneyEditProps extends BaseColumnEditProps {
480
597
  */
481
598
  precision?: number;
482
599
  /**
483
- * Hide the browser's increment/decrement spinner buttons.
600
+ * Hide the increment / decrement spinner buttons rendered alongside the
601
+ * input. When `false` (the default) the editor shows up / down chevrons in
602
+ * the input's `contentAfter` slot; press them to step by {@link step}
603
+ * (press-and-hold accelerates after a short delay).
604
+ * `BaseNumberEdit.HideStep`.
484
605
  */
485
606
  hideStep?: boolean;
486
607
  /**
487
608
  * .NET-style format string applied to the read-only display value
488
609
  * (e.g. `"c2"` for currency with 2 decimals, `"n0"` for thousands-
489
- * separated integer). Mirrors Blazor's `BaseNumberEdit.Format` — the
610
+ * separated integer). the
490
611
  * editable input branch ignores this; the resolved value only appears
491
612
  * when `readOnly` or `disabled` is in effect.
492
613
  *
493
614
  * Resolution order in read-only mode:
494
- * 1. `record.formattedValues[columnName]` — Dataverse's
495
- * server-side formatted string (currency symbol, locale-aware
496
- * separators, Money base-currency context). Wins when present.
497
- * 2. `formatValue(value, format, locale)` — client-side formatting
498
- * via `Intl.NumberFormat`. Used for unsaved records, columns the
499
- * server didn't emit a formatted value for, or when the locale
500
- * mismatches the server's.
501
- * 3. `String(value)` — raw fallback when no format is set.
615
+ * 1. `record.formattedValues[columnName]` — Dataverse's
616
+ * server-side formatted string (currency symbol, locale-aware
617
+ * separators, Money base-currency context). Wins when present.
618
+ * 2. `formatValue(value, format, locale)` — client-side formatting
619
+ * via `Intl.NumberFormat`. Used for unsaved records, columns the
620
+ * server didn't emit a formatted value for, or when the locale
621
+ * mismatches the server's.
622
+ * 3. `String(value)` — raw fallback when no format is set.
502
623
  *
503
624
  * Standard numeric codes (`N`, `F`, `C`, `P`, `E`, `X` ± digits) and
504
625
  * simple custom patterns (`0.00`, `#,##0.00`) are supported. See
505
626
  * `formatValue` for the full grid.
506
627
  */
507
628
  format?: string;
508
- /** Step interval. Defaults to `0.01` (one cent). */
629
+ /**
630
+ * Amount added or subtracted when the user clicks the spinner chevrons
631
+ * (or, while pressing-and-holding, the amount per repeat tick). Defaults
632
+ * to `0.01` (one minor unit).
633
+ * Honors {@link min} / {@link max} clamping and {@link precision} rounding.
634
+ * Has no effect when {@link hideStep} is `true`.
635
+ */
509
636
  step?: number;
510
637
  /** Optional placeholder shown when the field is empty. */
511
638
  placeholder?: string;
512
639
  }
513
640
  /**
514
- * Currency column editor. Always binds to a `MoneyValue` ($type 8)
641
+ * Currency column editor. Always binds to a `MoneyValue` ($type 8)
515
642
  * distinct from {@link NumberEdit} because Dataverse currency columns
516
643
  * participate in the org's transactioncurrency / exchange-rate plumbing
517
644
  * and round-trip through a different wire shape than plain decimals.
518
645
  *
519
646
  * `min`, `max`, `precision`, `required`, and `readOnly` are auto-resolved
520
647
  * from MoneyMetadata. In the editable branch the input shows the raw
521
- * decimal value — same as Blazor's `<FluentNumberField>` — so consumers
648
+ * decimal value — same as — so consumers
522
649
  * can type freely. In the read-only / disabled branch the value renders
523
650
  * as plain text and resolves through `record.formattedValues` → `format`
524
- * fallback → raw `String(value)`, matching Blazor's
651
+ * fallback → raw `String(value)`
525
652
  * `BaseNumberEdit.GetReadOnlyDisplayValue()`.
526
653
  */
527
654
  declare function MoneyEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, min, max, precision, hideStep, format, step, placeholder, validate, }: MoneyEditProps): react_jsx_runtime.JSX.Element | null;
@@ -606,13 +733,13 @@ interface ColumnDisplayValueProps {
606
733
  declare function ColumnDisplayValue({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, isVisible, emptyPlaceholder, format, className, style, id, }: ColumnDisplayValueProps): react_jsx_runtime.JSX.Element | null;
607
734
 
608
735
  /**
609
- * Which input(s) the editor renders. Mirrors Blazor's `DateTimeEditorType`.
736
+ * Which input(s) the editor renders.
610
737
  *
611
- * - `'dateTime'` (default for `UserLocal` / `TimeZoneIndependent` metadata)
612
- * side-by-side `DatePicker` + `TimePicker`.
738
+ * - `'dateTime'` (default for `UserLocal` / `TimeZoneIndependent` metadata)
739
+ * side-by-side `DatePicker` + `TimePicker`.
613
740
  * - `'dateOnly'` (default for `DateOnly` metadata) — `DatePicker` only.
614
741
  * - `'timeOnly'` — `TimePicker` only. The date portion of an existing
615
- * stored value is preserved; a fresh value uses today's date.
742
+ * stored value is preserved; a fresh value uses today's date.
616
743
  */
617
744
  declare const DateTimeEditorType: {
618
745
  readonly DateTime: "dateTime";
@@ -662,9 +789,9 @@ interface DateTimeEditProps extends BaseColumnEditProps {
662
789
  *
663
790
  * - `dateOnly` → just `DatePicker`. Stored as midnight UTC on the wire.
664
791
  * - `dateTime` → `DatePicker` + `TimePicker` side-by-side; changes from
665
- * either preserve the other half so editing one doesn't clobber the other.
792
+ * either preserve the other half so editing one doesn't clobber the other.
666
793
  * - `timeOnly` → just `TimePicker`, anchored to the existing wire value's
667
- * date (or today when there isn't one).
794
+ * date (or today when there isn't one).
668
795
  *
669
796
  * Wire format is ISO 8601 string in/out via `useDateColumn`; `Date` objects
670
797
  * live only inside this component for picker interop.
@@ -681,7 +808,7 @@ interface FileEditProps extends BaseColumnEditProps {
681
808
  /**
682
809
  * Maximum file size in bytes the consumer is willing to accept. When
683
810
  * omitted, no client-side check runs — server-side
684
- * <c>EnvironmentFileSettings.maxUploadSize</c> still applies on save.
811
+ * <c>OrganizationSettings.maxUploadFileSizeInBytes</c> still applies on save.
685
812
  * Files exceeding the limit are rejected with a console warning before
686
813
  * any state updates.
687
814
  */
@@ -701,18 +828,18 @@ interface FileEditProps extends BaseColumnEditProps {
701
828
  *
702
829
  * Upload flow:
703
830
  * 1. User drops a file or clicks the drop zone (which proxies a hidden
704
- * `<input type="file">`).
831
+ * `<input type="file">`).
705
832
  * 2. The file is read as a Data URL via `FileReader`, base64-decoded, and
706
- * stored on the record via `setValue({ fileName, id: emptyGuid, value })`.
833
+ * stored on the record via `setValue({ fileName, id: emptyGuid, value })`.
707
834
  * 3. When the consumer's parent context saves the record, the framework's
708
- * file-upload pipeline picks up the new content and writes it to
709
- * Dataverse, replacing the empty `id` with the assigned file id.
835
+ * file-upload pipeline picks up the new content and writes it to
836
+ * Dataverse, replacing the empty `id` with the assigned file id.
710
837
  *
711
838
  * Download flow:
712
839
  * - When `value.value` is non-null (the upload happened in this session),
713
- * the in-memory bytes are turned into a blob and saved with the file name.
840
+ * the in-memory bytes are turned into a blob and saved with the file name.
714
841
  * - Otherwise <c>getFileInfoAsync(table, id, column, includeData=true)</c>
715
- * fetches the binary on-demand.
842
+ * fetches the binary on-demand.
716
843
  */
717
844
  declare function FileEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, accept, maxFileSizeBytes, uploadHintText, validate, }: FileEditProps): react_jsx_runtime.JSX.Element | null;
718
845
 
@@ -733,7 +860,7 @@ interface ImageEditProps extends BaseColumnEditProps {
733
860
  /**
734
861
  * Maximum file size in bytes the consumer is willing to accept. When
735
862
  * omitted, no client-side check runs — server-side
736
- * <c>EnvironmentFileSettings.maxUploadSize</c> still applies on save.
863
+ * <c>OrganizationSettings.maxUploadFileSizeInBytes</c> still applies on save.
737
864
  */
738
865
  maxFileSizeBytes?: number;
739
866
  /**
@@ -770,10 +897,10 @@ interface ImageEditProps extends BaseColumnEditProps {
770
897
  *
771
898
  * Image-specific work this component owns (and `FileEdit` doesn't):
772
899
  * <list type="bullet">
773
- * <item>The binary lazy-load — `FileEdit` only fetches metadata after
774
- * refresh; ImageEdit also fetches the bytes so the preview can render.</item>
775
- * <item>The `<img>` rendering, MIME-type guess, and read-only
776
- * click-to-download UX.</item>
900
+ * <item>The binary lazy-load — `FileEdit` only fetches metadata after
901
+ * refresh; ImageEdit also fetches the bytes so the preview can render.</item>
902
+ * <item>The `<img>` rendering, MIME-type guess, and read-only
903
+ * click-to-download UX.</item>
777
904
  * </list>
778
905
  */
779
906
  declare function ImageEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, accept, displayImage, maxFileSizeBytes, uploadHintText, outputFormat, outputQuality, validate, }: ImageEditProps): react_jsx_runtime.JSX.Element | null;
@@ -781,7 +908,7 @@ declare function ImageEdit({ columnName, label, description, displayLabelWhenAva
781
908
  type ColumnMetadataBase$3 = components['schemas']['ColumnMetadataBase'];
782
909
  /**
783
910
  * Helpers that derive UI props from the parent RecordContext's table metadata.
784
- * Mirror Blazor's `BaseColumnEdit.OnParametersSetAsync` defaults — required is
911
+ * Mirror defaults — required is
785
912
  * driven by `RequiredLevel`, readOnly is driven by `isValidForCreate` /
786
913
  * `isValidForUpdate` based on whether the record is new or existing, and
787
914
  * type-specific props (maxLength, min/max, precision) come from the matching
@@ -808,7 +935,7 @@ declare function isMetadataRequired(metadata: ColumnMetadataBase$3 | undefined):
808
935
  * standard Update path — file content rides through a separate
809
936
  * `SetFileField` round-trip. The framework's update endpoint handles
810
937
  * that translation server-side, so from the consumer's perspective these
811
- * columns ARE editable. Mirrors Blazor's
938
+ * columns ARE editable.
812
939
  * `BaseColumnEdit.OnParametersSetAsync` exclusion of FileMetadata /
813
940
  * ImageMetadata when computing `_readOnlyInternal`.
814
941
  */
@@ -818,12 +945,12 @@ declare function isMetadataReadOnly(metadata: ColumnMetadataBase$3 | undefined,
818
945
  * server). Treats three signals as "new":
819
946
  * - missing / null id;
820
947
  * - Guid.Empty (`00000000-0000-0000-0000-000000000000`) id (the wire's
821
- * legacy "new record" marker);
948
+ * legacy "new record" marker);
822
949
  * - non-empty id but no `permissions` stamped. RecordContext create-mode
823
- * pre-generates a GUID so descendants like `<ManyToManyLookupEdit>`
824
- * can target a stable parent id before save; that defeats the id-only
825
- * heuristic but the missing-`permissions` marker still works because
826
- * the server stamps permissions on every record it returns.
950
+ * pre-generates a GUID so descendants like `<ManyToManyLookupEdit>`
951
+ * can target a stable parent id before save; that defeats the id-only
952
+ * heuristic but the missing-`permissions` marker still works because
953
+ * the server stamps permissions on every record it returns.
827
954
  */
828
955
  declare function isNewRecord(record: {
829
956
  id?: string | null;
@@ -831,7 +958,7 @@ declare function isNewRecord(record: {
831
958
  } | undefined): boolean;
832
959
  /**
833
960
  * Resolves the display label for a column via the active localizer, using the
834
- * key `tables.{tableName}.columns.{columnName}.label`. Mirrors Blazor's
961
+ * key `tables.{tableName}.columns.{columnName}.label`.
835
962
  * `BaseColumnEdit` which does the identical lookup via `IStringLocalizer`.
836
963
  *
837
964
  * The cached metadata's `displayName` is NOT the source of truth — Dataverse
@@ -839,7 +966,7 @@ declare function isNewRecord(record: {
839
966
  * the application user), so it doesn't change when the request culture
840
967
  * switches. The localizer cache (populated per-LCID from Dataverse
841
968
  * `LocalizedLabels` at startup) is the per-culture source. On a localizer
842
- * miss the key itself is returned, matching Blazor's behavior and the
969
+ * miss the key itself is returned
843
970
  * "show keys, not a fallback language" rule consumers rely on to spot
844
971
  * un-translated strings during development.
845
972
  *
@@ -922,7 +1049,7 @@ interface NumberLimits {
922
1049
  */
923
1050
  declare function getNumberLimits(metadata: ColumnMetadataBase$3 | undefined): NumberLimits;
924
1051
 
925
- /** Sort order for the rendered choice options. Mirrors Blazor's `ChoiceValueSort`. */
1052
+ /** Sort order for the rendered choice options. */
926
1053
  declare const ChoiceValueSort: {
927
1054
  /** Server order — whatever Dataverse returned. */
928
1055
  readonly Default: "default";
@@ -938,7 +1065,7 @@ declare const ChoiceValueSort: {
938
1065
  type ChoiceValueSort = (typeof ChoiceValueSort)[keyof typeof ChoiceValueSort];
939
1066
  /**
940
1067
  * Behavior when a choice value is excluded by `validChoiceValues` /
941
- * `invalidChoiceValues`. Mirrors Blazor's `ChoiceInvalidValueBehavior`.
1068
+ * `invalidChoiceValues`.
942
1069
  */
943
1070
  declare const ChoiceInvalidValueBehavior: {
944
1071
  /** Hide the option entirely. */
@@ -949,7 +1076,7 @@ declare const ChoiceInvalidValueBehavior: {
949
1076
  type ChoiceInvalidValueBehavior = (typeof ChoiceInvalidValueBehavior)[keyof typeof ChoiceInvalidValueBehavior];
950
1077
  /**
951
1078
  * Layout direction for the radio (single-select) or checkbox (multi-select)
952
- * variants. Mirrors Blazor's `ComponentOrientation`. Shared because the
1079
+ * variants. Shared because the
953
1080
  * underlying axis decision is identical between the two editors.
954
1081
  */
955
1082
  declare const ChoiceOrientation: {
@@ -960,7 +1087,7 @@ type ChoiceOrientation = (typeof ChoiceOrientation)[keyof typeof ChoiceOrientati
960
1087
 
961
1088
  /**
962
1089
  * Renders the choice column as a single-select dropdown ({@link Dropdown}) or
963
- * a {@link RadioGroup}. Mirrors Blazor's `ChoiceEditType`.
1090
+ * a {@link RadioGroup}.
964
1091
  */
965
1092
  declare const ChoiceEditorType: {
966
1093
  readonly Dropdown: "dropdown";
@@ -1057,8 +1184,8 @@ interface MultiSelectChoiceEditProps extends BaseColumnEditProps {
1057
1184
  * scrolling once the container's bounds are reached:
1058
1185
  * - `checkboxOrientation: 'horizontal'` — wraps onto multiple rows.
1059
1186
  * - `checkboxOrientation: 'vertical'` — flows into additional columns when a
1060
- * height cap is applied (e.g. `style={{ maxHeight }}`); otherwise it stays
1061
- * a single growing column.
1187
+ * height cap is applied (e.g. `style={{ maxHeight }}`); otherwise it stays
1188
+ * a single growing column.
1062
1189
  *
1063
1190
  * When `false`, the layout scrolls instead (horizontal scrollbar for the row,
1064
1191
  * vertical scrollbar for the column). Defaults to `true`.
@@ -1089,7 +1216,7 @@ interface MultiSelectChoiceEditProps extends BaseColumnEditProps {
1089
1216
  declare function MultiSelectChoiceEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, validChoiceValues, invalidChoiceValues, sort, invalidValueBehavior, checkboxOrientation, wrapCheckboxes, minCount, maxCount, validate, }: MultiSelectChoiceEditProps): react_jsx_runtime.JSX.Element | null;
1090
1217
 
1091
1218
  /**
1092
- * Which control shape the lookup renders. Mirrors Blazor's `LookupEditType`.
1219
+ * Which control shape the lookup renders.
1093
1220
  */
1094
1221
  declare const LookupEditorType: {
1095
1222
  /**
@@ -1147,7 +1274,7 @@ interface LookupEditProps extends BaseColumnEditProps {
1147
1274
  radioButtonOrientation?: ChoiceOrientation;
1148
1275
  /**
1149
1276
  * Maximum height of the dropdown popup (AutoComplete + Dropdown modes).
1150
- * Beyond this height the listbox scrolls. Accepts any CSS length
1277
+ * Beyond this height the listbox scrolls. Accepts any CSS length
1151
1278
  * pixels (`'400px'`), viewport-relative (`'50vh'`), etc. Default
1152
1279
  * `'250px'`.
1153
1280
  */
@@ -1185,13 +1312,13 @@ interface LookupEditProps extends BaseColumnEditProps {
1185
1312
  * editor shapes via {@link editorType}:
1186
1313
  *
1187
1314
  * - **AutoComplete** (default) — debounced typeahead via Fluent {@link Combobox}.
1188
- * Polymorphic columns get a target-table picker rendered alongside the
1189
- * combobox; consumers can pin the initial target via {@link defaultTable}.
1315
+ * Polymorphic columns get a target-table picker rendered alongside the
1316
+ * combobox; consumers can pin the initial target via {@link defaultTable}.
1190
1317
  * - **Dropdown** — pre-fetched top-N records in a Fluent {@link Dropdown}.
1191
- * No typing; the user picks from the visible list.
1318
+ * No typing; the user picks from the visible list.
1192
1319
  * - **RadioButtons** — pre-fetched top-N records as a {@link RadioGroup}.
1193
- * Honors {@link displayNullChoice} for an explicit "(none)" radio and
1194
- * {@link radioButtonOrientation} for horizontal/vertical layout.
1320
+ * Honors {@link displayNullChoice} for an explicit "(none)" radio and
1321
+ * {@link radioButtonOrientation} for horizontal/vertical layout.
1195
1322
  *
1196
1323
  * **Search behavior:** When the target table has a Lookup view configured
1197
1324
  * (or a view is pinned via {@link defaultViewId}), the typed query is
@@ -1212,7 +1339,7 @@ interface LookupEditProps extends BaseColumnEditProps {
1212
1339
  declare function LookupEdit({ columnName, label, description, displayLabelWhenAvailable, descriptionLocation, displayValidationErrorMessage, required, readOnly, disabled, isVisible, className, style, id, editorType, maxRecordsReturned, placeholder, defaultTable, displayNullChoice, radioButtonOrientation, popupMaxHeight, popupMinHeight, defaultViewId, viewIds, validate, }: LookupEditProps): react_jsx_runtime.JSX.Element | null;
1213
1340
 
1214
1341
  /**
1215
- * Selectable render mode. Mirrors Blazor's `EditorType` pattern on other
1342
+ * Selectable render mode. Mirrors pattern on other
1216
1343
  * editors (`BoolEditorType`, `LookupEditorType`).
1217
1344
  */
1218
1345
  declare const ManyToManyLookupEditorType: {
@@ -1345,7 +1472,7 @@ type ColumnMetadataBase$2 = components['schemas']['ColumnMetadataBase'];
1345
1472
  /**
1346
1473
  * Meta-dispatcher edit component — renders the per-type edit
1347
1474
  * (`<TextEdit>`, `<NumberEdit>`, `<DateTimeEdit>`, etc.) that matches the
1348
- * column's metadata `$type` discriminator. Mirrors Blazor's
1475
+ * column's metadata `$type` discriminator.
1349
1476
  * `ColumnEdit.razor`, which big-ifs over `ColumnMetadata is XxxMetadata`
1350
1477
  * and forwards the same prop set.
1351
1478
  *
@@ -1361,20 +1488,20 @@ type ColumnMetadataBase$2 = components['schemas']['ColumnMetadataBase'];
1361
1488
  *
1362
1489
  * Type-code mapping (matches the C# `ColumnType` enum / OpenAPI's
1363
1490
  * `ColumnMetadataBase*` `$type` discriminators):
1364
- * 0 = Bool → BoolEdit
1365
- * 2 = DateTime → DateTimeEdit
1366
- * 3 = Decimal → NumberEdit
1367
- * 4 = Double → NumberEdit
1368
- * 5 = Int → NumberEdit
1369
- * 6 = Lookup → LookupEdit
1370
- * 7 = Memo → MemoEdit
1371
- * 8 = Money → MoneyEdit
1372
- * 11 = Choice → ChoiceEdit
1373
- * 14 = String → TextEdit
1374
- * 18 = BigInt → NumberEdit
1375
- * 40 = MultiSelectChoice → MultiSelectChoiceEdit
1376
- * 41 = File → FileEdit
1377
- * 42 = Image → ImageEdit
1491
+ * 0 = Bool → BoolEdit
1492
+ * 2 = DateTime → DateTimeEdit
1493
+ * 3 = Decimal → NumberEdit
1494
+ * 4 = Double → NumberEdit
1495
+ * 5 = Int → NumberEdit
1496
+ * 6 = Lookup → LookupEdit
1497
+ * 7 = Memo → MemoEdit
1498
+ * 8 = Money → MoneyEdit
1499
+ * 11 = Choice → ChoiceEdit
1500
+ * 14 = String → TextEdit
1501
+ * 18 = BigInt → NumberEdit
1502
+ * 40 = MultiSelectChoice → MultiSelectChoiceEdit
1503
+ * 41 = File → FileEdit
1504
+ * 42 = Image → ImageEdit
1378
1505
  *
1379
1506
  * `<ManyToManyLookupEdit>` is NOT dispatched here — many-to-many isn't a
1380
1507
  * column type (no `ColumnMetadata` variant for it); it's a relationship
@@ -1401,7 +1528,7 @@ declare function getEditComponentForMetadata(metadata: ColumnMetadataBase$2 | un
1401
1528
 
1402
1529
  /**
1403
1530
  * Options for {@link splitHighlightSegments}. Both fields mirror
1404
- * Blazor's `AccentInsensitiveHighlighter` parameters.
1531
+ * parameters.
1405
1532
  */
1406
1533
  interface SplitHighlightOptions {
1407
1534
  /**
@@ -1425,7 +1552,7 @@ interface SplitHighlightOptions {
1425
1552
  * independently and reused for non-React rendering paths (e.g. ARIA
1426
1553
  * labels, text-only fallbacks).
1427
1554
  *
1428
- * Mirrors Blazor's `AccentInsensitiveHighlighter`, which uses
1555
+ *, which uses
1429
1556
  * `CompareInfo.IndexOf` with `IgnoreCase | IgnoreNonSpace`. So `'cafe'`
1430
1557
  * highlights inside `'café'`, `'CAFÉ'`, `'café'`, etc.
1431
1558
  */
@@ -1446,7 +1573,7 @@ interface HighlighterProps {
1446
1573
  */
1447
1574
  searchText?: string | null;
1448
1575
  /**
1449
- * Characters that split the search term into independent tokens
1576
+ * Characters that split the search term into independent tokens
1450
1577
  * pass `' '` to highlight every space-separated word, `',. '` for
1451
1578
  * comma/period/space-tokenized, etc. When omitted (or empty), the
1452
1579
  * search term is matched verbatim.
@@ -1462,7 +1589,7 @@ interface HighlighterProps {
1462
1589
  }
1463
1590
  /**
1464
1591
  * Renders `text` with matching substrings wrapped in a `<mark>` so the user
1465
- * can see why each result was returned by a search. Mirrors Blazor's
1592
+ * can see why each result was returned by a search.
1466
1593
  * `AccentInsensitiveHighlighter`: matches are case- AND accent-insensitive
1467
1594
  * (NFD-decompose + strip combining marks + lowercase, the JS analog of
1468
1595
  * `CompareInfo` with `IgnoreCase | IgnoreNonSpace`).
@@ -1479,20 +1606,20 @@ type TableRecord$7 = Schemas['TableRecord'];
1479
1606
  type ColumnMetadataBase$1 = Schemas['ColumnMetadataBase'];
1480
1607
  /**
1481
1608
  * Resolves the display string for a column on a record — the value a
1482
- * user would see in a grid cell or lookup option. Mirrors Blazor's
1609
+ * user would see in a grid cell or lookup option.
1483
1610
  * `GridViewColumnDisplayValueResolver.ResolveDisplayValue`.
1484
1611
  *
1485
1612
  * **Resolution order:**
1486
1613
  *
1487
1614
  * 1. `record.formattedValues[columnName]` — Dataverse's server-side
1488
- * pre-formatted localized string. Covers choices (localized label),
1489
- * dates (locale-formatted), numbers (thousands separators), money
1490
- * (currency symbol + locale), bool (Yes/No), and is the most reliable
1491
- * source when available.
1615
+ * pre-formatted localized string. Covers choices (localized label),
1616
+ * dates (locale-formatted), numbers (thousands separators), money
1617
+ * (currency symbol + locale), bool (Yes/No), and is the most reliable
1618
+ * source when available.
1492
1619
  * 2. The raw `record.properties[columnName]` value, with type-aware
1493
- * fallback rendering. String → as-is. Lookup → the lookup's `name`.
1494
- * Numeric → `String(value)`. File/Image GUIDs / byte arrays →
1495
- * `null` (no useful display in a row context).
1620
+ * fallback rendering. String → as-is. Lookup → the lookup's `name`.
1621
+ * Numeric → `String(value)`. File/Image GUIDs / byte arrays →
1622
+ * `null` (no useful display in a row context).
1496
1623
  * 3. `null` if the column isn't present on the record.
1497
1624
  *
1498
1625
  * Exposed alongside the lookup edit so consumers writing their own
@@ -1507,9 +1634,9 @@ declare function resolveColumnDisplayValue(record: TableRecord$7, columnName: st
1507
1634
  *
1508
1635
  * - `url`: passed straight through.
1509
1636
  * - `base64`: rendered as a `data:<mime>;base64,<value>` URL — no allocation,
1510
- * no cleanup, but bytes are duplicated through the parser.
1637
+ * no cleanup, but bytes are duplicated through the parser.
1511
1638
  * - `bytes`: wrapped in a `Blob` and exposed via `URL.createObjectURL`. The
1512
- * resulting `blob:` URL is revoked on cleanup so memory doesn't leak.
1639
+ * resulting `blob:` URL is revoked on cleanup so memory doesn't leak.
1513
1640
  */
1514
1641
  type ImageSource = {
1515
1642
  kind: 'url';
@@ -1573,7 +1700,7 @@ interface ImageViewerProps {
1573
1700
  *
1574
1701
  * - With `toolbar`, adds a download button to the toolbar.
1575
1702
  * - With `framed` (no toolbar), renders a download button overlay in the
1576
- * corner.
1703
+ * corner.
1577
1704
  * - Without either, makes the image itself click-to-download.
1578
1705
  *
1579
1706
  * Inline `base64`/`bytes` sources download the bytes directly. `url`
@@ -1597,10 +1724,10 @@ interface ImageViewerProps {
1597
1724
  * When true (and `toolbar` is also true), enables crop interactions:
1598
1725
  *
1599
1726
  * - Right-click drag on the image draws a dashed selection rectangle
1600
- * (with the current aspect ratio applied if not `'free'`).
1727
+ * (with the current aspect ratio applied if not `'free'`).
1601
1728
  * - The toolbar gains an aspect-ratio menu and a Crop button.
1602
1729
  * - The Crop button rasterizes the selection to a PNG and fires
1603
- * `onCropApplied`. The viewer then displays the cropped result.
1730
+ * `onCropApplied`. The viewer then displays the cropped result.
1604
1731
  * - Reset clears the local crop and reverts to the original `source`.
1605
1732
  */
1606
1733
  croppable?: boolean;
@@ -1624,7 +1751,7 @@ interface ImageViewerProps {
1624
1751
  * (rotation, flip, zoom, pan) don't toggle dirty on their own — they
1625
1752
  * don't generate new bytes unless they're folded into a crop.
1626
1753
  */
1627
- onDirtyChange?: (isDirty: boolean) => void;
1754
+ onDirtyChanged?: (isDirty: boolean) => void;
1628
1755
  /**
1629
1756
  * When set together with `toolbar`, renders a green checkmark button at
1630
1757
  * the right end of the toolbar. The button is disabled while the viewer
@@ -1699,7 +1826,7 @@ interface ImageViewerHandle {
1699
1826
  }
1700
1827
  /**
1701
1828
  * Standalone image viewer. Accepts a URL, a base64 string, or a `Uint8Array`,
1702
- * resolves it to an `<img>` `src`, and renders. Defaults to a bare `<img>`
1829
+ * resolves it to an `<img>` `src`, and renders. Defaults to a bare `<img>`
1703
1830
  * the optional `framed` / `toolbar` / `downloadable` props add chrome on
1704
1831
  * demand.
1705
1832
  *
@@ -1714,9 +1841,9 @@ declare const ImageViewer: react.ForwardRefExoticComponent<ImageViewerProps & re
1714
1841
  * dispatcher can categorize a remote file without a network round-trip.
1715
1842
  *
1716
1843
  * - `url`: the value is passed straight to renderers that accept URLs
1717
- * (`<img>`, `<iframe>`); for text/markdown we `fetch` it and read text.
1844
+ * (`<img>`, `<iframe>`); for text/markdown we `fetch` it and read text.
1718
1845
  * - `base64`: decoded once per resolution and either text-decoded (for
1719
- * text/markdown) or wrapped in an object URL (for embedded iframes).
1846
+ * text/markdown) or wrapped in an object URL (for embedded iframes).
1720
1847
  * - `bytes`: same as `base64` but skips the decode step.
1721
1848
  */
1722
1849
  type FileSource = {
@@ -1757,6 +1884,14 @@ interface FileViewerProps {
1757
1884
  * iframe). Sets the scrollable viewport. Default: <c>60vh</c>.
1758
1885
  */
1759
1886
  maxHeight?: string | number;
1887
+ /**
1888
+ * When `true` (the default), shows a download button in the top-right
1889
+ * corner of every previewable arm (markdown, text, embedded, zip) and as
1890
+ * the primary action on the unsupported-file card. The image arm renders
1891
+ * the button via the nested {@link ImageViewer} chrome instead — same
1892
+ * behavior, same icon, just owned one layer deeper.
1893
+ */
1894
+ downloadable?: boolean;
1760
1895
  }
1761
1896
  /**
1762
1897
  * Standalone file viewer that auto-detects how to render its source.
@@ -1768,7 +1903,7 @@ interface FileViewerProps {
1768
1903
  * by the file extension. Unknown types fall through to the download
1769
1904
  * card so consumers always get a usable result.
1770
1905
  */
1771
- declare function FileViewer({ source, fileName, className, style, id, fallback, maxHeight, }: FileViewerProps): react_jsx_runtime.JSX.Element;
1906
+ declare function FileViewer({ source, fileName, className, style, id, fallback, maxHeight, downloadable, }: FileViewerProps): react_jsx_runtime.JSX.Element;
1772
1907
 
1773
1908
  /**
1774
1909
  * Fluent UI implementation of {@link DialogService}. Mount a single
@@ -1777,10 +1912,9 @@ declare function FileViewer({ source, fileName, className, style, id, fallback,
1777
1912
  * renders one Fluent `Dialog` at a time, queuing additional requests so
1778
1913
  * concurrent calls don't lose each other.
1779
1914
  *
1780
- * Drop-in replacement for Blazor's DI registration of `IDialogService` +
1781
- * `IPowerPortalsProDialogService` in `PowerPortalsProWebBlazorFluentUI`same
1782
- * concrete behavior (success / warning / error / info / confirmation dialogs),
1783
- * just plumbed through React context instead of constructor-injected services.
1915
+ * Implements the standard PowerPortalsPro dialog contract success,
1916
+ * warning, error, info, and confirmation dialogs plumbed through React
1917
+ * context.
1784
1918
  *
1785
1919
  * Single-button dialogs (success/warning/error/info) resolve with
1786
1920
  * `{ cancelled: false }` regardless of whether the user clicked the button or
@@ -1794,7 +1928,7 @@ declare function FluentDialogProvider({ children }: {
1794
1928
  }): react_jsx_runtime.JSX.Element;
1795
1929
 
1796
1930
  /**
1797
- * Theme mode the user has selected. Mirrors Blazor's
1931
+ * Theme mode the user has selected.
1798
1932
  * `DesignThemeModes` enum (Light = 0, Dark = 1, System = 2).
1799
1933
  * Hybrid const-object + literal-union pattern so consumers can compare
1800
1934
  * via either string literal or the constant.
@@ -1806,23 +1940,29 @@ declare const ThemeMode: {
1806
1940
  };
1807
1941
  type ThemeMode = (typeof ThemeMode)[keyof typeof ThemeMode];
1808
1942
  /**
1809
- * Accent color slot the theme provider resolves to a Fluent v9
1810
- * theme. Mirrors Blazor's `OfficeColor` enum at the surface level
1811
- * but with a narrower set of out-of-the-box options — consumers
1812
- * register more via `<PowerPortalsProThemeProvider customAccents={...}>`.
1943
+ * Accent color slot the theme provider resolves to a Fluent v9 theme.
1944
+ * The full FluentUI Blazor `OfficeColor` palette ships built-in parity
1945
+ * with the Blazor `<ThemeColorSelector>` picker, no per-app wiring.
1813
1946
  *
1814
1947
  * Built-in values:
1815
- * - `'default'` — Fluent v9 Communication Blue (`webLightTheme` /
1816
- * `webDarkTheme`).
1817
- * - `'teams'` — Fluent v9 Teams Purple (`teamsLightTheme` /
1818
- * `teamsDarkTheme`).
1819
- *
1820
- * Custom keys are any string the consumer registers; they take
1948
+ * - `'default'` — Fluent v9 Communication Blue (`webLightTheme` /
1949
+ * `webDarkTheme`).
1950
+ * - `'teams'` — Fluent v9 Teams Purple (`teamsLightTheme` /
1951
+ * `teamsDarkTheme`).
1952
+ * - The Office-brand accents: `'access'`, `'booking'`, `'exchange'`,
1953
+ * `'excel'`, `'group-me'`, `'office'`, `'one-note'`, `'outlook'`,
1954
+ * `'planner'`, `'power-apps'`, `'power-bi'`, `'power-point'`,
1955
+ * `'publisher'`, `'stream'`, `'sway'`, `'visio'`, `'word'`, `'yammer'`
1956
+ * — each generated from its `OfficeColor` base hex. See
1957
+ * `OFFICE_ACCENT_DEFINITIONS`.
1958
+ *
1959
+ * Consumers register more (or override a built-in) via
1960
+ * `<PowerPortalsProThemeProvider customAccents={...}>`; custom keys take
1821
1961
  * priority over built-ins when names collide.
1822
1962
  */
1823
1963
  type AccentColor = 'default' | 'teams' | (string & {});
1824
1964
  /**
1825
- * Text-direction preference. Mirrors Blazor's `ThemeTextDirection`
1965
+ * Text-direction preference. Mirrors
1826
1966
  * boolean toggle but as a literal-union for parity with the rest of
1827
1967
  * the theme enums.
1828
1968
  */
@@ -1922,10 +2062,13 @@ interface PowerPortalsProThemeProviderProps {
1922
2062
  */
1923
2063
  defaultTextDirection?: TextDirection;
1924
2064
  /**
1925
- * Consumer-supplied custom accents. Each key registers as an
1926
- * available `<ThemeColorSelector>` option. Built-ins (`'default'`,
1927
- * `'teams'`) can be overridden by registering a key with the same
1928
- * name. Construct light / dark variants via `createLightTheme(...)`
2065
+ * Consumer-supplied custom accents, layered ON TOP of the built-in
2066
+ * Office-brand palette (`'default'`, `'teams'`, `'excel'`, `'word'`,
2067
+ * the full FluentUI Blazor `OfficeColor` set ships out of the
2068
+ * box). Each key registers as an additional `<ThemeColorSelector>`
2069
+ * option; registering a key that matches a built-in (e.g. `'default'`)
2070
+ * overrides it with your own brand. Construct light / dark variants
2071
+ * via `createLightTheme(...)`
1929
2072
  * / `createDarkTheme(...)` from `@fluentui/react-components`, fed
1930
2073
  * with the `BrandVariants` 16-stop ramp.
1931
2074
  *
@@ -1933,12 +2076,12 @@ interface PowerPortalsProThemeProviderProps {
1933
2076
  * import { createLightTheme, createDarkTheme } from '@fluentui/react-components';
1934
2077
  * const forest = { 10: '#001805', ..., 160: '#FFFFFF' };
1935
2078
  * <PowerPortalsProThemeProvider
1936
- * customAccents={{
1937
- * forest: {
1938
- * light: createLightTheme(forest),
1939
- * dark: createDarkTheme(forest),
1940
- * },
1941
- * }}
2079
+ * customAccents={{
2080
+ * forest: {
2081
+ * light: createLightTheme(forest),
2082
+ * dark: createDarkTheme(forest),
2083
+ * },
2084
+ * }}
1942
2085
  * >
1943
2086
  * ```
1944
2087
  */
@@ -1976,7 +2119,7 @@ interface PowerPortalsProThemeProviderProps {
1976
2119
  * `<ThemeSelector>` / `<SiteSettingsButton>` UIs read/write the
1977
2120
  * preference via `useTheme()`.
1978
2121
  *
1979
- * Mirrors Blazor's `<ThemeProvider>` + `FluentDesignTheme`
2122
+ * Mirrors + `FluentDesignTheme`
1980
2123
  * combination, condensed into a single React component since the
1981
2124
  * React FluentProvider already owns the design-token cascade. Cross-
1982
2125
  * stack consumers picking different storage keys keep their state
@@ -1985,7 +2128,7 @@ interface PowerPortalsProThemeProviderProps {
1985
2128
  *
1986
2129
  * ```tsx
1987
2130
  * <PowerPortalsProThemeProvider style={{ height: '100%' }}>
1988
- * <App />
2131
+ * <App />
1989
2132
  * </PowerPortalsProThemeProvider>
1990
2133
  * ```
1991
2134
  */
@@ -2007,7 +2150,7 @@ interface ThemeSelectorProps {
2007
2150
  }
2008
2151
  /**
2009
2152
  * Dropdown that lets the user pick between Light, Dark, and System
2010
- * (follow OS preference) themes. Mirrors Blazor's `<ThemeSelector>`.
2153
+ * (follow OS preference) themes.
2011
2154
  * Reads/writes the preference via {@link useTheme} — wrap in a
2012
2155
  * `<PowerPortalsProThemeProvider>` for it to function.
2013
2156
  */
@@ -2038,15 +2181,16 @@ interface ThemeColorSelectorProps {
2038
2181
  accentLabels?: Readonly<Record<string, string>>;
2039
2182
  }
2040
2183
  /**
2041
- * Dropdown that lets the user pick the active accent color. Mirrors
2042
- * Blazor's `<ThemeColorSelector>`. Reads / writes the preference via
2043
- * {@link useTheme} — wrap in `<PowerPortalsProThemeProvider>` for it
2044
- * to function.
2184
+ * Dropdown that lets the user pick the active accent color. Reads /
2185
+ * writes the preference via {@link useTheme} wrap in
2186
+ * `<PowerPortalsProThemeProvider>` for it to function.
2045
2187
  *
2046
- * Built-ins are `'default'` (Fluent v9 Communication Blue) and
2047
- * `'teams'` (Teams Purple). Consumer-registered customs via
2188
+ * Ships the full FluentUI Blazor `OfficeColor` palette built-in
2189
+ * `'default'`, `'teams'`, and the 18 Office-brand accents (`'excel'`,
2190
+ * `'word'`, `'power-bi'`, …) — for parity with the Blazor picker, with
2191
+ * no per-app configuration. Consumer-registered customs via
2048
2192
  * `<PowerPortalsProThemeProvider customAccents={...}>` appear in the
2049
- * dropdown automatically no per-call configuration required.
2193
+ * dropdown automatically alongside them.
2050
2194
  *
2051
2195
  * Option labels resolve via the localizer:
2052
2196
  * `app.components.theme-color-selector.accent.<key>`. Missing keys
@@ -2055,6 +2199,102 @@ interface ThemeColorSelectorProps {
2055
2199
  */
2056
2200
  declare function ThemeColorSelector({ readOnly, label, width, accentLabels, }: ThemeColorSelectorProps): react_jsx_runtime.JSX.Element;
2057
2201
 
2202
+ /**
2203
+ * Canonical accent definition. One entry per visually-distinct brand
2204
+ * color sourced from FluentUI Blazor's `OfficeColor` enum (read via
2205
+ * `OfficeColorUtilities.ToAttributeValue(...)`).
2206
+ */
2207
+ interface OfficeAccentDefinition {
2208
+ /**
2209
+ * Accent key as used by `setAccentColor` and the `<ThemeColorSelector>`
2210
+ * picker (kebab-case, matching the localization key under
2211
+ * `app.components.theme-color-selector.accent.<name>`).
2212
+ */
2213
+ readonly name: string;
2214
+ /**
2215
+ * Representative brand hex (lands at `BrandVariants` stop 80 — the
2216
+ * recognizable "this is the brand color" shade). Drives both the
2217
+ * generated theme ramp and the picker's color swatch.
2218
+ */
2219
+ readonly hex: string;
2220
+ /**
2221
+ * Canonical FluentUI `OfficeColor` enum integer for this brand. When
2222
+ * several enum values share the same hex (Exchange / OneDrive /
2223
+ * SharePoint / Skype / Windows all use `#0078d4`), this is the LOWEST
2224
+ * such index — the first enum value that introduces the color.
2225
+ */
2226
+ readonly officeColorIndex: number;
2227
+ /**
2228
+ * Every FluentUI `OfficeColor` enum NAME (PascalCase) that resolves to
2229
+ * this accent. Multiple names collapse onto one accent because the
2230
+ * Blazor side computes identical hex for sibling brands. Used to build
2231
+ * the {@link OFFICE_COLOR_NAME_TO_ACCENT} interop map.
2232
+ */
2233
+ readonly officeColorNames: readonly string[];
2234
+ }
2235
+ /**
2236
+ * The full accent set, mirroring FluentUI Blazor's `OfficeColor` picker.
2237
+ * DEDUPLICATED by hex — the 25 `OfficeColor` enum values collapse to 20
2238
+ * visually-distinct accents (Exchange / OneDrive / SharePoint / Skype /
2239
+ * Windows all share `#0078d4`; Planner / Project share `#31752f`), so
2240
+ * the picker shows one swatch per color instead of repeating identical
2241
+ * swatches under different brand names. The {@link OFFICE_COLOR_NAME_TO_ACCENT}
2242
+ * map preserves the full 25→20 name mapping for Blazor interop.
2243
+ *
2244
+ * Order is the picker order: `default` first, then the brands roughly
2245
+ * alphabetically (with `teams` in its alphabetical slot).
2246
+ */
2247
+ declare const OFFICE_ACCENT_DEFINITIONS: readonly OfficeAccentDefinition[];
2248
+ /**
2249
+ * Built-in accent themes for `<PowerPortalsProThemeProvider>`, keyed by
2250
+ * accent name (`'default'`, `'access'`, `'excel'`, …). Every consumer's
2251
+ * `<ThemeColorSelector>` shows this full set out of the box — parity with
2252
+ * FluentUI Blazor's `OfficeColor` picker, with no per-app wiring.
2253
+ *
2254
+ * `'default'` and `'teams'` resolve to FluentUI's hand-tuned `webLight`/
2255
+ * `webDark` and `teamsLight`/`teamsDark` themes — the first-class Fluent
2256
+ * v9 themes, not HSL approximations. The remaining 18 brand accents are
2257
+ * generated from each `OfficeColor` base hex via an HSL-based
2258
+ * `BrandVariants` ramp (an approximation of FluentUI's hand-tuned
2259
+ * `webBrandVariants` — close enough that the primary accent visually
2260
+ * tracks the brand; tighter parity would require porting the FluentUI
2261
+ * Theme Designer's perceptual color algorithm).
2262
+ *
2263
+ * Consumers can register additional accents — or override any of these —
2264
+ * via `<PowerPortalsProThemeProvider customAccents={...}>`.
2265
+ */
2266
+ declare const OFFICE_ACCENT_THEMES: Readonly<Record<string, AccentThemePair>>;
2267
+ /**
2268
+ * Interop: FluentUI Blazor's `<fluent-design-theme>` persists the active
2269
+ * accent as the `OfficeColor` enum NAME (PascalCase, e.g. `"Access"`,
2270
+ * `"SharePoint"`) — both in `localStorage["theme"].primaryColor` and as
2271
+ * the `primary-color` attribute. Maps each of the 25 enum names to the
2272
+ * matching React accent name so a cross-stack consumer can sync a Blazor
2273
+ * host's accent into the React provider via `setAccentColor`.
2274
+ *
2275
+ * Several names collapse onto one accent (Exchange / OneDrive /
2276
+ * SharePoint / Skype / Windows → `'exchange'`; Planner / Project →
2277
+ * `'planner'`) because the Blazor side computes identical hex for them.
2278
+ */
2279
+ declare const OFFICE_COLOR_NAME_TO_ACCENT: Readonly<Record<string, string>>;
2280
+ /**
2281
+ * Interop: reverse lookup from a lowercased `#rrggbb` hex to the React
2282
+ * accent name. Covers the FluentUI Blazor `CustomColor` code path, where
2283
+ * the host exposes the accent as a raw hex rather than an enum name.
2284
+ */
2285
+ declare const OFFICE_ACCENT_HEX_TO_NAME: Readonly<Record<string, string>>;
2286
+ /**
2287
+ * Resolves a value persisted by FluentUI Blazor's accent picker to a
2288
+ * React accent name registered in {@link OFFICE_ACCENT_THEMES}. Accepts
2289
+ * either a raw hex (the `CustomColor` path) or a PascalCase `OfficeColor`
2290
+ * enum name (the common path). Returns `null` for unrecognized values so
2291
+ * callers can fall back to the provider's default rather than throwing.
2292
+ *
2293
+ * Pair with `setAccentColor` to mirror a Blazor host's accent into a
2294
+ * React `<PowerPortalsProThemeProvider>`.
2295
+ */
2296
+ declare function officeColorValueToAccentName(raw: string | null | undefined): string | null;
2297
+
2058
2298
  interface ThemeTextDirectionProps {
2059
2299
  /** Disable the control. */
2060
2300
  readOnly?: boolean;
@@ -2068,7 +2308,7 @@ interface ThemeTextDirectionProps {
2068
2308
  }
2069
2309
  /**
2070
2310
  * Dropdown that lets the user pick the active text direction (LTR or
2071
- * RTL). Mirrors Blazor's `<ThemeTextDirection>`. The choice flows
2311
+ * RTL). The choice flows
2072
2312
  * through `<PowerPortalsProThemeProvider>` into
2073
2313
  * `<FluentProvider dir>` which cascades to every Fluent v9
2074
2314
  * component below.
@@ -2119,19 +2359,20 @@ interface LanguageDropdownProps {
2119
2359
  }
2120
2360
  /**
2121
2361
  * Dropdown that lets the user pick the active UI locale. Mirrors
2122
- * Blazor's `<LanguageDropdown>` — selecting an option calls
2362
+ * — selecting an option calls
2123
2363
  * `setLocale()` from `useLocale()` and (by default) writes the ASP.NET
2124
2364
  * culture cookie so server-rendered requests pick up the same value.
2125
2365
  *
2126
2366
  * Pass `supportedLocales` to populate the option list. Without it, the
2127
2367
  * dropdown shows only the current locale and is effectively read-only.
2128
2368
  *
2129
- * Unlike Blazor, this does NOT trigger a full-page navigation on
2130
- * change the React app updates in place via the React-side
2131
- * `setLocale`. If you need a hard reload (e.g. the host page has
2132
- * server-rendered shells that need to re-emit with the new culture),
2133
- * subscribe to the cookie change separately or call
2134
- * `window.location.reload()` from a wrapper.
2369
+ * Switch behavior follows the server's configured `UrlCultureStrategy`
2370
+ * (read from the localization manifest): under a prefix strategy
2371
+ * (`PathPrefix` / `PathPrefixAll`) the locale lives in the URL, so selecting
2372
+ * a language navigates to the new `/{locale}` URL and the server re-renders
2373
+ * under the matching base href. Under `CookieOnly` — or before the manifest
2374
+ * resolves / when no framework localizer is mounted — the React app updates
2375
+ * in place via `setLocale`, no navigation.
2135
2376
  */
2136
2377
  declare function LanguageDropdown({ supportedLocales, label, displayNativeLanguage, width, readOnly, persistToCookie, }: LanguageDropdownProps): react_jsx_runtime.JSX.Element;
2137
2378
 
@@ -2163,7 +2404,7 @@ interface ProfileMainMenuProps {
2163
2404
  /**
2164
2405
  * Rendered when the user is anonymous. Receives nothing — wire to
2165
2406
  * your router for sign-in / register links. When omitted, the menu
2166
- * renders a single "Sign in" button that calls `useAuth().login`
2407
+ * renders a single "Sign in" button that calls `useAuth().login`
2167
2408
  * useful for apps with a separate `/login` page rather than an
2168
2409
  * inline form.
2169
2410
  */
@@ -2177,7 +2418,7 @@ interface ProfileMainMenuProps {
2177
2418
  /**
2178
2419
  * Avatar-triggered popover with the signed-in user's identity + a
2179
2420
  * logout action, plus an optional Account link and anonymous-state
2180
- * UI. Mirrors Blazor's `<ProfileMainMenu>`.
2421
+ * UI.
2181
2422
  *
2182
2423
  * When the signed-in user has a sibling Dataverse identity registered
2183
2424
  * (a contact↔systemuser pair — the framework's `UserManager.GetClaimsAsync`
@@ -2190,12 +2431,12 @@ interface ProfileMainMenuProps {
2190
2431
  * `<PowerPortalsProProvider>` for it to function.
2191
2432
  *
2192
2433
  * Three render branches:
2193
- * - `loading`: renders a placeholder avatar with no popover so the
2194
- * layout doesn't reflow when the auth call lands.
2195
- * - `authenticated`: avatar with the user's initials → popover with
2196
- * identity + (optional) switch-identity + logout + optional Account link.
2197
- * - `anonymous`: a "Sign in" button (or consumer-supplied
2198
- * `anonymousContent`).
2434
+ * - `loading`: renders a placeholder avatar with no popover so the
2435
+ * layout doesn't reflow when the auth call lands.
2436
+ * - `authenticated`: avatar with the user's initials → popover with
2437
+ * identity + (optional) switch-identity + logout + optional Account link.
2438
+ * - `anonymous`: a "Sign in" button (or consumer-supplied
2439
+ * `anonymousContent`).
2199
2440
  */
2200
2441
  declare function ProfileMainMenu({ accountUrl, accountLabel, headerSlot, footerSlot, anonymousContent, signInUrl, }: ProfileMainMenuProps): react_jsx_runtime.JSX.Element;
2201
2442
 
@@ -2240,7 +2481,7 @@ interface SiteSettingsButtonProps {
2240
2481
  }
2241
2482
  /**
2242
2483
  * Gear-icon button that opens a side drawer with the user's site
2243
- * preferences (language + theme). Mirrors Blazor's
2484
+ * preferences (language + theme).
2244
2485
  * `<SiteSettingsButton>` / `<SiteSettingsPanel>` pair, condensed into
2245
2486
  * a single React component since the drawer state is local.
2246
2487
  *
@@ -2250,9 +2491,9 @@ interface SiteSettingsButtonProps {
2250
2491
  *
2251
2492
  * ```tsx
2252
2493
  * <header>
2253
- * <Logo />
2254
- * <SiteSettingsButton supportedLocales={['en', 'es', 'fr']} />
2255
- * <ProfileMainMenu accountUrl="/account/manage" />
2494
+ * <Logo />
2495
+ * <SiteSettingsButton supportedLocales={['en', 'es', 'fr']} />
2496
+ * <ProfileMainMenu accountUrl="/account/manage" />
2256
2497
  * </header>
2257
2498
  * ```
2258
2499
  */
@@ -2299,7 +2540,7 @@ interface SiteSettingsPanelProps {
2299
2540
  }
2300
2541
  /**
2301
2542
  * Stand-alone panel that bundles the language / theme / accent-color /
2302
- * text-direction site-preference controls. Mirrors Blazor's
2543
+ * text-direction site-preference controls.
2303
2544
  * `<SiteSettingsPanel>` — same configurable sections, just mounted
2304
2545
  * directly into your layout instead of inside the gear-icon drawer.
2305
2546
  *
@@ -2317,13 +2558,13 @@ interface SiteSettingsPanelProps {
2317
2558
  * ```tsx
2318
2559
  * // dedicated /settings page
2319
2560
  * <PageLayout
2320
- * header={<Title2>Preferences</Title2>}
2321
- * body={
2322
- * <SiteSettingsPanel
2323
- * allowRightToLeftChange
2324
- * supportedLocales={['en', 'es', 'fr']}
2325
- * />
2326
- * }
2561
+ * header={<Title2>Preferences</Title2>}
2562
+ * body={
2563
+ * <SiteSettingsPanel
2564
+ * allowRightToLeftChange
2565
+ * supportedLocales={['en', 'es', 'fr']}
2566
+ * />
2567
+ * }
2327
2568
  * />
2328
2569
  * ```
2329
2570
  */
@@ -2354,7 +2595,7 @@ interface LogoutButtonProps {
2354
2595
  onLoggedOut?: () => void | Promise<void>;
2355
2596
  /**
2356
2597
  * Fires when `useAuth().logout()` throws. When provided, takes over
2357
- * error display. When omitted, errors are swallowed silently
2598
+ * error display. When omitted, errors are swallowed silently
2358
2599
  * matches the `ProfileMainMenu` baseline (server-side cookie still in
2359
2600
  * place on failure; user can retry).
2360
2601
  */
@@ -2363,7 +2604,7 @@ interface LogoutButtonProps {
2363
2604
  className?: string;
2364
2605
  }
2365
2606
  /**
2366
- * Standalone "Sign out" button. Mirrors Blazor's `<LogoutButton>`. Click
2607
+ * Standalone "Sign out" button. Click
2367
2608
  * fires `useAuth().logout()` which clears the session cookie server-side
2368
2609
  * and transitions the React auth state to `anonymous`. Default styling
2369
2610
  * matches the logout entry inside `<ProfileMainMenu>`; the two can
@@ -2375,6 +2616,40 @@ interface LogoutButtonProps {
2375
2616
  */
2376
2617
  declare function LogoutButton({ label, icon, appearance, disabled, onLoggedOut, onError, className, }: LogoutButtonProps): react_jsx_runtime.JSX.Element;
2377
2618
 
2619
+ /**
2620
+ * Horizontal menu bar that overflows extra items into a popover. Mirrors
2621
+ * — typical contents are context-action buttons
2622
+ * (`<SaveContextButton>`, `<RefreshContextButton>`, `<DeleteContextButton>`,
2623
+ * etc.) laid out left-to-right; if the container shrinks past what fits,
2624
+ * the trailing items collapse into a "more" popover triggered by a
2625
+ * vertical-ellipsis button on the inline-end edge.
2626
+ *
2627
+ * Built on Fluent UI v9's `<Overflow>` primitive — `useOverflowMenu` /
2628
+ * `useIsOverflowItemVisible` measure the container at runtime and decide
2629
+ * which children sit in the row vs. the popover. Resize-aware out of the
2630
+ * box.
2631
+ *
2632
+ * Each child is rendered twice — once in the row (via `<OverflowItem>`) and
2633
+ * once inside the overflow popover (only visible when the row's copy is
2634
+ * hidden). Both copies share their own state, so a button clicked in either
2635
+ * place fires the same handler.
2636
+ */
2637
+ interface MenuBarProps {
2638
+ /** Menu items (typically action buttons) laid out horizontally. */
2639
+ children?: ReactNode;
2640
+ /** Extra CSS class on the outer container. */
2641
+ className?: string;
2642
+ /** Inline styles on the outer container. */
2643
+ style?: CSSProperties;
2644
+ /**
2645
+ * Accessible label for the "more items" overflow trigger. Defaults to
2646
+ * `"{count} more items"` derived from the live overflow count. Pass a
2647
+ * localized string when consuming under a non-English UI.
2648
+ */
2649
+ overflowLabel?: string;
2650
+ }
2651
+ declare function MenuBar({ children, className, style, overflowLabel }: MenuBarProps): react_jsx_runtime.JSX.Element;
2652
+
2378
2653
  type NavMatchMode = 'exact' | 'prefix';
2379
2654
  interface NavMenuProps {
2380
2655
  /** `<NavGroup>` children, each typically wrapping `<NavItem>` links. May be wrapped in `<AuthorizedView>` for auth-gated groups. */
@@ -2415,7 +2690,7 @@ interface NavItemProps {
2415
2690
  * How the current route is matched against {@link to}:
2416
2691
  * - `'exact'` (default for `to="/"`): only when pathname equals `to`.
2417
2692
  * - `'prefix'` (default everywhere else): also when pathname starts with `to + '/'`,
2418
- * so `/Accounts/Account/123` highlights `/Accounts`.
2693
+ * so `/Accounts/Account/123` highlights `/Accounts`.
2419
2694
  */
2420
2695
  match?: NavMatchMode;
2421
2696
  /** Link label. */
@@ -2457,7 +2732,7 @@ declare function NavItem({ to, icon, children }: NavItemProps): react_jsx_runtim
2457
2732
  *
2458
2733
  * Scoped overlays (those with a `targetId`) are NOT rendered here — they're
2459
2734
  * routed to a matching `<FluentOverlayTarget>` mounted inside whichever
2460
- * subtree should host them. Mirrors Blazor's split between the global
2735
+ * subtree should host them.
2461
2736
  * `<OverlayProvider>` (no `TargetId`) and per-component `<OverlayProvider TargetId="…">`.
2462
2737
  */
2463
2738
  declare function FluentOverlayProvider({ children }: {
@@ -2466,18 +2741,18 @@ declare function FluentOverlayProvider({ children }: {
2466
2741
  /**
2467
2742
  * Scoped overlay container. Wraps `children` in a `position: relative` div
2468
2743
  * and renders the topmost overlay for `targetId` as an absolutely-positioned
2469
- * scrim covering the wrapper. Mirrors Blazor's per-target `<OverlayProvider>`.
2744
+ * scrim covering the wrapper.
2470
2745
  *
2471
2746
  * Typical use is alongside `<RecordContext>` to scope its loading overlay to
2472
2747
  * the record's region of the page:
2473
2748
  *
2474
2749
  * ```tsx
2475
2750
  * <RecordContext table="contact" id={id}>
2476
- * {(ctx) => (
2477
- * <FluentOverlayTarget targetId={ctx.overlayTargetId}>
2478
- * <Form />
2479
- * </FluentOverlayTarget>
2480
- * )}
2751
+ * {(ctx) => (
2752
+ * <FluentOverlayTarget targetId={ctx.overlayTargetId}>
2753
+ * <Form />
2754
+ * </FluentOverlayTarget>
2755
+ * )}
2481
2756
  * </RecordContext>
2482
2757
  * ```
2483
2758
  *
@@ -2485,12 +2760,12 @@ declare function FluentOverlayProvider({ children }: {
2485
2760
  *
2486
2761
  * ```tsx
2487
2762
  * function RecordPanel() {
2488
- * const ctx = useRecordContext();
2489
- * return (
2490
- * <FluentOverlayTarget targetId={ctx.overlayTargetId}>
2491
- * <Form />
2492
- * </FluentOverlayTarget>
2493
- * );
2763
+ * const ctx = useRecordContext();
2764
+ * return (
2765
+ * <FluentOverlayTarget targetId={ctx.overlayTargetId}>
2766
+ * <Form />
2767
+ * </FluentOverlayTarget>
2768
+ * );
2494
2769
  * }
2495
2770
  * ```
2496
2771
  */
@@ -2538,7 +2813,7 @@ interface LocalizationBoundaryProps {
2538
2813
  * Holds off rendering `children` until every expected localization
2539
2814
  * prefix has been settled — the framework's default bundle (Tier 1),
2540
2815
  * any `prefixes` declared on the provider, and any declared on this
2541
- * boundary. Mirrors Blazor's `<LocalizationBoundary>` with the
2816
+ * boundary. Mirrors with the
2542
2817
  * equivalent fetch-then-render gate.
2543
2818
  *
2544
2819
  * **Once-loaded stickiness.** After the first time the boundary's
@@ -2566,21 +2841,73 @@ interface LocalizationBoundaryProps {
2566
2841
  * @example
2567
2842
  * ```tsx
2568
2843
  * <LocalizationBoundary prefixes={['tables.account']}>
2569
- * <EditAccountPage />
2844
+ * <EditAccountPage />
2570
2845
  * </LocalizationBoundary>
2571
2846
  * ```
2572
2847
  *
2573
2848
  * @example Root gate (wait for default bundle + provider baselines):
2574
2849
  * ```tsx
2575
2850
  * <PowerPortalsProProvider localizationPrefixes={['tables.contact']}>
2576
- * <LocalizationBoundary>
2577
- * <App />
2578
- * </LocalizationBoundary>
2851
+ * <LocalizationBoundary>
2852
+ * <App />
2853
+ * </LocalizationBoundary>
2579
2854
  * </PowerPortalsProProvider>
2580
2855
  * ```
2581
2856
  */
2582
2857
  declare function LocalizationBoundary({ prefixes, fallback, children, }: LocalizationBoundaryProps): react_jsx_runtime.JSX.Element;
2583
2858
 
2859
+ interface LocalizationTranslatorProps {
2860
+ /** Optional extra class merged onto the component's outermost element. */
2861
+ className?: string;
2862
+ }
2863
+ /**
2864
+ * Self-gating "translate a localization file" panel — the React counterpart of the Blazor
2865
+ * `<LocalizationTranslator />`. Loads translation availability on mount, then:
2866
+ * renders nothing when translation isn't configured; an install prompt when the managed solution
2867
+ * is missing; otherwise the upload → translate → download workflow. Translation reuses the Dataverse
2868
+ * translation memory and reports translated-vs-reused counts; download per-language or all-as-zip.
2869
+ *
2870
+ * The panel does NOT enforce authorization — gate the host page yourself (e.g. wrap it in
2871
+ * `<AuthorizedView roles="SystemAdmin">`), matching how the Blazor demo page hosts the component.
2872
+ */
2873
+ declare function LocalizationTranslator({ className }: LocalizationTranslatorProps): react_jsx_runtime.JSX.Element;
2874
+
2875
+ interface LocalizationAdminProps {
2876
+ /** Optional extra class merged onto the component's outermost element. */
2877
+ className?: string;
2878
+ }
2879
+ /**
2880
+ * Admin inspector for the string-localization pipeline — the React counterpart of the
2881
+ * Blazor `<LocalizationAdmin />`. Renders the configured sources (directories, files,
2882
+ * table-localization mode, web-resource pattern, default culture) and a grid of the
2883
+ * per-source load records from the most recent warmup (load order, kind, cultures, key
2884
+ * counts, how many keys overrode an earlier source, duration, status), plus a reload
2885
+ * button, merged + per-source downloads, and the embedded `<LocalizationTranslator />`
2886
+ * panel (which self-hides unless a translation provider is configured server-side).
2887
+ *
2888
+ * The panel does NOT enforce authorization — gate the host page yourself (e.g. wrap it in
2889
+ * `<AuthorizedView roles="SystemAdmin">`), matching how the Blazor `<LocalizationAdmin />`
2890
+ * is hosted. Server-side the `/api/localizations/*` admin endpoints reject non-SystemAdmin
2891
+ * callers regardless.
2892
+ */
2893
+ declare function LocalizationAdmin({ className }: LocalizationAdminProps): react_jsx_runtime.JSX.Element;
2894
+
2895
+ interface CacheAdminProps {
2896
+ /** Optional extra class merged onto the component's outermost element. */
2897
+ className?: string;
2898
+ }
2899
+ /**
2900
+ * Cache-administration panel — lists every registered server-side cache and lets an admin
2901
+ * clear them all at once or one at a time, surfacing per-cache success/failure and elapsed
2902
+ * timing. Cache descriptions come from the framework-shipped `app.cache-descriptions.<Name>`
2903
+ * strings; a cache without a registered description renders just its button.
2904
+ *
2905
+ * The panel does NOT enforce authorization — gate the host page yourself (e.g. wrap it in
2906
+ * `<AuthorizedView roles="SystemAdmin">`), matching how the Blazor `<CacheAdmin />` is hosted.
2907
+ * Server-side the `/api/caches/*` endpoints reject non-SystemAdmin callers regardless.
2908
+ */
2909
+ declare function CacheAdmin({ className }: CacheAdminProps): react_jsx_runtime.JSX.Element;
2910
+
2584
2911
  interface ValidationSummaryProps {
2585
2912
  /**
2586
2913
  * Header text shown above the error list. Defaults to the localized
@@ -2601,7 +2928,7 @@ interface ValidationSummaryProps {
2601
2928
  /**
2602
2929
  * Lists every validation error in the surrounding {@link ValidationContext}
2603
2930
  * (or the subset matching {@link ValidationSummaryProps.columns}). Mirrors
2604
- * Blazor's `<ValidationSummary>` — intended for the top of a form so the
2931
+ * — intended for the top of a form so the
2605
2932
  * user sees a consolidated rollup alongside the per-field inline messages.
2606
2933
  *
2607
2934
  * Renders nothing when there are no errors (no empty MessageBar) so the
@@ -2685,7 +3012,7 @@ interface RefreshContextButtonProps {
2685
3012
  *
2686
3013
  * - Calls `onBeforeRefresh` (cancellable) on click.
2687
3014
  * - If the context has unsaved changes, prompts via the Dialog service
2688
- * ("You have unsaved changes…") and aborts on cancel.
3015
+ * ("You have unsaved changes…") and aborts on cancel.
2689
3016
  * - Awaits `refreshAll()` — own reload + nested descendants in one shot.
2690
3017
  * - Calls `onRefreshed` after success.
2691
3018
  *
@@ -2708,23 +3035,18 @@ interface DeleteContextButtonProps {
2708
3035
  * `() => window.history.back()` — pops the browser back one entry,
2709
3036
  * landing the user on whatever page brought them to this record.
2710
3037
  *
2711
- * Parity note: Blazor's `<DeleteContextButton>` uses
2712
- * `NavigationHistory.PopToPrevious()` (an in-app URL stack populated
2713
- * by `NavigationManager.LocationChanged`) and falls back to
2714
- * `history.back` only when that stack is empty. For the user, both
2715
- * land on the same page in the common in-app flow (the in-app history
2716
- * stack and the browser history mirror each other). Blazor's primitive
2717
- * exists to work around Blazor Server's server-side navigation state;
2718
- * a SPA's `window.history` already tracks the same URLs natively, so
2719
- * React doesn't need the extra stack.
3038
+ * Parity note: uses
3039
+ * SPA navigation already tracks every visited URL natively through
3040
+ * `window.history`, so `history.back()` is the right post-delete
3041
+ * default it lands the user on whatever page they came from.
2720
3042
  *
2721
3043
  * Override when the default isn't right — e.g. the record was opened
2722
3044
  * via deep link (no in-app history), or you want to land somewhere
2723
3045
  * specific:
2724
3046
  *
2725
- * `onDeleted={() => navigate('/accounts')}` (react-router)
2726
- * `onDeleted={() => navigate(-1)}` (react-router, equivalent to default)
2727
- * `onDeleted={() => router.push('/accounts')}` (TanStack Router)
3047
+ * `onDeleted={() => navigate('/accounts')}` (react-router)
3048
+ * `onDeleted={() => navigate(-1)}` (react-router, equivalent to default)
3049
+ * `onDeleted={() => router.push('/accounts')}` (TanStack Router)
2728
3050
  */
2729
3051
  onDeleted?: () => void | Promise<void>;
2730
3052
  /**
@@ -2742,10 +3064,10 @@ interface DeleteContextButtonProps {
2742
3064
  * Reads the record + its `permissions` from the nearest `RecordContext` and:
2743
3065
  *
2744
3066
  * - Disables when the current user lacks `TableSecurityPermission.Delete` on the
2745
- * record, when no record has loaded, or when the consumer forces `disabled`.
3067
+ * record, when no record has loaded, or when the consumer forces `disabled`.
2746
3068
  * - Calls `onBeforeDelete` (cancellable) on click.
2747
3069
  * - Prompts confirmation via the Dialog service — bound to the framework's
2748
- * default messaging; consumers can pre-empt by handling the click externally.
3070
+ * default messaging; consumers can pre-empt by handling the click externally.
2749
3071
  * - Calls `ppp.deleteRecordAsync(table, id)`.
2750
3072
  * - Calls `onDeleted` after success (default: `window.history.back()`).
2751
3073
  */
@@ -2780,7 +3102,7 @@ declare const GridButtonRole: {
2780
3102
  /** Deletes a record. */
2781
3103
  readonly Delete: "delete";
2782
3104
  /**
2783
- * Anything that doesn't fit the create/open/delete taxonomy
3105
+ * Anything that doesn't fit the create/open/delete taxonomy
2784
3106
  * refresh, link/unlink, custom export, etc. The grid doesn't
2785
3107
  * dispatch row-level interactions to `'other'` buttons; they're
2786
3108
  * triggered exclusively by their own click handlers.
@@ -2798,8 +3120,8 @@ type GridButtonRole = (typeof GridButtonRole)[keyof typeof GridButtonRole];
2798
3120
  declare function setGridButtonRole<P>(Component: ComponentType<P>, role: GridButtonRole): void;
2799
3121
  /**
2800
3122
  * Read the {@link GridButtonRole} a React element claims via either:
2801
- * 1. A `gridButtonRole` prop on the element (per-instance override).
2802
- * 2. The component's stamped default from {@link setGridButtonRole}.
3123
+ * 1. A `gridButtonRole` prop on the element (per-instance override).
3124
+ * 2. The component's stamped default from {@link setGridButtonRole}.
2803
3125
  *
2804
3126
  * Returns `null` when neither is set — the grid skips the element
2805
3127
  * for role-based dispatch but still renders it in the toolbar.
@@ -2835,7 +3157,7 @@ interface GridButtonRoleProps {
2835
3157
 
2836
3158
  /**
2837
3159
  * Selection-based visibility / enabled mode for grid toolbar buttons.
2838
- * Mirrors Blazor's `GridButtonBehavior` enum used by
3160
+ * Mirrors enum used by
2839
3161
  * `<NavigateRecordGridButton>` / `<GridButton>` consumers.
2840
3162
  *
2841
3163
  * Hybrid const-object + literal-union — same pattern other enums in
@@ -3051,9 +3373,9 @@ interface GridContextValue {
3051
3373
  * link click, single-record Open button click) to the right
3052
3374
  * registered handler based on the row's state:
3053
3375
  *
3054
- * - Synthetic `__pending-create-` id → create button's re-open
3055
- * handler (when registered).
3056
- * - Real Dataverse id → open button's handler (when registered).
3376
+ * - Synthetic `__pending-create-` id → create button's re-open
3377
+ * handler (when registered).
3378
+ * - Real Dataverse id → open button's handler (when registered).
3057
3379
  *
3058
3380
  * Falls back to the other handler when only one of the two is
3059
3381
  * registered. No-op when neither is mounted (the grid keeps the
@@ -3149,7 +3471,7 @@ interface GridContextValue {
3149
3471
  * to target).
3150
3472
  *
3151
3473
  * Entries carry the full {@link TableRecord} (not just a reference)
3152
- * so the grid can pin them as visible rows while they're queued
3474
+ * so the grid can pin them as visible rows while they're queued
3153
3475
  * matching the UX of pending row creates. The wire-side
3154
3476
  * `AssociateRequest` only carries `{tableName, id}`; the grid strips
3155
3477
  * down at request-build time.
@@ -3279,10 +3601,10 @@ interface GridButtonProps extends GridButtonRoleProps {
3279
3601
  tooltip?: string;
3280
3602
  /**
3281
3603
  * Forwarded onto Fluent's `Button.appearance`. Defaults to `"subtle"` so the
3282
- * button reads as transparent at rest and only paints a background on hover
3604
+ * button reads as transparent at rest and only paints a background on hover
3283
3605
  * matching the grid's built-in Refresh / Settings buttons. Override per-button
3284
3606
  * when a custom action wants a different visual weight (e.g. `"primary"` for a
3285
- * primary call-to-action). Mirrors the Blazor `<GridButton Appearance="...">`
3607
+ * primary call-to-action). Mirrors the
3286
3608
  * surface — same default (FAST `Stealth` there, Fluent v9 `"subtle"` here, both
3287
3609
  * resolve to transparent-at-rest with a hover fill).
3288
3610
  */
@@ -3302,7 +3624,7 @@ interface GridButtonProps extends GridButtonRoleProps {
3302
3624
  * when you need a custom action (a one-off export, a custom workflow
3303
3625
  * trigger, anything outside the typed-button taxonomy).
3304
3626
  *
3305
- * Mirrors Blazor's `<GridButton>` surface — selection-based visibility
3627
+ * Mirrors surface — selection-based visibility
3306
3628
  * + enabled gates, role marker for row-click dispatch, label + icon +
3307
3629
  * tooltip + appearance. Plumbed into the same {@link useGridContext}
3308
3630
  * grid-toolbar registry the typed buttons use, so a custom button
@@ -3318,21 +3640,21 @@ interface GridButtonProps extends GridButtonRoleProps {
3318
3640
  *
3319
3641
  * ```tsx
3320
3642
  * <MainGrid tableName="contact">
3321
- * <GridButtons>
3322
- * <NewRecordGridButton>
3323
- * <Section><SectionColumn><TextEdit columnName="firstname" /></SectionColumn></Section>
3324
- * </NewRecordGridButton>
3325
- *
3326
- * <GridButton
3327
- * label="Export selected"
3328
- * icon={<ArrowDownload20Regular />}
3329
- * enabledBehavior={GridButtonBehavior.OneOrMoreSelected}
3330
- * onClick={async (grid) => {
3331
- * const ids = grid.selectedRecords.map((r) => r.id!);
3332
- * await exportToCsvAsync(ids);
3333
- * }}
3334
- * />
3335
- * </GridButtons>
3643
+ * <GridButtons>
3644
+ * <NewRecordGridButton>
3645
+ * <Section><SectionColumn><TextEdit columnName="firstname" /></SectionColumn></Section>
3646
+ * </NewRecordGridButton>
3647
+ *
3648
+ * <GridButton
3649
+ * label="Export selected"
3650
+ * icon={<ArrowDownload20Regular />}
3651
+ * enabledBehavior={GridButtonBehavior.OneOrMoreSelected}
3652
+ * onClick={async (grid) => {
3653
+ * const ids = grid.selectedRecords.map((r) => r.id!);
3654
+ * await exportToCsvAsync(ids);
3655
+ * }}
3656
+ * />
3657
+ * </GridButtons>
3336
3658
  * </MainGrid>
3337
3659
  * ```
3338
3660
  */
@@ -3340,7 +3662,7 @@ declare function GridButton({ onClick, label, icon, visibilityBehavior, enabledB
3340
3662
 
3341
3663
  /**
3342
3664
  * Mutable context handed to a `<NavigateRecordGridButton>`'s
3343
- * `onClick` callback. Mirrors Blazor's `NavigateGridButtonContext`.
3665
+ * `onClick` callback.
3344
3666
  * The callback can rewrite `url` before navigation fires — useful
3345
3667
  * for view-aware routing (e.g. switch destination based on the
3346
3668
  * grid's active view's table).
@@ -3404,14 +3726,14 @@ interface NavigateRecordGridButtonProps extends GridButtonRoleProps {
3404
3726
  appearance?: ButtonProps['appearance'];
3405
3727
  }
3406
3728
  /**
3407
- * Generic grid toolbar navigation button. Mirrors Blazor's
3729
+ * Generic grid toolbar navigation button.
3408
3730
  * `<NavigateRecordGridButton>` — useful for navigation actions that
3409
3731
  * don't fit `<NavigateNewRecordGridButton>` / `<NavigateOpenRecordGridButton>`:
3410
3732
  * "View Details", "Print", "Open Audit Log", etc.
3411
3733
  *
3412
3734
  * Renders nothing when {@link buttonVisibleBehavior} doesn't match the
3413
- * current selection — same semantic Blazor uses (clean DOM, no
3414
- * disabled-style ghosting). Default role is `'other'` so this button
3735
+ * current selection (clean DOM, no disabled-style ghosting). Default
3736
+ * role is `'other'` so this button
3415
3737
  * doesn't get drafted into the grid's row-click dispatch; pass
3416
3738
  * `gridButtonRole="open"` to override (e.g. when the URL leads to an
3417
3739
  * edit page and the consumer wants the primary-name cell to route
@@ -3419,10 +3741,10 @@ interface NavigateRecordGridButtonProps extends GridButtonRoleProps {
3419
3741
  *
3420
3742
  * ```tsx
3421
3743
  * <NavigateRecordGridButton
3422
- * title="View details"
3423
- * url="/contacts/{0}/details"
3424
- * icon={<Eye20Regular />}
3425
- * buttonEnabledBehavior={GridButtonBehavior.OnlyOneSelected}
3744
+ * title="View details"
3745
+ * url="/contacts/{0}/details"
3746
+ * icon={<Eye20Regular />}
3747
+ * buttonEnabledBehavior={GridButtonBehavior.OnlyOneSelected}
3426
3748
  * />
3427
3749
  * ```
3428
3750
  */
@@ -3451,7 +3773,7 @@ interface RefreshGridButtonProps {
3451
3773
  }
3452
3774
  /**
3453
3775
  * Reload the grid's current page / sort / search via the grid context.
3454
- * Mirrors Blazor's built-in refresh toolbar button. Always enabled (a
3776
+ * Always enabled (a
3455
3777
  * refresh is meaningful even on an unchanged view); the
3456
3778
  * working-state coalescing that prevents rapid double-click round-trips
3457
3779
  * lives on the underlying {@link GridButton} primitive.
@@ -3460,7 +3782,7 @@ declare function RefreshGridButton({ disabled, onBeforeRefresh, onRefreshed, onE
3460
3782
 
3461
3783
  /**
3462
3784
  * Mutable context handed to a `<NavigateNewRecordGridButton>`'s
3463
- * `onClick` callback. Mirrors Blazor's `NavigateGridButtonContext`.
3785
+ * `onClick` callback.
3464
3786
  * The callback can rewrite `url` before navigation fires.
3465
3787
  */
3466
3788
  interface NavigateNewRecordGridButtonContext {
@@ -3503,7 +3825,7 @@ interface NavigateNewRecordGridButtonProps {
3503
3825
  }
3504
3826
  /**
3505
3827
  * Grid toolbar button that navigates to a URL for creating a new record.
3506
- * Mirrors Blazor's `NavigateNewRecordGridButton` — disabled when one or
3828
+ * disabled when one or
3507
3829
  * more records are selected (the "new record" intent doesn't combine with
3508
3830
  * an existing-record selection), AND when the current user lacks the
3509
3831
  * `Create` permission on the grid's table (sampled from
@@ -3516,7 +3838,7 @@ declare function NavigateNewRecordGridButton({ url, onClick, onNavigate, disable
3516
3838
  type TableRecord$5 = components['schemas']['TableRecord'];
3517
3839
  /**
3518
3840
  * Mutable context handed to a `<NavigateOpenRecordGridButton>`'s
3519
- * `onClick` callback. Mirrors Blazor's `NavigateGridButtonContext`.
3841
+ * `onClick` callback.
3520
3842
  * The callback can rewrite `url` before navigation fires — useful for
3521
3843
  * view-aware routing (e.g. switch the destination based on the active
3522
3844
  * view's table).
@@ -3566,7 +3888,7 @@ interface NavigateOpenRecordGridButtonProps {
3566
3888
  }
3567
3889
  /**
3568
3890
  * Grid toolbar button that navigates to a URL for editing the currently-
3569
- * selected record. Mirrors Blazor's `NavigateOpenRecordGridButton` — only
3891
+ * selected record. only
3570
3892
  * enabled when exactly ONE record is selected, since navigation targets a
3571
3893
  * single record's edit page (multi-record edit isn't a meaningful URL).
3572
3894
  */
@@ -3577,28 +3899,28 @@ declare function NavigateOpenRecordGridButton({ urlFor, onClick, onNavigate, dis
3577
3899
  * clicks Save:
3578
3900
  *
3579
3901
  * - **`withGridContext`** (default) — Queues the dirty columns into the
3580
- * grid's pending-updates registry. The surrounding `<MainContext>` /
3581
- * `<RecordContext>` picks them up in its next transactional save (one
3582
- * `executeMultiple` round-trip covers the record-context's own update
3583
- * plus every queued row in the grid). Use when the grid lives inside a
3584
- * record-edit page and the user expects "save the whole page" semantics.
3902
+ * grid's pending-updates registry. The surrounding `<MainContext>` /
3903
+ * `<RecordContext>` picks them up in its next transactional save (one
3904
+ * `executeMultiple` round-trip covers the record-context's own update
3905
+ * plus every queued row in the grid). Use when the grid lives inside a
3906
+ * record-edit page and the user expects "save the whole page" semantics.
3585
3907
  * - **`immediately`** — Issues the update right away through the standard
3586
- * RecordContext save flow, then refreshes the grid. Use for standalone
3587
- * grid pages where each Edit is its own commit.
3908
+ * RecordContext save flow, then refreshes the grid. Use for standalone
3909
+ * grid pages where each Edit is its own commit.
3588
3910
  *
3589
- * Mirrors Blazor's `GridActionBehavior.WithGridContext` / `.Immediately`
3911
+ * Mirrors / `.Immediately`
3590
3912
  * enum (`OpenRecordGridButton<TForm>.Behavior` parameter).
3591
3913
  */
3592
3914
  type OpenRecordGridButtonBehavior = 'withGridContext' | 'immediately';
3593
3915
  /**
3594
3916
  * Where the dialog renders. `center` is a modal in the middle of the
3595
- * viewport; `panel` slides in from the right edge. Mirrors Blazor's
3917
+ * viewport; `panel` slides in from the right edge.
3596
3918
  * `DialogLocation.Center` / `.Panel`.
3597
3919
  *
3598
3920
  * Implementation note: `panel` is approximated via Fluent's standard
3599
3921
  * `Dialog` with a `dialogSurface` style override that pins it to the
3600
3922
  * right edge — Fluent's React `Dialog` doesn't ship a first-class panel
3601
- * variant the way Blazor's `FluentDialog` does.
3923
+ * variant the way does.
3602
3924
  */
3603
3925
  type DialogLocation = 'center' | 'panel';
3604
3926
  interface OpenRecordGridButtonProps {
@@ -3663,20 +3985,19 @@ interface OpenRecordGridButtonProps {
3663
3985
  }
3664
3986
  /**
3665
3987
  * Grid toolbar button that opens a dialog form for editing the currently
3666
- * selected record(s). Mirrors Blazor's `<OpenRecordGridButton TForm="..." />`
3988
+ * selected record(s). Mirrors
3667
3989
  * minus the `TForm` type parameter (React composes via children instead).
3668
3990
  *
3669
3991
  * Two flavors driven by the current selection size:
3670
3992
  *
3671
3993
  * - **Single record selected** — opens the form bound to a fresh fetch of
3672
- * that record, with any already-queued dirty columns from a prior dialog
3673
- * session pre-applied. Save commits just this record.
3994
+ * that record, with any already-queued dirty columns from a prior dialog
3995
+ * session pre-applied. Save commits just this record.
3674
3996
  * - **Multiple records selected** — opens the form bound to an EMPTY record
3675
- * (only `tableName` populated). The user fills in whichever columns they
3676
- * want to apply, and Save broadcasts those same dirty columns to every
3677
- * selected record. Untouched columns leave each target row alone.
3678
- * Mirrors Blazor's multi-edit flow in
3679
- * `OpenRecordGridButton.razor.cs::OnSaveClicked`.
3997
+ * (only `tableName` populated). The user fills in whichever columns they
3998
+ * want to apply, and Save broadcasts those same dirty columns to every
3999
+ * selected record. Untouched columns leave each target row alone.
4000
+ *razor.cs::OnSaveClicked`.
3680
4001
  *
3681
4002
  * The Open button gates on Read permission (not Write); per-column Write
3682
4003
  * enforcement happens inside the form via the bound record's `permissions`
@@ -3697,18 +4018,18 @@ type ColumnValueBase$1 = components['schemas']['ColumnValueBase'];
3697
4018
  * clicked:
3698
4019
  *
3699
4020
  * - **`withGridContext`** (default) — Queues a `CreateRequest` into the
3700
- * grid's pending-creates registry. The surrounding `<MainContext>` /
3701
- * `<RecordContext>` picks it up in its next transactional save (one
3702
- * `executeMultiple` round-trip covers the parent record's update plus
3703
- * every queued new row in the grid). Use when the grid lives inside a
3704
- * record-edit page and the user expects "save the whole page" semantics
3705
- * the new row's FK to the parent stays consistent with whatever id the
3706
- * parent settles at.
4021
+ * grid's pending-creates registry. The surrounding `<MainContext>` /
4022
+ * `<RecordContext>` picks it up in its next transactional save (one
4023
+ * `executeMultiple` round-trip covers the parent record's update plus
4024
+ * every queued new row in the grid). Use when the grid lives inside a
4025
+ * record-edit page and the user expects "save the whole page" semantics
4026
+ * the new row's FK to the parent stays consistent with whatever id the
4027
+ * parent settles at.
3707
4028
  * - **`immediately`** — Issues the create right away through
3708
- * `executeMultipleAsync`, then refreshes the grid. Use for standalone
3709
- * grid pages where each new row is its own commit.
4029
+ * `executeMultipleAsync`, then refreshes the grid. Use for standalone
4030
+ * grid pages where each new row is its own commit.
3710
4031
  *
3711
- * Mirrors Blazor's `GridActionBehavior.WithGridContext` / `.Immediately`
4032
+ * Mirrors / `.Immediately`
3712
4033
  * on `NewRecordGridButton<TForm>.Behavior`.
3713
4034
  */
3714
4035
  type NewRecordGridButtonBehavior = 'withGridContext' | 'immediately';
@@ -3758,7 +4079,7 @@ interface NewRecordGridButtonProps {
3758
4079
  }
3759
4080
  /**
3760
4081
  * Grid toolbar button that opens a dialog form for creating a new record.
3761
- * Mirrors Blazor's `<NewRecordGridButton TForm="..." />` minus the `TForm`
4082
+ * Mirrors minus the `TForm`
3762
4083
  * type parameter (React composes via children instead).
3763
4084
  *
3764
4085
  * When hosted inside a `<SubGrid>`, automatically pre-fills the parent
@@ -3775,29 +4096,29 @@ declare function NewRecordGridButton({ children, behavior, location, disabled, l
3775
4096
 
3776
4097
  /**
3777
4098
  * How the immediate-delete path issues requests to the server. Mirrors
3778
- * Blazor's `BulkOperationMode`.
4099
+ *.
3779
4100
  *
3780
- * - `'individually'` (default): one `deleteRecordAsync` call per selected
3781
- * record, awaited in sequence so a mid-batch failure short-circuits.
3782
- * - `'bulk'`: one `executeMultipleAsync` round-trip carrying every
3783
- * `DeleteRequest` in a single transactional batch.
4101
+ * - `'individually'` (default): one `deleteRecordAsync` call per selected
4102
+ * record, awaited in sequence so a mid-batch failure short-circuits.
4103
+ * - `'bulk'`: one `executeMultipleAsync` round-trip carrying every
4104
+ * `DeleteRequest` in a single transactional batch.
3784
4105
  */
3785
4106
  type DeleteRecordGridButtonMode = 'individually' | 'bulk';
3786
4107
  /**
3787
- * When the button actually contacts the server. Mirrors Blazor's
3788
- * `GridActionBehavior` (and Blazor's default of `WithGridContext`).
3789
- *
3790
- * - `'withGridContext'` (default): stage the deletes via the grid's
3791
- * pending-row queue. The actual `DeleteRequest`s are emitted from
3792
- * the grid's descendant `getRequests` when the surrounding
3793
- * `<MainContext>.saveAll` runs, so they land in one transactional
3794
- * batch alongside any sibling edits. Requires a surrounding
3795
- * `<MainContext>` or `<RecordContext>` to ever commit — without one
3796
- * the staged deletes never ship.
3797
- * - `'immediately'`: confirm → delete → refresh, all inside the
3798
- * button's click handler. Use for grids that aren't hosted inside a
3799
- * save-coordinating context (a stand-alone list page, an admin
3800
- * table).
4108
+ * When the button actually contacts the server.
4109
+ * `GridActionBehavior` (and.
4110
+ *
4111
+ * - `'withGridContext'` (default): stage the deletes via the grid's
4112
+ * pending-row queue. The actual `DeleteRequest`s are emitted from
4113
+ * the grid's descendant `getRequests` when the surrounding
4114
+ * `<MainContext>.saveAll` runs, so they land in one transactional
4115
+ * batch alongside any sibling edits. Requires a surrounding
4116
+ * `<MainContext>` or `<RecordContext>` to ever commit — without one
4117
+ * the staged deletes never ship.
4118
+ * - `'immediately'`: confirm → delete → refresh, all inside the
4119
+ * button's click handler. Use for grids that aren't hosted inside a
4120
+ * save-coordinating context (a stand-alone list page, an admin
4121
+ * table).
3801
4122
  */
3802
4123
  type DeleteRecordGridButtonBehavior = 'withGridContext' | 'immediately';
3803
4124
  interface DeleteRecordGridButtonProps {
@@ -3847,17 +4168,17 @@ interface DeleteRecordGridButtonProps {
3847
4168
  behavior?: DeleteRecordGridButtonBehavior;
3848
4169
  }
3849
4170
  /**
3850
- * Bulk-delete every selected record in the grid. Mirrors Blazor's
4171
+ * Bulk-delete every selected record in the grid.
3851
4172
  * `DeleteRecordGridButton` — disabled when nothing is selected. On click:
3852
4173
  *
3853
4174
  * 1. Calls `onBeforeDelete` (cancellable).
3854
4175
  * 2. Prompts a confirmation dialog (localized "Delete N records?" /
3855
- * "Delete record?" depending on count).
4176
+ * "Delete record?" depending on count).
3856
4177
  * 3. Issues a `deleteRecordAsync` per selected record, awaited in
3857
- * sequence so the server processes them in a deterministic order
3858
- * and a mid-batch failure short-circuits the rest.
4178
+ * sequence so the server processes them in a deterministic order
4179
+ * and a mid-batch failure short-circuits the rest.
3859
4180
  * 4. Triggers the grid's refresh so the deleted rows disappear from the
3860
- * current page (and `totalRecordCount` decrements).
4181
+ * current page (and `totalRecordCount` decrements).
3861
4182
  * 5. Calls `onDeleted` with the records that were deleted.
3862
4183
  *
3863
4184
  * The button is also disabled when ANY selected record lacks the
@@ -3881,19 +4202,19 @@ type TableRecord$4 = components['schemas']['TableRecord'];
3881
4202
  * How a `<LinkExistingRecordGridButton>` commits its associations:
3882
4203
  *
3883
4204
  * - **`withGridContext`** (default) — Queue the chosen records into the
3884
- * grid's pending-associate registry. The surrounding `<MainContext>` /
3885
- * `<RecordContext>` picks them up in its next transactional save so
3886
- * the M2M link lands as part of the parent record's `executeMultiple`
3887
- * batch. Required when the parent record doesn't have an id yet (new
3888
- * record + subgrid flow): the AssociateRequest can't be composed until
3889
- * after the parent's CreateRequest assigns the id, which the parent's
3890
- * save flow handles automatically.
4205
+ * grid's pending-associate registry. The surrounding `<MainContext>` /
4206
+ * `<RecordContext>` picks them up in its next transactional save so
4207
+ * the M2M link lands as part of the parent record's `executeMultiple`
4208
+ * batch. Required when the parent record doesn't have an id yet (new
4209
+ * record + subgrid flow): the AssociateRequest can't be composed until
4210
+ * after the parent's CreateRequest assigns the id, which the parent's
4211
+ * save flow handles automatically.
3891
4212
  * - **`immediately`** — Issue an AssociateRequest right away through
3892
- * `executeMultipleAsync`, then refresh the grid. Use for grids where
3893
- * each link is its own commit (the parent record already exists and
3894
- * the user isn't editing it).
4213
+ * `executeMultipleAsync`, then refresh the grid. Use for grids where
4214
+ * each link is its own commit (the parent record already exists and
4215
+ * the user isn't editing it).
4216
+ *
3895
4217
  *
3896
- * Mirrors Blazor's `GridActionBehavior` on `LinkExistingRecordGridButton`.
3897
4218
  */
3898
4219
  type LinkExistingRecordBehavior = 'withGridContext' | 'immediately';
3899
4220
  /**
@@ -3901,7 +4222,7 @@ type LinkExistingRecordBehavior = 'withGridContext' | 'immediately';
3901
4222
  * record (Individually) or a single Associate carrying every selected
3902
4223
  * record (Bulk). Only meaningful in `behavior="immediately"` — the
3903
4224
  * `withGridContext` queue always emits a single Associate spanning the
3904
- * accumulated queue. Mirrors Blazor's `BulkOperationMode`.
4225
+ * accumulated queue.
3905
4226
  */
3906
4227
  type LinkExistingBulkMode = 'individually' | 'bulk';
3907
4228
  interface LinkExistingRecordGridButtonProps {
@@ -3933,13 +4254,13 @@ interface LinkExistingRecordGridButtonProps {
3933
4254
  /**
3934
4255
  * Grid toolbar button that pops a multi-select lookup dialog for picking
3935
4256
  * existing records to associate with the SubGrid's parent record via the
3936
- * SubGrid's M2M relationship. Mirrors Blazor's
4257
+ * SubGrid's M2M relationship.
3937
4258
  * `<LinkExistingRecordGridButton>`.
3938
4259
  *
3939
4260
  * Requires the grid to be a `<SubGrid>` — the button reads `parentRecord`
3940
4261
  * + `relationshipName` off `useGridContext()` and disables itself when
3941
4262
  * either is missing. Visible regardless of selection state (matches
3942
- * Blazor's `GridButtonBehavior.NoneSelected` default — the action's
4263
+ * default — the action's
3943
4264
  * input is the lookup dialog's picker, not the grid's current row
3944
4265
  * selection).
3945
4266
  */
@@ -3971,10 +4292,9 @@ interface UnlinkExistingRecordGridButtonProps {
3971
4292
  /**
3972
4293
  * Grid toolbar button that prompts the user to disassociate the currently
3973
4294
  * selected rows from the SubGrid's parent record via the M2M relationship.
3974
- * Mirrors Blazor's `<UnlinkExistingRecordGridButton>`.
3975
4295
  *
3976
- * Hidden when nothing is selected (`OneOrMoreSelected` visibility gate
3977
- * matches Blazor's `<UnlinkExistingRecordGridButton>` default). Requires
4296
+ * Hidden when nothing is selected (`OneOrMoreSelected` visibility gate
4297
+ *. Requires
3978
4298
  * the grid to be a `<SubGrid>` — the click handler reads `parentRecord`
3979
4299
  * + `relationshipName` off the grid context and bails when either is
3980
4300
  * missing. Composed on top of {@link GridButton}.
@@ -3993,7 +4313,7 @@ type TableRecord$3 = components['schemas']['TableRecord'];
3993
4313
  *
3994
4314
  * `parentRecord` is the surrounding `<RecordContext>`'s record when the
3995
4315
  * grid is mounted as a `<SubGrid>` (a 1:N or M:N child grid of a parent
3996
- * form). Lets a renderer key conditional formatting off the parent
4316
+ * form). Lets a renderer key conditional formatting off the parent
3997
4317
  * e.g. "highlight contacts whose `industrycode` doesn't match the parent
3998
4318
  * account's." `undefined` for top-level `<MainGrid>` usage where there's
3999
4319
  * no surrounding record context.
@@ -4043,16 +4363,16 @@ type GridColumnCellRenderer = (props: GridColumnCellRendererProps) => ReactNode;
4043
4363
  * carry a single `value` or `metadata` (a template column has no
4044
4364
  * bound column to provide them for); instead it surfaces:
4045
4365
  *
4046
- * - `id` — the template column's identifier (auto-generated by the
4047
- * extract walker when the consumer omits it).
4048
- * - `dependsOnMetadata` — pre-built lookup map keyed by the column
4049
- * names declared in {@link GridTemplateColumnProps.dependsOn},
4050
- * each entry the resolved `ColumnMetadataBase` from the primary
4051
- * table's metadata. Entries that don't resolve (dot-notation
4052
- * linked columns, or a non-existent column name) come back as
4053
- * `undefined`.
4054
- * - The shared `record` / `parentRecord` / `searchText` context from
4055
- * {@link BaseCellRendererProps}.
4366
+ * - `id` — the template column's identifier (auto-generated by the
4367
+ * extract walker when the consumer omits it).
4368
+ * - `dependsOnMetadata` — pre-built lookup map keyed by the column
4369
+ * names declared in {@link GridTemplateColumnProps.dependsOn},
4370
+ * each entry the resolved `ColumnMetadataBase` from the primary
4371
+ * table's metadata. Entries that don't resolve (dot-notation
4372
+ * linked columns, or a non-existent column name) come back as
4373
+ * `undefined`.
4374
+ * - The shared `record` / `parentRecord` / `searchText` context from
4375
+ * {@link BaseCellRendererProps}.
4056
4376
  *
4057
4377
  * Read column values from `record.properties` / `record.formattedValues`
4058
4378
  * — or use `resolveColumnDisplayValue` for the formatted → raw
@@ -4066,25 +4386,25 @@ type GridTemplateColumnCellRenderer = (props: GridTemplateColumnCellRendererProp
4066
4386
  /**
4067
4387
  * Shape passed to a `<GridTemplateColumn>`'s `editRenderer` when the
4068
4388
  * grid is in inline-edit mode. Same fields as
4069
- * {@link GridTemplateColumnCellRendererProps} plus {@link setValue}
4389
+ * {@link GridTemplateColumnCellRendererProps} plus {@link setValue}
4070
4390
  * the imperative escape hatch for the custom-widget editing path.
4071
4391
  *
4072
4392
  * Two authoring patterns are supported:
4073
4393
  *
4074
- * 1. **Drop-in editors** — render `<ColumnEdit columnName="firstname"/>`
4075
- * (or any other type-dispatched editor) directly inside the
4076
- * `editRenderer`'s returned JSX. The surrounding per-row
4077
- * `<RecordContext>` provides their metadata + setValue hooks
4078
- * automatically, so the edits dirty-track and validate exactly
4079
- * like a bound `<GridColumn>`'s `cellRenderer` does. No need to
4080
- * call {@link setValue} in this case.
4081
- *
4082
- * 2. **Custom widget** — render an arbitrary input (a "First Last"
4083
- * string parser that emits two columns, a slider tied to multiple
4084
- * percent fields, etc.) and call `setValue(columnName, value)` for
4085
- * each affected column. **Validation is your responsibility on
4086
- * this path** — the framework only validates editors that
4087
- * registered with the row's edit-context.
4394
+ * 1. **Drop-in editors** — render `<ColumnEdit columnName="firstname"/>`
4395
+ * (or any other type-dispatched editor) directly inside the
4396
+ * `editRenderer`'s returned JSX. The surrounding per-row
4397
+ * `<RecordContext>` provides their metadata + setValue hooks
4398
+ * automatically, so the edits dirty-track and validate exactly
4399
+ * like a bound `<GridColumn>`'s `cellRenderer` does. No need to
4400
+ * call {@link setValue} in this case.
4401
+ *
4402
+ * 2. **Custom widget** — render an arbitrary input (a "First Last"
4403
+ * string parser that emits two columns, a slider tied to multiple
4404
+ * percent fields, etc.) and call `setValue(columnName, value)` for
4405
+ * each affected column. **Validation is your responsibility on
4406
+ * this path** — the framework only validates editors that
4407
+ * registered with the row's edit-context.
4088
4408
  */
4089
4409
  interface GridTemplateColumnEditRendererProps extends GridTemplateColumnCellRendererProps {
4090
4410
  /**
@@ -4125,10 +4445,9 @@ declare function getRendererTypeForMetadata(metadata: ColumnMetadataBase | undef
4125
4445
  declare function getCellRenderer(metadata: ColumnMetadataBase | undefined): GridColumnCellRenderer;
4126
4446
  /**
4127
4447
  * Whether the column can be sorted server-side via a FetchXML `<order>`
4128
- * clause. File (type 41) and Image (type 42) columns are excluded
4448
+ * clause. File (type 41) and Image (type 42) columns are excluded
4129
4449
  * Dataverse stores them as GUIDs and sorting by GUID is meaningless to
4130
- * a user (matches Blazor's behavior + the server-resolved
4131
- * `ResolvedColumn.isSortable` flag).
4450
+ * a user.
4132
4451
  *
4133
4452
  * MainGrid prefers the server-provided `ResolvedColumn.isSortable` over
4134
4453
  * this client-side check; consumers without a `ResolvedColumn` (writing
@@ -4139,11 +4458,7 @@ declare function isColumnSortable(metadata: ColumnMetadataBase | undefined): boo
4139
4458
 
4140
4459
  type ViewColumn = components['schemas']['ViewColumn'];
4141
4460
  /**
4142
- * Paging strategy used by the grid. Mirrors Blazor's `GridPagingMode` —
4143
- * kept in lockstep with that source of truth at
4144
- * `src/PowerPortalsPro.Web.Blazor.FluentUI/Components/Grids/FluentGridBase.razor.cs`
4145
- * (search for `enum GridPagingMode`). When the Blazor enum gains a new
4146
- * entry, add the matching key here.
4461
+ * Paging strategy used by the grid.
4147
4462
  */
4148
4463
  declare const PagingMode: {
4149
4464
  /** Classic pager — Prev / Next / page-size selector at the bottom. */
@@ -4158,11 +4473,7 @@ declare const PagingMode: {
4158
4473
  };
4159
4474
  type PagingMode = (typeof PagingMode)[keyof typeof PagingMode];
4160
4475
  /**
4161
- * Sort order applied to the view-picker dropdown options. Mirrors Blazor's
4162
- * `ViewSort` enum — kept in lockstep with that source of truth at
4163
- * `src/PowerPortalsPro.Web.Blazor/Components/Grids/GridBase.razor.cs`
4164
- * (search for `enum ViewSort`). When the Blazor enum gains a new entry,
4165
- * add the matching key here.
4476
+ * Sort order applied to the view-picker dropdown options.
4166
4477
  */
4167
4478
  declare const ViewSort: {
4168
4479
  /** Server-returned order, plus custom views appended in declaration order. */
@@ -4175,19 +4486,14 @@ declare const ViewSort: {
4175
4486
  type ViewSort = (typeof ViewSort)[keyof typeof ViewSort];
4176
4487
  /**
4177
4488
  * Consumer-supplied in-memory view, mixed into the view-picker dropdown
4178
- * alongside Dataverse-resolved views. Mirrors Blazor's `GridViewDefinition`
4179
- * shape — the minimum a grid needs to render a view without a Dataverse
4180
- * `savedquery`/`userquery` round-trip.
4489
+ * alongside Dataverse-resolved views the minimum a grid needs to render
4490
+ * a view without a Dataverse `savedquery`/`userquery` round-trip.
4181
4491
  *
4182
4492
  * Custom views are submitted to `POST /api/grids/data` as inline `fetchXml`
4183
4493
  * rather than `viewId`, so the server takes the consumer-supplied FetchXML
4184
4494
  * verbatim (still wraps it through `IFetchXmlQueryComposer` for search,
4185
4495
  * sort, filter, paging — same as the view-id path).
4186
4496
  *
4187
- * Source of truth: kept in lockstep (by hand, not codegen) with Blazor's
4188
- * `GridViewDefinition` at
4189
- * `src/PowerPortalsPro.Common/Models/GridViewDefinition.cs`. When that
4190
- * record gains / drops fields a consumer would set, mirror the change here.
4191
4497
  * The generated `ViewMetadata` TS type is intentionally NOT reused — it
4192
4498
  * includes Dataverse-internal fields (`isDefault`, `quickFindCompatible`,
4193
4499
  * `userDefined`, `type`) that don't belong on the consumer-facing surface.
@@ -4222,16 +4528,16 @@ type ViewMetadata = components['schemas']['ViewMetadata'];
4222
4528
  * future props can grow it without breaking consumers.
4223
4529
  *
4224
4530
  * Consumer surface (Phase 1):
4225
- * - One of `viewId` or `tableName` (viewId wins when both are set).
4226
- * - `pageSize` (default 25), `className`, `style`.
4531
+ * - One of `viewId` or `tableName` (viewId wins when both are set).
4532
+ * - `pageSize` (default 25), `className`, `style`.
4227
4533
  *
4228
4534
  * Data flow:
4229
- * 1. Resolve the active viewId — explicit prop, or first public view for
4230
- * `tableName`.
4231
- * 2. Fetch view metadata (FetchXML + view columns).
4232
- * 3. Fetch table metadata in parallel (per-column metadata for renderers).
4233
- * 4. Inject `page` + `count` into the view's FetchXML and execute.
4234
- * 5. Hand the result to TanStack + the type-dispatched cell renderers.
4535
+ * 1. Resolve the active viewId — explicit prop, or first public view for
4536
+ * `tableName`.
4537
+ * 2. Fetch view metadata (FetchXML + view columns).
4538
+ * 3. Fetch table metadata in parallel (per-column metadata for renderers).
4539
+ * 4. Inject `page` + `count` into the view's FetchXML and execute.
4540
+ * 5. Hand the result to TanStack + the type-dispatched cell renderers.
4235
4541
  */
4236
4542
  interface MainGridProps {
4237
4543
  /**
@@ -4369,10 +4675,10 @@ interface MainGridProps {
4369
4675
  *
4370
4676
  * - `'none'`: no selector column; rows are display-only.
4371
4677
  * - `'single'`: a radio-button column appears; selecting one row
4372
- * deselects any previously-selected row.
4678
+ * deselects any previously-selected row.
4373
4679
  * - `'multiple'` (default): a checkbox column appears with a
4374
- * header-level select-all toggle; users can select any combination
4375
- * of rows.
4680
+ * header-level select-all toggle; users can select any combination
4681
+ * of rows.
4376
4682
  *
4377
4683
  * The current selection ships back to the consumer via
4378
4684
  * {@link onSelectedRecordsChange} or the controlled
@@ -4489,7 +4795,7 @@ interface MainGridProps {
4489
4795
  /**
4490
4796
  * Minimum height of the grid. CSS value string (`"250px"`, `"30vh"`,
4491
4797
  * `"50%"`) or a raw number (treated as pixels). Defaults to `"250px"`
4492
- * to match Blazor's `GridBase.MinHeight`. The body area grows to fit
4798
+ *. The body area grows to fit
4493
4799
  * content above this floor, then engages vertical scrolling once
4494
4800
  * content + {@link maxHeight} caps the total height. Ignored when
4495
4801
  * {@link fullSize} is `true`.
@@ -4617,12 +4923,12 @@ interface MainGridProps {
4617
4923
  * queries) and inline `CustomViewDefinition.columns[].width`.
4618
4924
  *
4619
4925
  * Defaults to `1` (no scaling — widths pass through as-is, matching
4620
- * the Blazor `<GridColumn Width="..." />` 1:1 behavior at
4926
+ * the 1:1 behavior at
4621
4927
  * `FluentGridBase.razor`). Set to a value above 1 to inflate every
4622
4928
  * numeric width — useful when adapting Dataverse "pixel" widths
4623
4929
  * calibrated for the denser model-driven-app rendering and they
4624
4930
  * read cramped in a less-dense React page. User-resized columns
4625
- * (the drag-handle widths held in `columnSizing`) are NOT scaled
4931
+ * (the drag-handle widths held in `columnSizing`) are NOT scaled
4626
4932
  * those are explicit pixel choices the user made in this rendering,
4627
4933
  * and re-scaling them would feel like the column "fights back"
4628
4934
  * against a deliberate resize. Only applies to numeric widths;
@@ -4636,7 +4942,7 @@ interface MainGridProps {
4636
4942
  * Public MainGrid wrapper that mounts an inner `<MainContext>` around
4637
4943
  * the grid's body. The wrapper exists so the grid's inline-edit
4638
4944
  * descendants (per-row `<RecordContext>`s, dialog-driven row queues)
4639
- * report dirty state to a context whose scope is exactly this grid
4945
+ * report dirty state to a context whose scope is exactly this grid
4640
4946
  * letting the built-in refresh button warn on unsaved inline edits and
4641
4947
  * letting consumer code aggregate "is this one grid dirty?" without
4642
4948
  * sweeping in unrelated dirty state from the surrounding page.
@@ -4657,7 +4963,7 @@ declare function MainGrid(props: MainGridProps): react_jsx_runtime.JSX.Element;
4657
4963
  * deliberately short (`v` / `p` / `ps` / `s` / `q`) so the encoded blob
4658
4964
  * stays compact when round-tripped through bookmarks and shared links.
4659
4965
  *
4660
- * Kept in lockstep with the Blazor `PersistedGridState` shape so a URL
4966
+ * Kept in lockstep with the shape so a URL
4661
4967
  * produced by one stack is consumable by the other — same param name, same
4662
4968
  * keys, same value semantics. Update both sides together.
4663
4969
  */
@@ -4685,7 +4991,7 @@ interface PersistedSort {
4685
4991
 
4686
4992
  type TableRecord$1 = components['schemas']['TableRecord'];
4687
4993
  /**
4688
- * Grid that shows records related to a parent via a Dataverse relationship
4994
+ * Grid that shows records related to a parent via a Dataverse relationship
4689
4995
  * either one-to-many ("contacts on this account") or many-to-many ("tags on
4690
4996
  * this article"). Wraps {@link MainGrid} with a `RelationshipFilter` so the
4691
4997
  * server's `IFetchXmlQueryComposer` scopes the rows to "children of this
@@ -4704,7 +5010,7 @@ type TableRecord$1 = components['schemas']['TableRecord'];
4704
5010
  *
4705
5011
  * ```tsx
4706
5012
  * const staticFilters = useMemo(() => [
4707
- * { $type: 'RelationshipFilter', parentRecord, relationshipName } as GridFilterBase,
5013
+ * { $type: 'RelationshipFilter', parentRecord, relationshipName } as GridFilterBase,
4708
5014
  * ], [parentRecord, relationshipName]);
4709
5015
  * const ds = useViewDataSource({ viewId, staticFilters, aggregations });
4710
5016
  *
@@ -4719,20 +5025,20 @@ type TableRecord$1 = components['schemas']['TableRecord'];
4719
5025
  * Two ways to provide the parent record:
4720
5026
  *
4721
5027
  * 1. **Cascading from `<RecordContext>`** (most common):
4722
- * ```tsx
4723
- * <RecordContext table="account" id={accountId}>
4724
- * {() => <SubGrid relationshipName="contact_customer_accounts" tableName="contact" />}
4725
- * </RecordContext>
4726
- * ```
5028
+ * ```tsx
5029
+ * <RecordContext table="account" id={accountId}>
5030
+ * {() => <SubGrid relationshipName="contact_customer_accounts" tableName="contact" />}
5031
+ * </RecordContext>
5032
+ * ```
4727
5033
  *
4728
5034
  * 2. **Explicit `record` prop** when no context is in scope:
4729
- * ```tsx
4730
- * <SubGrid
4731
- * relationshipName="contact_customer_accounts"
4732
- * tableName="contact"
4733
- * record={someAccountRecord}
4734
- * />
4735
- * ```
5035
+ * ```tsx
5036
+ * <SubGrid
5037
+ * relationshipName="contact_customer_accounts"
5038
+ * tableName="contact"
5039
+ * record={someAccountRecord}
5040
+ * />
5041
+ * ```
4736
5042
  *
4737
5043
  * Explicit prop wins over the cascading record so consumers can override
4738
5044
  * intentionally (e.g. a peek-at-related-records dialog whose parent isn't
@@ -4748,22 +5054,22 @@ type TableRecord$1 = components['schemas']['TableRecord'];
4748
5054
  *
4749
5055
  * **Toolbar button choice cheat-sheet:**
4750
5056
  * - **One-to-many SubGrid:** `<NewRecordGridButton>` opens a dialog form
4751
- * for the related record (parent FK pre-filled automatically from the
4752
- * SubGrid's `relationshipName`); `<OpenRecordGridButton>` opens the
4753
- * selected row in the same dialog form for editing. URL-navigation
4754
- * variants (`<NavigateNewRecordGridButton>` / `<NavigateOpenRecordGridButton>`)
4755
- * are alternatives when the consumer prefers a dedicated edit page over
4756
- * an in-place dialog. `<DeleteRecordGridButton>` for bulk delete works
4757
- * in either case. `allowEdit` is fine — inline edits update the child
4758
- * record.
5057
+ * for the related record (parent FK pre-filled automatically from the
5058
+ * SubGrid's `relationshipName`); `<OpenRecordGridButton>` opens the
5059
+ * selected row in the same dialog form for editing. URL-navigation
5060
+ * variants (`<NavigateNewRecordGridButton>` / `<NavigateOpenRecordGridButton>`)
5061
+ * are alternatives when the consumer prefers a dedicated edit page over
5062
+ * an in-place dialog. `<DeleteRecordGridButton>` for bulk delete works
5063
+ * in either case. `allowEdit` is fine — inline edits update the child
5064
+ * record.
4759
5065
  * - **Many-to-many SubGrid:** `<LinkExistingRecordGridButton>` opens a
4760
- * lookup dialog to pick existing records to associate;
4761
- * `<UnlinkExistingRecordGridButton>` does the reverse on the current
4762
- * selection. Don't pass `allowEdit={true}` — the inline-edit save path
4763
- * issues `UpdateRequest`s against the related table, which alters the
4764
- * related record itself rather than its association with the parent
4765
- * (probably not what the user expects). Brand-new "create + associate"
4766
- * isn't built (see the memory note `react-m2m-new-record-deferred`).
5066
+ * lookup dialog to pick existing records to associate;
5067
+ * `<UnlinkExistingRecordGridButton>` does the reverse on the current
5068
+ * selection. Don't pass `allowEdit={true}` — the inline-edit save path
5069
+ * issues `UpdateRequest`s against the related table, which alters the
5070
+ * related record itself rather than its association with the parent
5071
+ * (probably not what the user expects). Brand-new "create + associate"
5072
+ * isn't built (see the memory note `react-m2m-new-record-deferred`).
4767
5073
  *
4768
5074
  * The built-in refresh icon button is always present.
4769
5075
  */
@@ -4846,18 +5152,18 @@ declare function FileGrid(props: FileGridProps): react_jsx_runtime.JSX.Element;
4846
5152
 
4847
5153
  /**
4848
5154
  * Optional flex container for grouping grid action buttons inside any
4849
- * `<MainGrid>` or `<SubGrid>`. Matches the Blazor `<Buttons>` render
5155
+ * `<MainGrid>` or `<SubGrid>`. Matches the render
4850
5156
  * fragment slot — consumers drop button components inside this wrapper
4851
5157
  * and they line up horizontally with the right spacing automatically.
4852
5158
  *
4853
5159
  * ```tsx
4854
5160
  * <MainGrid tableName="account">
4855
- * <GridButtons>
4856
- * <NewRecordGridButton />
4857
- * <OpenRecordGridButton />
4858
- * <DeleteRecordGridButton />
4859
- * <RefreshGridButton />
4860
- * </GridButtons>
5161
+ * <GridButtons>
5162
+ * <NewRecordGridButton />
5163
+ * <OpenRecordGridButton />
5164
+ * <DeleteRecordGridButton />
5165
+ * <RefreshGridButton />
5166
+ * </GridButtons>
4861
5167
  * </MainGrid>
4862
5168
  * ```
4863
5169
  *
@@ -4875,7 +5181,7 @@ declare function GridButtons({ children, className, style }: GridButtonsProps):
4875
5181
 
4876
5182
  /**
4877
5183
  * Horizontal alignment for a `<GridColumn>`'s body cells and header label.
4878
- * Mirrors Blazor's `Align.Start | Center | End` enum. When omitted, the
5184
+ * Mirrors enum. When omitted, the
4879
5185
  * cell uses the type-driven default: numeric columns end-align, boolean
4880
5186
  * columns center, everything else starts.
4881
5187
  */
@@ -4969,12 +5275,12 @@ interface GridColumnProps {
4969
5275
  * that renders whatever it wants from the row record.
4970
5276
  *
4971
5277
  * Use cases:
4972
- * - Combined-name column: `dependsOn={['firstname', 'lastname']}`,
4973
- * renderer joins them as a single bold cell.
4974
- * - Computed status badge: `dependsOn={['statuscode', 'createdon']}`,
4975
- * renderer returns a coloured badge keyed on both.
4976
- * - Pure-decoration actions column: `dependsOn` omitted, renderer
4977
- * returns inline buttons / icons reading nothing from the row.
5278
+ * - Combined-name column: `dependsOn={['firstname', 'lastname']}`,
5279
+ * renderer joins them as a single bold cell.
5280
+ * - Computed status badge: `dependsOn={['statuscode', 'createdon']}`,
5281
+ * renderer returns a coloured badge keyed on both.
5282
+ * - Pure-decoration actions column: `dependsOn` omitted, renderer
5283
+ * returns inline buttons / icons reading nothing from the row.
4978
5284
  *
4979
5285
  * Mixed with `<GridColumn>` children in declaration order — the grid
4980
5286
  * renders them interleaved as declared. Sort / search: template columns
@@ -4984,17 +5290,17 @@ interface GridColumnProps {
4984
5290
  *
4985
5291
  * ```tsx
4986
5292
  * <GridColumns>
4987
- * <GridColumn columnName="emailaddress1" />
4988
- * <GridTemplateColumn
4989
- * displayName="Full Name"
4990
- * dependsOn={['firstname', 'lastname']}
4991
- * sortBy="lastname"
4992
- * cellRenderer={({ record }) => {
4993
- * const f = resolveColumnDisplayValue(record, 'firstname') ?? '';
4994
- * const l = resolveColumnDisplayValue(record, 'lastname') ?? '';
4995
- * return <strong>{`${f} ${l}`.trim()}</strong>;
4996
- * }}
4997
- * />
5293
+ * <GridColumn columnName="emailaddress1" />
5294
+ * <GridTemplateColumn
5295
+ * displayName="Full Name"
5296
+ * dependsOn={['firstname', 'lastname']}
5297
+ * sortBy="lastname"
5298
+ * cellRenderer={({ record }) => {
5299
+ * const f = resolveColumnDisplayValue(record, 'firstname') ?? '';
5300
+ * const l = resolveColumnDisplayValue(record, 'lastname') ?? '';
5301
+ * return <strong>{`${f} ${l}`.trim()}</strong>;
5302
+ * }}
5303
+ * />
4998
5304
  * </GridColumns>
4999
5305
  * ```
5000
5306
  */
@@ -5085,13 +5391,13 @@ interface GridTemplateColumnProps {
5085
5391
  * Two authoring patterns are supported (see
5086
5392
  * {@link GridTemplateColumnEditRendererProps}):
5087
5393
  *
5088
- * 1. **Drop-in editors** — return `<ColumnEdit columnName="firstname"/>`
5089
- * (or any other type-dispatched editor). The surrounding per-row
5090
- * `<RecordContext>` provides their hooks automatically.
5394
+ * 1. **Drop-in editors** — return `<ColumnEdit columnName="firstname"/>`
5395
+ * (or any other type-dispatched editor). The surrounding per-row
5396
+ * `<RecordContext>` provides their hooks automatically.
5091
5397
  *
5092
- * 2. **Custom widget** — return an arbitrary input and call
5093
- * `setValue(columnName, value)` for each affected column.
5094
- * Validation is your responsibility on this path.
5398
+ * 2. **Custom widget** — return an arbitrary input and call
5399
+ * `setValue(columnName, value)` for each affected column.
5400
+ * Validation is your responsibility on this path.
5095
5401
  *
5096
5402
  * Omit to keep the column read-only even when the grid is editable
5097
5403
  * (e.g. an actions column that's always just a pair of buttons).
@@ -5106,23 +5412,23 @@ interface GridTemplateColumnProps {
5106
5412
  declare function GridTemplateColumn(_props: GridTemplateColumnProps): null;
5107
5413
  /**
5108
5414
  * Declarative column override for `<MainGrid>` / `<SubGrid>`. Mirrors
5109
- * Blazor's `<GridColumn>` — when one or more are declared as children,
5415
+ * — when one or more are declared as children,
5110
5416
  * the grid switches to **replace mode** and renders only the declared
5111
5417
  * columns in the declared order. Without any declarations, the grid
5112
5418
  * uses the view's full column set as before.
5113
5419
  *
5114
5420
  * ```tsx
5115
5421
  * <MainGrid tableName="contact">
5116
- * <GridColumns>
5117
- * <GridColumn columnName="firstname" />
5118
- * <GridColumn columnName="lastname" />
5119
- * <GridColumn columnName="emailaddress1" width={250} />
5120
- * </GridColumns>
5422
+ * <GridColumns>
5423
+ * <GridColumn columnName="firstname" />
5424
+ * <GridColumn columnName="lastname" />
5425
+ * <GridColumn columnName="emailaddress1" width={250} />
5426
+ * </GridColumns>
5121
5427
  * </MainGrid>
5122
5428
  * ```
5123
5429
  *
5124
5430
  * The wrapping `<GridColumns>` is optional — bare `<GridColumn>` children
5125
- * work too. The wrapper exists for parity with Blazor's authoring style
5431
+ * work too. The wrapper exists for parity with
5126
5432
  * and to give consumers a single place to group column declarations
5127
5433
  * alongside `<GridButtons>` and other toolbar children.
5128
5434
  *
@@ -5137,7 +5443,7 @@ interface GridColumnsProps {
5137
5443
  }
5138
5444
  /**
5139
5445
  * Optional grouping wrapper for one or more `<GridColumn>` declarations.
5140
- * Mirrors Blazor's `<GridColumns>` child fragment. Renders `null`
5446
+ * Mirrors child fragment. Renders `null`
5141
5447
  * MainGrid traverses the React tree at render time to harvest column
5142
5448
  * declarations.
5143
5449
  */
@@ -5222,9 +5528,10 @@ interface LookupFormProps {
5222
5528
  /** Class on the embedded `<MainGrid>` outer wrapper. */
5223
5529
  gridClassName?: string;
5224
5530
  /**
5225
- * Inline style on the embedded `<MainGrid>` outer wrapper. Standard use:
5226
- * `gridStyle={{ minHeight: 300, maxHeight: 300 }}` to clamp the grid's
5227
- * height when embedded in a dialog.
5531
+ * Inline style on the embedded `<MainGrid>` outer wrapper. The grid fills the
5532
+ * dialog height by default (rendered with `fullSize`); use this only to override
5533
+ * that e.g. `gridStyle={{ minHeight: 300, maxHeight: 300 }}` to clamp it to a
5534
+ * fixed height instead of filling.
5228
5535
  */
5229
5536
  gridStyle?: CSSProperties;
5230
5537
  }
@@ -5334,15 +5641,14 @@ interface WizardRecordPageProps {
5334
5641
  * `<RecordContext>`'s validate when
5335
5642
  * `forceSuccessfulValidationBeforeSave` is `true`.
5336
5643
  *
5337
- * Mirrors Blazor's `<WizardRecordPage>`. Same gate semantics as the
5338
- * Blazor `<FluentWizardStep>` + `RecordContext.Validate()` pair.
5644
+ * Same gate semantics as the
5645
+ * + `RecordContext.Validate()` pair.
5339
5646
  */
5340
5647
  declare function WizardRecordPage({ children, forceSuccessfulValidationBeforeSave, }: WizardRecordPageProps): react_jsx_runtime.JSX.Element;
5341
5648
 
5342
5649
  /**
5343
- * Visibility of the step indicator above the wizard body. Mirrors
5344
- * Blazor's `StepperVisible` boolean defaults to `false` (matches the
5345
- * Blazor default; the Save flow is button-driven, not stepper-driven).
5650
+ * Visibility of the step indicator above the wizard body. Defaults to
5651
+ * `'hidden'` — the Save flow is button-driven, not stepper-driven.
5346
5652
  */
5347
5653
  type StepperVisibility = 'visible' | 'hidden';
5348
5654
  interface WizardRecordFormProps extends Pick<RecordContextProps, 'table' | 'id' | 'initialRecord' | 'loadedRecord'> {
@@ -5402,7 +5708,7 @@ interface WizardRecordFormProps extends Pick<RecordContextProps, 'table' | 'id'
5402
5708
  }
5403
5709
  /**
5404
5710
  * Multi-step record-edit wizard backed by `react-use-wizard`. Mirrors
5405
- * Blazor's `<WizardRecordForm>` / `<WizardRecordPage>` pair. Each child
5711
+ * / `<WizardRecordPage>` pair. Each child
5406
5712
  * `<WizardRecordPage>` is rendered as one step; only the active step
5407
5713
  * mounts at any time (react-use-wizard's default), so descendant edit
5408
5714
  * components register validators / dirty state only for the current
@@ -5420,13 +5726,13 @@ interface WizardRecordFormProps extends Pick<RecordContextProps, 'table' | 'id'
5420
5726
  *
5421
5727
  * ```tsx
5422
5728
  * <WizardRecordForm table="contact" onCompleted={() => navigate('/contacts')}>
5423
- * <WizardRecordPage>
5424
- * <TextEdit columnName="firstname" />
5425
- * <TextEdit columnName="lastname" />
5426
- * </WizardRecordPage>
5427
- * <WizardRecordPage forceSuccessfulValidationBeforeSave={false}>
5428
- * <MemoEdit columnName="description" />
5429
- * </WizardRecordPage>
5729
+ * <WizardRecordPage>
5730
+ * <TextEdit columnName="firstname" />
5731
+ * <TextEdit columnName="lastname" />
5732
+ * </WizardRecordPage>
5733
+ * <WizardRecordPage forceSuccessfulValidationBeforeSave={false}>
5734
+ * <MemoEdit columnName="description" />
5735
+ * </WizardRecordPage>
5430
5736
  * </WizardRecordForm>
5431
5737
  * ```
5432
5738
  */
@@ -5487,11 +5793,47 @@ interface PageLayoutProps {
5487
5793
  * consumers wire their own routing-aware value here.
5488
5794
  */
5489
5795
  scrollResetKey?: string;
5796
+ /**
5797
+ * When `true` (the default), a drag handle on the nav/body boundary lets the user
5798
+ * resize the navigation column. Has no effect when `navigationVisible` is `false`
5799
+ * or the navigation slot is empty, and the handle disables on mobile (where the
5800
+ * nav reverts to a viewport-relative cap). Double-click the handle to reset to
5801
+ * `defaultNavigationWidth`.
5802
+ */
5803
+ enableNavigationResizing?: boolean;
5804
+ /** Nav width (px) used before the user resizes, and on double-click reset. Default `280`. */
5805
+ defaultNavigationWidth?: number;
5806
+ /** Smallest the nav can be dragged to, in px. Default `200`. */
5807
+ minNavigationWidth?: number;
5808
+ /**
5809
+ * Largest the navigation column will ever grow to, in px. Default `480`. Unified
5810
+ * cap: when `enableNavigationResizing` is on, this is the upper bound the user
5811
+ * can drag the splitter to; when it's off, this is the element's `max-width`.
5812
+ * Mobile (≤767.97px viewport) still falls back to a viewport-relative cap so a
5813
+ * 480px default doesn't overrun a small phone.
5814
+ */
5815
+ maxNavigationWidth?: number;
5816
+ /**
5817
+ * When `true` (the default), the navigation width the user drags to is persisted
5818
+ * to localStorage under `navigationResizeStorageKey` and restored on subsequent
5819
+ * loads. Set to `false` to make every page load start fresh at
5820
+ * `defaultNavigationWidth`. Only meaningful when `enableNavigationResizing` is `true`.
5821
+ */
5822
+ persistNavigationWidth?: boolean;
5823
+ /**
5824
+ * localStorage key the chosen nav width persists under. Default
5825
+ * `'ppp-page-layout-nav-width'`. Set a distinct key per layout if more than one
5826
+ * resizable `PageLayout` can be mounted. Ignored when `persistNavigationWidth`
5827
+ * is `false`.
5828
+ */
5829
+ navigationResizeStorageKey?: string;
5830
+ /** Accessible label for the resize handle (`role="separator"`). Default `'Resize navigation'`. */
5831
+ navigationResizeHandleLabel?: string;
5490
5832
  }
5491
5833
  /**
5492
5834
  * CSS Grid layout with four named areas (header / navigation / body /
5493
5835
  * footer). Body and navigation scroll independently; header and footer span
5494
- * the full width and stay fixed while the body scrolls. Supports nesting
5836
+ * the full width and stay fixed while the body scrolls. Supports nesting
5495
5837
  * an inner `<PageLayout>` inside the body picks up a `child-layout` style
5496
5838
  * variant automatically (thinner header border, fills the parent's body
5497
5839
  * rather than the viewport).
@@ -5500,7 +5842,7 @@ interface PageLayoutProps {
5500
5842
  * rather than nested children, giving TypeScript a place to surface
5501
5843
  * required-slot constraints if we add them later.
5502
5844
  */
5503
- declare function PageLayout({ header, navigation, body, footer, headerVisible, navigationVisible, footerVisible, className, style, headerClassName, headerStyle, navigationClassName, navigationStyle, bodyClassName, bodyStyle, footerClassName, footerStyle, scrollResetKey, }: PageLayoutProps): react_jsx_runtime.JSX.Element;
5845
+ declare function PageLayout({ header, navigation, body, footer, headerVisible, navigationVisible, footerVisible, className, style, headerClassName, headerStyle, navigationClassName, navigationStyle, bodyClassName, bodyStyle, footerClassName, footerStyle, scrollResetKey, enableNavigationResizing, defaultNavigationWidth, minNavigationWidth, maxNavigationWidth, persistNavigationWidth, navigationResizeStorageKey, navigationResizeHandleLabel, }: PageLayoutProps): react_jsx_runtime.JSX.Element;
5504
5846
 
5505
5847
  interface HeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
5506
5848
  /** Header content. */
@@ -5509,8 +5851,7 @@ interface HeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
5509
5851
  * Class merged onto the default Fluent header styling. Use this to
5510
5852
  * apply CONTEXT-specific overrides — e.g. PageLayout adds its accent-
5511
5853
  * colored border by passing a className that overrides
5512
- * `borderBottom`. Mirrors Blazor's per-consumer CSS specificity
5513
- * pattern (`.page-layout header { ... }` overriding `.ppp-header`).
5854
+ * `borderBottom`.page-layout header { ... }` overriding `.ppp-header`).
5514
5855
  */
5515
5856
  className?: string;
5516
5857
  /** Inline style override. */
@@ -5519,7 +5860,7 @@ interface HeaderProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
5519
5860
  /**
5520
5861
  * Page-header band — the single source of truth for the framework's
5521
5862
  * "header strip" visual treatment. Renders a semantic `<header>`
5522
- * element with Fluent token-driven styling that mirrors Blazor's
5863
+ * element with Fluent token-driven styling that
5523
5864
  * `Header.razor` + `Header.razor.css` exactly.
5524
5865
  *
5525
5866
  * Used internally by `<Section>` for section-header bands and by
@@ -5546,7 +5887,7 @@ interface BodyProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
5546
5887
  /**
5547
5888
  * Body content area — the single source of truth for the framework's
5548
5889
  * "inset content region" padding. Renders a semantic `<main>` element
5549
- * matching Blazor's `Body.razor`. Used internally by the framework's
5890
+ *. Used internally by the framework's
5550
5891
  * grid (toolbar + data area) and any other "content needs inset
5551
5892
  * padding" slot; equally usable standalone.
5552
5893
  *
@@ -5575,7 +5916,7 @@ interface FooterProps extends Omit<HTMLAttributes<HTMLElement>, 'children'> {
5575
5916
  /**
5576
5917
  * Page-footer band — the single source of truth for the framework's
5577
5918
  * "footer strip" visual treatment. Renders a semantic `<footer>`
5578
- * element with Fluent token-driven styling matching Blazor's
5919
+ * element with Fluent token-driven styling
5579
5920
  * `Footer.razor` + `Footer.razor.css` exactly.
5580
5921
  *
5581
5922
  * Used internally by `<Section>` for section-footer bands and by
@@ -5600,10 +5941,10 @@ declare function Footer({ children, className, style, ...rest }: FooterProps): r
5600
5941
  *
5601
5942
  * ```tsx
5602
5943
  * const router = createBrowserRouter([{ path: '/', element: (
5603
- * <PowerPortalsProProvider>
5604
- * <RouterUnsavedChangesGuard />
5605
- * <App />
5606
- * </PowerPortalsProProvider>
5944
+ * <PowerPortalsProProvider>
5945
+ * <RouterUnsavedChangesGuard />
5946
+ * <App />
5947
+ * </PowerPortalsProProvider>
5607
5948
  * )}]);
5608
5949
  * ```
5609
5950
  *
@@ -5616,16 +5957,16 @@ declare function Footer({ children, className, style, ...rest }: FooterProps): r
5616
5957
  *
5617
5958
  * - Single top-level context: prompt when it dirties.
5618
5959
  * - Sibling top-level contexts on the same page: ONE prompt if any are
5619
- * dirty (the registry OR-merges; the guard only opens one
5620
- * `useBlocker`).
5960
+ * dirty (the registry OR-merges; the guard only opens one
5961
+ * `useBlocker`).
5621
5962
  * - Nested contexts (inner `<MainContext>` inside outer
5622
- * `<RecordContext>`, etc.): only the outermost reports. Inner
5623
- * dirty state already bubbles up through the existing
5624
- * `registerDescendant` chain.
5963
+ * `<RecordContext>`, etc.): only the outermost reports. Inner
5964
+ * dirty state already bubbles up through the existing
5965
+ * `registerDescendant` chain.
5625
5966
  * - Editable grid with N row `<RecordContext>`s: rows aren't topmost
5626
- * (they're descendants of the page's MainContext), so they don't
5627
- * register here. Their edits flow up via `registerDescendant` and
5628
- * show in the page-level reporter's `isDirty`.
5967
+ * (they're descendants of the page's MainContext), so they don't
5968
+ * register here. Their edits flow up via `registerDescendant` and
5969
+ * show in the page-level reporter's `isDirty`.
5629
5970
  *
5630
5971
  * Same-pathname navigations (search-param tweaks, `replace: true` to
5631
5972
  * the current URL) are NOT blocked — the user isn't actually leaving
@@ -5648,8 +5989,7 @@ declare function RouterUnsavedChangesGuard(): null;
5648
5989
 
5649
5990
  /**
5650
5991
  * Orientation hint for the column's stacked children. Vertical (default)
5651
- * lays children out top-to-bottom; horizontal lays them in a row. Mirrors
5652
- * Blazor's `ComponentOrientation` on `SectionColumn`.
5992
+ * lays children out top-to-bottom; horizontal lays them in a row.
5653
5993
  */
5654
5994
  declare const SectionColumnOrientation: {
5655
5995
  readonly Vertical: "vertical";
@@ -5773,8 +6113,7 @@ declare function Section({ children, header, footer, headerText, footerText, bor
5773
6113
  /**
5774
6114
  * Theme-aware wrapper around `<Chart>`. Reads colors from the active
5775
6115
  * FluentUI design tokens and auto-fills missing dataset colors from a
5776
- * palette derived from the active accent. Mirrors
5777
- * `PowerPortalsPro.Web.Blazor.FluentUI.Components.FluentUIChart`.
6116
+ * palette derived from the active accent.
5778
6117
  *
5779
6118
  * Cartesian charts get one palette color per dataset; radial charts
5780
6119
  * (pie, doughnut, polarArea, radar, funnel) get one color per data point
@@ -5831,19 +6170,19 @@ interface DataverseChartProps {
5831
6170
  * The data source. Two shapes accepted; the chart discriminates at
5832
6171
  * runtime via `instanceof DataverseChartDataSource`:
5833
6172
  *
5834
- * - **`DataverseChartDataSource`** (and its subclasses
5835
- * `AggregateDataverseChartDataSource` /
5836
- * `ViewDataverseChartDataSource`) — stand-alone class instance.
5837
- * The chart owns the load/refresh lifecycle; the source just
5838
- * supplies the FetchXML and the post-load shaping. Use this
5839
- * when a chart owns its own fetch.
6173
+ * - **`DataverseChartDataSource`** (and its subclasses
6174
+ * `AggregateDataverseChartDataSource` /
6175
+ * `ViewDataverseChartDataSource`) — stand-alone class instance.
6176
+ * The chart owns the load/refresh lifecycle; the source just
6177
+ * supplies the FetchXML and the post-load shaping. Use this
6178
+ * when a chart owns its own fetch.
5840
6179
  *
5841
- * - **`ViewDataSource`** (from `useViewDataSource()`) — shared
5842
- * reactive store. The chart reads its aggregation result from
5843
- * {@link aggregationIndex} of `aggregationResults` and dispatches
5844
- * cross-filter state on slice clicks per {@link crossFilterMode}.
5845
- * Use this when one fetch should drive multiple grids/charts
5846
- * atomically (one round-trip, consistent snapshot).
6180
+ * - **`ViewDataSource`** (from `useViewDataSource()`) — shared
6181
+ * reactive store. The chart reads its aggregation result from
6182
+ * {@link aggregationIndex} of `aggregationResults` and dispatches
6183
+ * cross-filter state on slice clicks per {@link crossFilterMode}.
6184
+ * Use this when one fetch should drive multiple grids/charts
6185
+ * atomically (one round-trip, consistent snapshot).
5847
6186
  */
5848
6187
  dataSource: DataverseChartDataSource | ViewDataSource;
5849
6188
  /**
@@ -5857,14 +6196,14 @@ interface DataverseChartProps {
5857
6196
  /**
5858
6197
  * What happens when a chart slice is clicked while
5859
6198
  * {@link dataSource} is a `ViewDataSource`:
5860
- * - `'highlight'` (default) — soft cross-filter via
5861
- * `dataSource.setHighlight({ column, value })`. The matching
5862
- * slice stays opaque, other slices stay rendered but a sibling
5863
- * grid's non-matching rows dim. Click the same slice again to
5864
- * clear. NO server re-fetch — the cross-filter is purely styling.
5865
- * - `'none'` — no datasource interaction. Use the existing
5866
- * {@link onElementClick} callback for fully custom slice-click
5867
- * behavior (drill-through navigation, custom filter, etc.).
6199
+ * - `'highlight'` (default) — soft cross-filter via
6200
+ * `dataSource.setHighlight({ column, value })`. The matching
6201
+ * slice stays opaque, other slices stay rendered but a sibling
6202
+ * grid's non-matching rows dim. Click the same slice again to
6203
+ * clear. NO server re-fetch — the cross-filter is purely styling.
6204
+ * - `'none'` — no datasource interaction. Use the existing
6205
+ * {@link onElementClick} callback for fully custom slice-click
6206
+ * behavior (drill-through navigation, custom filter, etc.).
5868
6207
  *
5869
6208
  * Ignored when {@link dataSource} is a `DataverseChartDataSource`.
5870
6209
  * Consumer-supplied {@link onElementClick} STILL fires alongside
@@ -5941,7 +6280,7 @@ interface FluentChartPalette {
5941
6280
  * Reads the current chart palette from the CSS vars in scope at the
5942
6281
  * supplied DOM element. Call from a `useEffect` with a ref to an
5943
6282
  * element that sits INSIDE the FluentProvider (typically the chart's
5944
- * container) so Fluent v9's scoped design tokens resolve correctly
6283
+ * container) so Fluent v9's scoped design tokens resolve correctly
5945
6284
  * reading from html/body would miss them and the chart text would
5946
6285
  * fall back to a dim gray that's unreadable in dark mode.
5947
6286
  *
@@ -5954,30 +6293,28 @@ declare function getChartPalette(scope: Element): FluentChartPalette;
5954
6293
  * shapes the palette can produce after CSS variables are resolved:
5955
6294
  *
5956
6295
  * - `#rrggbb` (6-digit hex) — raw hex defaults baked into the palette
5957
- * when no CSS variable resolved.
6296
+ * when no CSS variable resolved.
5958
6297
  * - `rgb(r, g, b)` / `rgb(r g b)` — what `getComputedStyle()` returns
5959
- * when a CSS variable holds a hex value (browsers normalize colors
5960
- * to `rgb()` on read, even for `--var` values that LOOK like hex in
5961
- * the source CSS). This is what most FluentUI v9 tokens come back
5962
- * as in practice.
6298
+ * when a CSS variable holds a hex value (browsers normalize colors
6299
+ * to `rgb()` on read, even for `--var` values that LOOK like hex in
6300
+ * the source CSS). This is what most FluentUI v9 tokens come back
6301
+ * as in practice.
5963
6302
  * - `rgba(r, g, b, a)` — already-translucent values that we let through
5964
- * unchanged (overwriting the alpha would be presumptuous when the
5965
- * caller deliberately set one).
6303
+ * unchanged (overwriting the alpha would be presumptuous when the
6304
+ * caller deliberately set one).
5966
6305
  *
5967
6306
  * Anything else returns unchanged. Previously this only handled `#hex`
5968
6307
  * and let `rgb()` pass through opaque, so cartesian bar fills and
5969
- * borders ended up the same color in dark mode and the "translucent
5970
- * fill, full border" look from Blazor was lost.
6308
+ * borders ended up the same color in dark mode and the intended
6309
+ * "translucent fill, full border" look was lost.
5971
6310
  */
5972
6311
  declare function toTranslucent(color: string, alpha: number): string;
5973
6312
 
5974
6313
  /**
5975
6314
  * Reactive hook that reads the active FluentUI chart palette and re-reads
5976
- * whenever the page's design tokens change. Mirrors how Blazor's
5977
- * `FluentUIChart` subscribes to `ThemeService.ThemeChanged` the React
5978
- * surface area is a `MutationObserver` on the document root, since theme
5979
- * switches in FluentProvider land as class / style changes on a wrapping
5980
- * element.
6315
+ * whenever the page's design tokens change. Driven by a
6316
+ * `MutationObserver` on the document root, since theme switches in
6317
+ * FluentProvider land as class / style changes on a wrapping element.
5981
6318
  */
5982
6319
 
5983
6320
  /**
@@ -6000,4 +6337,4 @@ declare function useFluentChartPalette(scopeRef: RefObject<HTMLElement | null>):
6000
6337
 
6001
6338
  declare const VERSION = "0.1.0";
6002
6339
 
6003
- export { type AccentColor, type AccentThemePair, type BaseCellRendererProps, type BaseColumnEditProps, Body, type BodyProps, BoolEdit, type BoolEditProps, BoolEditorType, type CellRendererType, ChoiceEdit, type ChoiceEditProps, ChoiceEditorType, ChoiceInvalidValueBehavior, type ChoiceMetadataView, type ChoiceOption, ChoiceOrientation, ChoiceValueSort, ColumnDisplayValue, type ColumnDisplayValueProps, ColumnEdit, type CropAspect, type CropResult, type CustomViewDefinition, DataverseChart, type DataverseChartHandle, type DataverseChartProps, DateTimeEdit, type DateTimeEditProps, DateTimeEditorType, DeleteContextButton, type DeleteContextButtonProps, DeleteRecordGridButton, type DeleteRecordGridButtonProps, DescriptionLocation, type DialogLocation, type FileColumnValue, FileEdit, type FileEditProps, FileGrid, type FileGridProps, type FileSource, FileViewer, type FileViewerProps, type FluentChartPalette, FluentDialogProvider, FluentOverlayProvider, FluentOverlayTarget, FluentUIChart, type FluentUIChartProps, Footer, type FooterProps, GridButton, GridButtonBehavior, type GridButtonProps, GridButtonRole, type GridButtonRoleProps, GridButtons, type GridButtonsProps, GridColumn, type GridColumnAlign, type GridColumnCellRenderer, type GridColumnCellRendererProps, type GridColumnProps, GridColumns, type GridColumnsProps, type GridContextValue, type GridDeclaredColumn, GridTemplateColumn, type GridTemplateColumnCellRenderer, type GridTemplateColumnCellRendererProps, type GridTemplateColumnEditRenderer, type GridTemplateColumnEditRendererProps, type GridTemplateColumnProps, Header, type HeaderProps, Highlighter, type HighlighterProps, ImageEdit, type ImageEditProps, type ImageSource, ImageViewer, type ImageViewerHandle, type ImageViewerProps, LabelPosition, LanguageDropdown, type LanguageDropdownProps, type LinkExistingBulkMode, type LinkExistingRecordBehavior, LinkExistingRecordGridButton, type LinkExistingRecordGridButtonProps, LocalizationBoundary, type LocalizationBoundaryProps, LogoutButton, type LogoutButtonProps, type LookupColumnValue, LookupDialog, type LookupDialogProps, LookupEdit, type LookupEditProps, LookupEditorType, LookupForm, type LookupFormProps, type LookupMetadataView, MainGrid, type MainGridProps, ManyToManyLookupEdit, type ManyToManyLookupEditProps, ManyToManyLookupEditorType, MemoEdit, type MemoEditProps, MoneyEdit, type MoneyEditProps, MultiSelectChoiceEdit, type MultiSelectChoiceEditProps, NavGroup, type NavGroupProps, NavItem, type NavItemProps, type NavMatchMode, NavMenu, type NavMenuProps, NavigateNewRecordGridButton, type NavigateNewRecordGridButtonProps, NavigateOpenRecordGridButton, type NavigateOpenRecordGridButtonProps, NavigateRecordGridButton, type NavigateRecordGridButtonContext, type NavigateRecordGridButtonProps, type NewRecordDialogLocation, NewRecordGridButton, type NewRecordGridButtonBehavior, type NewRecordGridButtonProps, NumberEdit, type NumberEditProps, type NumberLimits, type NumberValueType, OpenRecordGridButton, type OpenRecordGridButtonBehavior, type OpenRecordGridButtonProps, PageLayout, type PageLayoutProps, PagingMode, type PendingRowCreate, type PendingRowUpdate, type PersistedGridState, type PersistedSort, PowerPortalsProThemeProvider, type PowerPortalsProThemeProviderProps, ProfileMainMenu, type ProfileMainMenuProps, RefreshContextButton, type RefreshContextButtonProps, RefreshGridButton, type RefreshGridButtonProps, RouterUnsavedChangesGuard, SaveContextButton, type SaveContextButtonProps, Section, SectionColumn, SectionColumnOrientation, type SectionColumnProps, type SectionProps, SiteSettingsButton, type SiteSettingsButtonProps, SiteSettingsPanel, type SiteSettingsPanelProps, type StepperVisibility, SubGrid, type SubGridProps, TextDirection, TextEdit, type TextEditProps, ThemeColorSelector, type ThemeColorSelectorProps, type ThemeContextValue, ThemeMode, ThemeSelector, type ThemeSelectorProps, ThemeTextDirection, type ThemeTextDirectionProps, type UnlinkExistingBulkMode, type UnlinkExistingRecordBehavior, UnlinkExistingRecordGridButton, type UnlinkExistingRecordGridButtonProps, VERSION, ValidationSummary, type ValidationSummaryProps, ViewSort, WizardRecordForm, type WizardRecordFormProps, WizardRecordPage, type WizardRecordPageProps, evaluateGridButtonBehavior, findFirstButtonOfRole, getCellRenderer, getChartPalette, getChoiceMetadata, getDisplayDescription, getDisplayLabel, getEditComponentForMetadata, getEditComponentForType, getGridButtonRoleFromElement, getLookupMetadata, getNumberLimits, getRendererTypeForMetadata, getStringMaxLength, isColumnSortable, isMetadataReadOnly, isMetadataRequired, isNewRecord, resolveColumnDisplayValue, setGridButtonRole, splitHighlightSegments, toTranslucent, useBoolColumn, useChoiceColumn, useDateColumn, useFileColumn, useFluentChartPalette, useGridContext, useLookupColumn, useMoneyColumn, useMultiSelectChoiceColumn, useNumberColumn, useStringColumn, useTheme };
6340
+ export { type AccentColor, type AccentThemePair, type BaseCellRendererProps, type BaseColumnEditProps, Body, type BodyProps, BoolEdit, type BoolEditProps, BoolEditorType, CacheAdmin, type CacheAdminProps, type CellRendererType, ChoiceEdit, type ChoiceEditProps, ChoiceEditorType, ChoiceInvalidValueBehavior, type ChoiceMetadataView, type ChoiceOption, ChoiceOrientation, ChoiceValueSort, ColumnDisplayValue, type ColumnDisplayValueProps, ColumnEdit, type CropAspect, type CropResult, type CustomViewDefinition, DataverseChart, type DataverseChartHandle, type DataverseChartProps, DateTimeEdit, type DateTimeEditProps, DateTimeEditorType, DeleteContextButton, type DeleteContextButtonProps, DeleteRecordGridButton, type DeleteRecordGridButtonProps, DescriptionLocation, type DialogLocation, type FileColumnValue, FileEdit, type FileEditProps, FileGrid, type FileGridProps, type FileSource, FileViewer, type FileViewerProps, type FluentChartPalette, FluentDialogProvider, FluentOverlayProvider, FluentOverlayTarget, FluentUIChart, type FluentUIChartProps, Footer, type FooterProps, GridButton, GridButtonBehavior, type GridButtonProps, GridButtonRole, type GridButtonRoleProps, GridButtons, type GridButtonsProps, GridColumn, type GridColumnAlign, type GridColumnCellRenderer, type GridColumnCellRendererProps, type GridColumnProps, GridColumns, type GridColumnsProps, type GridContextValue, type GridDeclaredColumn, GridTemplateColumn, type GridTemplateColumnCellRenderer, type GridTemplateColumnCellRendererProps, type GridTemplateColumnEditRenderer, type GridTemplateColumnEditRendererProps, type GridTemplateColumnProps, Header, type HeaderProps, Highlighter, type HighlighterProps, ImageEdit, type ImageEditProps, type ImageSource, ImageViewer, type ImageViewerHandle, type ImageViewerProps, LabelPosition, LanguageDropdown, type LanguageDropdownProps, type LinkExistingBulkMode, type LinkExistingRecordBehavior, LinkExistingRecordGridButton, type LinkExistingRecordGridButtonProps, LocalizationAdmin, type LocalizationAdminProps, LocalizationBoundary, type LocalizationBoundaryProps, LocalizationTranslator, type LocalizationTranslatorProps, LogoutButton, type LogoutButtonProps, type LookupColumnValue, LookupDialog, type LookupDialogProps, LookupEdit, type LookupEditProps, LookupEditorType, LookupForm, type LookupFormProps, type LookupMetadataView, MainGrid, type MainGridProps, ManyToManyLookupEdit, type ManyToManyLookupEditProps, ManyToManyLookupEditorType, MaskedTextField, type MaskedTextFieldHandle, type MaskedTextFieldProps, MemoEdit, type MemoEditProps, MenuBar, type MenuBarProps, MoneyEdit, type MoneyEditProps, MultiSelectChoiceEdit, type MultiSelectChoiceEditProps, NavGroup, type NavGroupProps, NavItem, type NavItemProps, type NavMatchMode, NavMenu, type NavMenuProps, NavigateNewRecordGridButton, type NavigateNewRecordGridButtonProps, NavigateOpenRecordGridButton, type NavigateOpenRecordGridButtonProps, NavigateRecordGridButton, type NavigateRecordGridButtonContext, type NavigateRecordGridButtonProps, type NewRecordDialogLocation, NewRecordGridButton, type NewRecordGridButtonBehavior, type NewRecordGridButtonProps, NumberEdit, type NumberEditProps, type NumberLimits, type NumberValueType, OFFICE_ACCENT_DEFINITIONS, OFFICE_ACCENT_HEX_TO_NAME, OFFICE_ACCENT_THEMES, OFFICE_COLOR_NAME_TO_ACCENT, type OfficeAccentDefinition, OpenRecordGridButton, type OpenRecordGridButtonBehavior, type OpenRecordGridButtonProps, PageLayout, type PageLayoutProps, PagingMode, type PendingRowCreate, type PendingRowUpdate, type PersistedGridState, type PersistedSort, PowerPortalsProThemeProvider, type PowerPortalsProThemeProviderProps, ProfileMainMenu, type ProfileMainMenuProps, RefreshContextButton, type RefreshContextButtonProps, RefreshGridButton, type RefreshGridButtonProps, RouterUnsavedChangesGuard, SaveContextButton, type SaveContextButtonProps, Section, SectionColumn, SectionColumnOrientation, type SectionColumnProps, type SectionProps, SiteSettingsButton, type SiteSettingsButtonProps, SiteSettingsPanel, type SiteSettingsPanelProps, type StepperVisibility, SubGrid, type SubGridProps, TextDirection, TextEdit, type TextEditProps, ThemeColorSelector, type ThemeColorSelectorProps, type ThemeContextValue, ThemeMode, ThemeSelector, type ThemeSelectorProps, ThemeTextDirection, type ThemeTextDirectionProps, type UnlinkExistingBulkMode, type UnlinkExistingRecordBehavior, UnlinkExistingRecordGridButton, type UnlinkExistingRecordGridButtonProps, VERSION, ValidationSummary, type ValidationSummaryProps, ViewSort, WizardRecordForm, type WizardRecordFormProps, WizardRecordPage, type WizardRecordPageProps, evaluateGridButtonBehavior, findFirstButtonOfRole, getCellRenderer, getChartPalette, getChoiceMetadata, getDisplayDescription, getDisplayLabel, getEditComponentForMetadata, getEditComponentForType, getGridButtonRoleFromElement, getLookupMetadata, getNumberLimits, getRendererTypeForMetadata, getStringMaxLength, isColumnSortable, isMetadataReadOnly, isMetadataRequired, isNewRecord, officeColorValueToAccentName, resolveColumnDisplayValue, setGridButtonRole, splitHighlightSegments, toTranslucent, useBoolColumn, useChoiceColumn, useDateColumn, useFileColumn, useFluentChartPalette, useGridContext, useLookupColumn, useMoneyColumn, useMultiSelectChoiceColumn, useNumberColumn, useStringColumn, useTheme };