@spfx-fast/sharepoint-ui 0.4.1 → 0.4.3
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/AGENTS.md +23 -3
- package/QUICKSTART.md +133 -0
- package/README.md +21 -878
- package/components.json +178 -33
- package/dist/appearance.js +4 -4
- package/dist/elements/alert.js +26 -2
- package/dist/elements/avatar.js +1 -1
- package/dist/elements/button.js +1 -1
- package/dist/elements/carousel.js +5 -2
- package/dist/elements/color-picker.js +1 -1
- package/dist/elements/combobox.js +5 -5
- package/dist/elements/data-grid-model.d.ts +3 -0
- package/dist/elements/data-grid.d.ts +2 -1
- package/dist/elements/data-grid.js +19 -10
- package/dist/elements/date-picker.js +1 -1
- package/dist/elements/dialog.js +1 -1
- package/dist/elements/file-upload.js +1 -1
- package/dist/elements/floating-position.d.ts +10 -0
- package/dist/elements/floating-position.js +53 -0
- package/dist/elements/info.js +1 -1
- package/dist/elements/input.js +2 -2
- package/dist/elements/link.js +1 -1
- package/dist/elements/message-bar.js +33 -5
- package/dist/elements/nav.js +4 -1
- package/dist/elements/overflow.d.ts +1 -0
- package/dist/elements/overflow.js +2 -2
- package/dist/elements/popover.js +1 -1
- package/dist/elements/rating.js +3 -3
- package/dist/elements/rich-text-editor.d.ts +15 -1
- package/dist/elements/rich-text-editor.js +938 -79
- package/dist/elements/search.js +3 -10
- package/dist/elements/select.js +2 -2
- package/dist/elements/shared.d.ts +4 -1
- package/dist/elements/shared.js +14 -1
- package/dist/elements/sharepoint-field-basic-controls.d.ts +1 -0
- package/dist/elements/sharepoint-field-basic-controls.js +14 -0
- package/dist/elements/sharepoint-fields.d.ts +29 -0
- package/dist/elements/sharepoint-fields.js +460 -0
- package/dist/elements/spin-button.js +2 -2
- package/dist/elements/tag-picker.js +29 -11
- package/dist/elements/textarea.js +2 -2
- package/dist/elements/toaster.js +2 -1
- package/dist/elements/tooltip.js +18 -1
- package/dist/elements/tree.js +1 -1
- package/dist/elements.d.ts +3 -2
- package/dist/elements.js +4 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.js +4 -2
- package/dist/react.d.ts +188 -19
- package/dist/react.js +321 -61
- package/dist/sharepoint-fields.d.ts +135 -0
- package/dist/sharepoint-fields.js +402 -0
- package/dist/theme.d.ts +9 -1
- package/dist/theme.js +78 -1
- package/package.json +11 -2
- package/skills/sharepoint-ui/SKILL.md +1 -1
- package/skills/sharepoint-ui/references/sharepoint-patterns.md +1 -1
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { createPortal } from "react-dom";
|
|
4
|
-
import { observeAccessibleTextFromIdRefs, resolveAccessibleTextFromIdRefs } from "./elements/shared.js";
|
|
4
|
+
import { getDirectionFromLanguage, observeAccessibleTextFromIdRefs, resolveAccessibleTextFromIdRefs } from "./elements/shared.js";
|
|
5
5
|
import { defineButton } from "./elements/button.js";
|
|
6
6
|
import { defineButtonGroup } from "./elements/button-group.js";
|
|
7
7
|
import { defineCompoundButton, defineMenuButton, defineSplitButton, defineToggleButton } from "./elements/button-variants.js";
|
|
@@ -27,7 +27,9 @@ import { defineSpinButton } from "./elements/spin-button.js";
|
|
|
27
27
|
import { defineSlider } from "./elements/slider.js";
|
|
28
28
|
import { defineDatePicker } from "./elements/date-picker.js";
|
|
29
29
|
import { defineCombobox } from "./elements/combobox.js";
|
|
30
|
-
import { defineRichTextEditor } from "./elements/rich-text-editor.js";
|
|
30
|
+
import { defineRichTextEditor, getRichTextEditorFieldOptions } from "./elements/rich-text-editor.js";
|
|
31
|
+
export { getRichTextEditorFieldOptions } from "./elements/rich-text-editor.js";
|
|
32
|
+
import { getSharePointFieldAdapter } from "./sharepoint-fields.js";
|
|
31
33
|
import { defineAlert } from "./elements/alert.js";
|
|
32
34
|
import { defineSkeleton, defineSkeletonItem } from "./elements/skeleton.js";
|
|
33
35
|
import { defineLink } from "./elements/link.js";
|
|
@@ -70,7 +72,8 @@ import { defineOverflow, defineOverflowItem, defineOverflowDivider } from "./ele
|
|
|
70
72
|
import { defineSwatchPicker as defineNativeSwatchPicker } from "./elements/swatch-picker.js";
|
|
71
73
|
import { createTableColumn as createNativeTableColumn, defineTable as defineNativeTable } from "./elements/table.js";
|
|
72
74
|
import { getSharePointUIStyleTokens } from "./appearance.js";
|
|
73
|
-
import { getSharePointUIDesignTokens } from "./theme.js";
|
|
75
|
+
import { getSharePointThemeColorPresets, getSharePointUIDesignTokens } from "./theme.js";
|
|
76
|
+
export { getSharePointThemeColorPresets } from "./theme.js";
|
|
74
77
|
export { createResizeObserverFromDocument, getRTLRootMargin, scrollToItemDynamic, scrollToItemStatic, useDynamicVirtualizerMeasure, useIntersectionObserver, useMeasureList, useResizeObserverRef_unstable, useStaticVirtualizerMeasure } from "./virtualizer-hooks.js";
|
|
75
78
|
export { composeSharePointUIDesignThemes } from "./theme.js";
|
|
76
79
|
const FieldContext = React.createContext(undefined);
|
|
@@ -105,9 +108,9 @@ export function useFieldControlProps_unstable(props, options = {}) {
|
|
|
105
108
|
next.style = { ...next.style, "--spui-control-border": tokens.border, "--spui-input-border": tokens.border, "--spui-focus-ring": tokens.border };
|
|
106
109
|
return next;
|
|
107
110
|
}
|
|
108
|
-
const defaultStrings = { loading: "Loading", close: "Close", dialogLabel: "Dialog", richTextEditorLabel: "Rich text", dismiss: "Dismiss", notifications: "Notifications", clear: "Clear", spinButtonIncrement: "Increment value", spinButtonDecrement: "Decrement value", remove: "Remove", noResults: "No results", selectedOptionsLabel: "Selected options", required: "Required", invalidValue: "Enter a valid value", moreInformation: "More information", people: "People", showMorePeople: "Show more people ({count})", showFewerPeople: "Show fewer people", navigationMenu: "Open navigation", navigationClose: "Close navigation", navigationExpand: "Expand navigation", navigationCollapse: "Collapse navigation", treeLabel: "Tree", treeToggleLabel: "Expand or collapse", treeEmptyMessage: "No items", splitButtonMenuLabel: "More options", navigationToggle: "Toggle navigation", splitNavItemActionLabel: "More actions", virtualizerLabel: "Items", dataGridLabel: "Data grid", dataGridFilterLabel: "Search rows", dataGridSelectRow: "Select row", dataGridSelectAll: "Select all rows", dataGridRowLabel: "row", dataGridLoadingLabel: "Loading…", dataGridEmptyLabel: "No items", dataGridSortPriority: "Sort priority {priority}", dataGridResizeLabel: "Resize column", dataGridReorderLabel: "Reorder column", dataGridEmptyGroupLabel: "No value", dataGridExpandGroupLabel: "Expand group", dataGridCollapseGroupLabel: "Collapse group", dataGridGroupCountLabel: "{count} items", dataGridEditHint: "Press Enter or F2 to edit", tableResizeHandle: "Resize column", dataGridSelectionCopied: "Selection copied.", dataGridCopyFailed: "Copy failed.
|
|
111
|
+
const defaultStrings = { loading: "Loading", close: "Close", dialogLabel: "Dialog", richTextEditorLabel: "Rich text", dismiss: "Dismiss", notifications: "Notifications", clear: "Clear", spinButtonIncrement: "Increment value", spinButtonDecrement: "Decrement value", remove: "Remove", noResults: "No results", selectedOptionsLabel: "Selected options", required: "Required", invalidValue: "Enter a valid value", moreInformation: "More information", people: "People", presenceAvailable: "Available", presenceBusy: "Busy", presenceDoNotDisturb: "Do not disturb", presenceAway: "Away", presenceOffline: "Offline", presenceUnknown: "Presence unknown", presenceOutOfOffice: "Out of office", presenceBlocked: "Blocked", presenceOutOfOfficeLabel: "{status}, out of office", showMorePeople: "Show more people ({count})", showFewerPeople: "Show fewer people", navigationMenu: "Open navigation", navigationClose: "Close navigation", navigationExpand: "Expand navigation", navigationCollapse: "Collapse navigation", treeLabel: "Tree", treeToggleLabel: "Expand or collapse", treeEmptyMessage: "No items", splitButtonMenuLabel: "More options", navigationToggle: "Toggle navigation", splitNavItemActionLabel: "More actions", virtualizerLabel: "Items", dataGridLabel: "Data grid", dataGridFilterLabel: "Search rows", dataGridSelectRow: "Select row", dataGridSelectAll: "Select all rows", dataGridRowLabel: "row", dataGridLoadingLabel: "Loading…", dataGridEmptyLabel: "No items", dataGridSortPriority: "Sort priority {priority}", dataGridResizeLabel: "Resize column", dataGridReorderLabel: "Reorder column", dataGridReorderHint: "Reorder {column}; use Alt+Shift+Arrow keys", dataGridLoadError: "Data could not be loaded.", dataGridEditError: "The value could not be saved.", dataGridEmptyGroupLabel: "No value", dataGridExpandGroupLabel: "Expand group", dataGridCollapseGroupLabel: "Collapse group", dataGridGroupCountLabel: "{count} items", dataGridEditHint: "Press Enter or F2 to edit", tableResizeHandle: "Resize column", dataGridSelectionCopied: "Selection copied.", dataGridCopyFailed: "Copy failed.", dataGridPasteOne: "Pasted {count} cell.", dataGridPasteMany: "Pasted {count} cells.", dataGridPasteFailed: "Paste failed.", dataGridColumnReordered: "{label}, {position} of {count}", toolbarLabel: "Toolbar", breadcrumbLabel: "Breadcrumb", menuBarLabel: "Menu bar", drawerExpand: "Expand drawer to full screen", drawerRestore: "Restore drawer size", drawerLabel: "Supplementary content", drawerNavigation: "Drawer navigation", tableResizeColumn: "Resize {column} column", ratingValue: "{value} of {max}", colorChoose: "Choose color", colorHex: "Hex color", colorHue: "Hue", colorArea: "Saturation and brightness", colorAreaValue: "{saturation}% saturation, {brightness}% brightness", colorSaturation: "Saturation", colorValue: "Brightness", colorFormat: "Color format", colorRgb: "RGB color values", colorRed: "Red", colorGreen: "Green", colorBlue: "Blue", colorOpacity: "Opacity", colorSwatches: "Color swatches", colorAdd: "Add color", colorSwatch: "Select {color}", colorInvalid: "Enter a 3 or 6 digit hex color, for example #336699.", richTextBold: "Bold", richTextTextColor: "Text color", richTextHighlightColor: "Highlight color", richTextCustomColor: "Custom color", richTextThemeAccent: "SharePoint theme accent", richTextFontFamily: "Font family", richTextFontSize: "Font size", richTextItalic: "Italic", richTextUnderline: "Underline", richTextStrike: "Strikethrough", richTextClearFormatting: "Clear formatting", richTextFormatBlock: "Text style", richTextParagraph: "Paragraph", richTextHeading1: "Heading 1", richTextHeading2: "Heading 2", richTextHeading3: "Heading 3", richTextBlockquote: "Quote", richTextPreformatted: "Preformatted", richTextBulletList: "Bulleted list", richTextNumberList: "Numbered list", richTextLink: "Link", richTextToolbar: "Rich text formatting", richTextLinkPrompt: "Link URL", richTextRequired: "Enter some text.", richTextChooseImage: "Choose image", richTextUndo: "Undo", richTextRedo: "Redo", richTextInsertTable: "Insert table", richTextInsertImage: "Insert image", richTextInsertRowAbove: "Insert row above", richTextInsertRowBelow: "Insert row below", richTextInsertColumnBefore: "Insert column before", richTextInsertColumnAfter: "Insert column after", richTextDeleteRow: "Delete row", richTextDeleteColumn: "Delete column", richTextDeleteTable: "Delete table", fileUploadBrowse: "Browse files", fileUploadDrop: "Drag files here or browse to select", fileUploadRemove: "Remove", fileUploadSelected: "Selected files", fileUploadRequired: "Select at least one file.", fileUploadTypeError: "The selected file type is not accepted.", fileUploadSizeError: "The selected file exceeds the allowed size.", fileUploadLimitError: "The maximum number of files has been reached.", carouselDescription: "Carousel", carouselPrevious: "Previous slide", carouselNext: "Next slide", carouselSlide: "Slide {index} of {count}", carouselRoleDescription: "carousel", carouselSlides: "Carousel slides", carouselNavigation: "Slide navigation", carouselPlay: "Play", carouselPause: "Pause", teachingPopoverLabel: "Guided steps", teachingPopoverDismiss: "Dismiss", teachingPopoverPrevious: "Previous step", teachingPopoverNext: "Next step", teachingPopoverFinish: "Finish tour", teachingPopoverSteps: "Tour steps", teachingPopoverPageCount: "{current} of {total}", teachingPopoverPageLabel: "Step {current} of {total}", overflowDescription: "Overflow actions", overflowMenuLabel: "More actions ({count})" };
|
|
109
112
|
const defaultHostStyle = Object.freeze({ "--spui-font-family": '"Segoe UI", sans-serif', "--spui-color-scheme": "light", colorScheme: "light" });
|
|
110
|
-
const UIContext = React.createContext({ appearance: "fluent", baseAppearance: "fluent", density: "comfortable", hasThemeValues: false, styleTokens: getSharePointUIStyleTokens(), fluentTokenStyles: {}, hostStyle: defaultHostStyle, providesCssInheritance: false, strings: defaultStrings });
|
|
113
|
+
const UIContext = React.createContext({ dirIsExplicit: false, appearance: "fluent", baseAppearance: "fluent", density: "comfortable", hasThemeValues: false, styleTokens: getSharePointUIStyleTokens(), fluentTokenStyles: {}, hostStyle: defaultHostStyle, providesCssInheritance: false, strings: defaultStrings });
|
|
111
114
|
const AvatarGroupSizeContext = React.createContext(32);
|
|
112
115
|
const AvatarGroupContext = React.createContext(undefined);
|
|
113
116
|
const BreadcrumbSizeContext = React.createContext("medium");
|
|
@@ -138,7 +141,9 @@ function hasDesignThemeValues(theme) {
|
|
|
138
141
|
function useHostProps(props) {
|
|
139
142
|
const context = React.useContext(UIContext);
|
|
140
143
|
const lang = context.lang || (typeof document === "undefined" ? undefined : document.documentElement.lang || undefined);
|
|
141
|
-
const
|
|
144
|
+
const documentDir = typeof document === "undefined" ? undefined : document.documentElement.dir || undefined;
|
|
145
|
+
const localLang = typeof props.lang === "string" ? props.lang : undefined;
|
|
146
|
+
const dir = props.dir ?? (context.dirIsExplicit ? context.dir : localLang ? getDirectionFromLanguage(localLang) ?? context.dir ?? documentDir : context.dir ?? documentDir ?? getDirectionFromLanguage(lang));
|
|
142
147
|
const style = context.providesCssInheritance ? props.style : props.style ? { ...context.hostStyle, ...props.style } : context.hostStyle;
|
|
143
148
|
const className = props.className;
|
|
144
149
|
return { ...props, className, "data-spui-appearance": props["data-spui-appearance"] ?? context.appearance, "data-spui-base-appearance": props["data-spui-base-appearance"] ?? context.baseAppearance, style, ...(props.lang === undefined && lang ? { lang } : {}), ...(props.dir === undefined && dir ? { dir } : {}) };
|
|
@@ -235,12 +240,25 @@ const nativeEventBindings = [
|
|
|
235
240
|
["transitionend", "onTransitionEnd", false, "transition"], ["transitionend", "onTransitionEndCapture", true, "transition"],
|
|
236
241
|
].map(([eventName, prop, capture, kind]) => ({ eventName, prop, capture, kind })),
|
|
237
242
|
];
|
|
243
|
+
const nativeEventBindingsByProp = new Map();
|
|
244
|
+
const nativeEventBindingOrder = new Map(nativeEventBindings.map((binding, index) => [binding, index]));
|
|
245
|
+
for (const binding of nativeEventBindings) {
|
|
246
|
+
const bindings = nativeEventBindingsByProp.get(binding.prop);
|
|
247
|
+
if (bindings)
|
|
248
|
+
bindings.push(binding);
|
|
249
|
+
else
|
|
250
|
+
nativeEventBindingsByProp.set(binding.prop, [binding]);
|
|
251
|
+
}
|
|
238
252
|
const nativeEventPropNames = new Set(nativeEventBindings.map(binding => binding.prop));
|
|
239
253
|
function withoutNativeControlEventProps(props) {
|
|
240
|
-
|
|
241
|
-
for (const prop
|
|
254
|
+
let hostProps;
|
|
255
|
+
for (const prop in props) {
|
|
256
|
+
if (!Object.prototype.hasOwnProperty.call(props, prop) || !nativeEventPropNames.has(prop))
|
|
257
|
+
continue;
|
|
258
|
+
hostProps ??= { ...props };
|
|
242
259
|
delete hostProps[prop];
|
|
243
|
-
|
|
260
|
+
}
|
|
261
|
+
return hostProps ?? props;
|
|
244
262
|
}
|
|
245
263
|
function nativeControlHostProps(props) {
|
|
246
264
|
return useCustomElementProps(withoutNativeControlEventProps(props));
|
|
@@ -249,7 +267,12 @@ function useNativeControlEvents(ref, selector, onClick, onClickCapture, events,
|
|
|
249
267
|
const handlers = { ...events, onClick, onClickCapture };
|
|
250
268
|
const handlersRef = React.useRef(handlers);
|
|
251
269
|
React.useLayoutEffect(() => { handlersRef.current = handlers; });
|
|
252
|
-
const activeBindings =
|
|
270
|
+
const activeBindings = [];
|
|
271
|
+
for (const prop of Object.keys(handlers)) {
|
|
272
|
+
if (typeof handlers[prop] === "function")
|
|
273
|
+
activeBindings.push(...(nativeEventBindingsByProp.get(prop) ?? []));
|
|
274
|
+
}
|
|
275
|
+
activeBindings.sort((a, b) => nativeEventBindingOrder.get(a) - nativeEventBindingOrder.get(b));
|
|
253
276
|
const subscriptionKey = activeBindings.map(binding => binding.eventName + ":" + binding.prop + ":" + (binding.capture ? 1 : 0)).join("|");
|
|
254
277
|
const hasMouseTransitions = typeof handlers.onMouseEnter === "function" || typeof handlers.onMouseLeave === "function";
|
|
255
278
|
const hasPointerTransitions = typeof handlers.onPointerEnter === "function" || typeof handlers.onPointerLeave === "function";
|
|
@@ -499,6 +522,10 @@ function useNativeMotionPresence(ref, visible, enabled, animationRoot = ref, ref
|
|
|
499
522
|
}
|
|
500
523
|
export function SharePointUIProvider({ children, lang, dir, appearance, baseAppearance, density, theme, tokens, fluentTokens, strings }) {
|
|
501
524
|
const parent = React.useContext(UIContext);
|
|
525
|
+
const resolvedLang = lang ?? parent.lang ?? (typeof document === "undefined" ? undefined : document.documentElement.lang || undefined);
|
|
526
|
+
const documentDir = typeof document === "undefined" ? undefined : document.documentElement.dir || undefined;
|
|
527
|
+
const resolvedDir = dir ?? (parent.dirIsExplicit ? parent.dir : lang !== undefined ? getDirectionFromLanguage(lang) ?? parent.dir ?? documentDir : parent.dir ?? documentDir ?? getDirectionFromLanguage(resolvedLang));
|
|
528
|
+
const dirIsExplicit = dir !== undefined || parent.dirIsExplicit;
|
|
502
529
|
const mergedTheme = { ...parent.theme, ...theme, palette: { ...parent.theme?.palette, ...theme?.palette }, fluentTokens: { ...parent.theme?.fluentTokens, ...theme?.fluentTokens }, colors: { ...parent.theme?.colors, ...theme?.colors }, typography: { ...parent.theme?.typography, ...theme?.typography }, spacing: { ...parent.theme?.spacing, ...theme?.spacing }, shape: { ...parent.theme?.shape, ...theme?.shape }, elevation: { ...parent.theme?.elevation, ...theme?.elevation }, materials: { ...parent.theme?.materials, ...theme?.materials }, motion: { ...parent.theme?.motion, ...theme?.motion }, layers: { ...parent.theme?.layers, ...theme?.layers }, customProperties: { ...parent.theme?.customProperties, ...theme?.customProperties } };
|
|
503
530
|
const mergedTokens = { ...parent.tokens, ...tokens };
|
|
504
531
|
const mergedFluentTokens = { ...parent.fluentTokens, ...fluentTokens };
|
|
@@ -510,8 +537,8 @@ export function SharePointUIProvider({ children, lang, dir, appearance, baseAppe
|
|
|
510
537
|
const hasThemeValues = hasDesignThemeValues(mergedTheme);
|
|
511
538
|
const inheritsDefaultTokens = resolvedAppearance === "fluent" && resolvedBaseAppearance === "fluent" && resolvedDensity === "comfortable" && !hasThemeValues && !Object.keys(mergedTokens).length && !Object.keys(mergedFluentTokens).length;
|
|
512
539
|
const hostStyle = inheritsDefaultTokens ? defaultHostStyle : Object.freeze({ ...fluentTokenStyles, ...styleTokens, colorScheme: styleTokens["--spui-color-scheme"] });
|
|
513
|
-
const value = { lang:
|
|
514
|
-
return _jsx(UIContext.Provider, { value: value, children: _jsx("div", { "data-spui-provider": "", "data-spui-appearance": resolvedAppearance, "data-spui-base-appearance": resolvedBaseAppearance, lang:
|
|
540
|
+
const value = { lang: resolvedLang, dir: resolvedDir, dirIsExplicit, appearance: resolvedAppearance, baseAppearance: resolvedBaseAppearance, density: resolvedDensity, theme: mergedTheme, hasThemeValues, tokens: mergedTokens, fluentTokens: mergedFluentTokens, styleTokens, fluentTokenStyles, hostStyle, providesCssInheritance: true, strings: { ...parent.strings, ...strings } };
|
|
541
|
+
return _jsx(UIContext.Provider, { value: value, children: _jsx("div", { "data-spui-provider": "", "data-spui-appearance": resolvedAppearance, "data-spui-base-appearance": resolvedBaseAppearance, lang: resolvedLang, dir: resolvedDir, style: { ...hostStyle, display: "contents" }, children: children }) });
|
|
515
542
|
}
|
|
516
543
|
export const Text = /* @__PURE__ */ React.forwardRef(function Text({ as = "span", size = 300, weight, font = "base", align = "start", italic = false, underline = false, strikethrough = false, truncate = false, wrap = true, block = false, children, style, ...props }, forwardedRef) {
|
|
517
544
|
const defaultBold = as === "strong" || as === "b";
|
|
@@ -836,7 +863,7 @@ export function useOverflowMenu(id) {
|
|
|
836
863
|
}, [registerOverflowMenu, id]);
|
|
837
864
|
return { ref, overflowCount, isOverflowing: hasOverflow };
|
|
838
865
|
}
|
|
839
|
-
export function Overflow({ children, label, minimumVisible = 0, overflowDirection = "end", overflowAxis = "horizontal", hasHiddenItems = false, overflowContent, padding = 10, onOverflowChange, onOverflowItemSelect, ...props }) {
|
|
866
|
+
export function Overflow({ children, label, minimumVisible = 0, overflowDirection = "end", overflowAxis = "horizontal", density = "comfortable", hasHiddenItems = false, overflowContent, padding = 10, onOverflowChange, onOverflowItemSelect, ...props }) {
|
|
840
867
|
const ref = React.useRef(null);
|
|
841
868
|
const [overflowIds, setOverflowIds] = React.useState([]);
|
|
842
869
|
const [overflowState, setOverflowState] = React.useState(emptyOverflowContext);
|
|
@@ -941,7 +968,7 @@ export function Overflow({ children, label, minimumVisible = 0, overflowDirectio
|
|
|
941
968
|
});
|
|
942
969
|
const trigger = React.createElement(Button, { appearance: "subtle", size: "small", iconOnly: true, "aria-label": menuLabel }, React.createElement("span", { "aria-hidden": true }, "⋯"));
|
|
943
970
|
const menu = React.createElement(Menu, { label: label || strings.overflowDescription, trigger, onSelect: value => onOverflowItemSelect?.(value) }, ...menuItems, overflowContent);
|
|
944
|
-
const host = React.createElement("spui-overflow", useCustomElementProps({ ...props, ref, "aria-label": label || strings.overflowDescription, "minimum-visible": minimumVisible, "overflow-direction": overflowDirection, "overflow-axis": overflowAxis, "has-hidden-items": hasHiddenItems || undefined, padding }), children, React.createElement("div", { slot: "overflow-trigger", hidden: overflowIds.length === 0 && !hasHiddenItems }, menu));
|
|
971
|
+
const host = React.createElement("spui-overflow", useCustomElementProps({ ...props, ref, "aria-label": label || strings.overflowDescription, "minimum-visible": minimumVisible, "overflow-direction": overflowDirection, "overflow-axis": overflowAxis, density, "has-hidden-items": hasHiddenItems || undefined, padding }), children, React.createElement("div", { slot: "overflow-trigger", hidden: overflowIds.length === 0 && !hasHiddenItems }, menu));
|
|
945
972
|
return React.createElement(OverflowProvider, { value: contextValue }, host);
|
|
946
973
|
}
|
|
947
974
|
export const Card = /* @__PURE__ */ React.forwardRef(function Card({ children, appearance = "filled", orientation = "vertical", size = "medium", focusMode, selected, defaultSelected, disabled = false, selectionLabel, checkbox, floatingAction, onSelectionChange, ...props }, forwardedRef) {
|
|
@@ -1310,10 +1337,10 @@ export const Drawer = /* @__PURE__ */ React.forwardRef(function Drawer({ type =
|
|
|
1310
1337
|
export function DrawerHeader({ children }) {
|
|
1311
1338
|
return React.createElement(React.Fragment, null, children);
|
|
1312
1339
|
}
|
|
1313
|
-
export function DrawerHeaderNavigation({ children, label, ...props }) {
|
|
1340
|
+
export const DrawerHeaderNavigation = /* @__PURE__ */ React.forwardRef(function DrawerHeaderNavigation({ children, label, ...props }, forwardedRef) {
|
|
1314
1341
|
const context = React.useContext(UIContext);
|
|
1315
|
-
return React.createElement("nav", useHostProps({ ...props, slot: "header-navigation", "aria-label": props["aria-label"] ?? label ?? context.strings.drawerNavigation ?? "Drawer navigation", style: { display: "flex", alignItems: "center", gap: 8, ...props.style } }), children);
|
|
1316
|
-
}
|
|
1342
|
+
return React.createElement("nav", useHostProps({ ...props, ref: forwardedRef, slot: "header-navigation", "aria-label": props["aria-label"] ?? label ?? context.strings.drawerNavigation ?? "Drawer navigation", style: { display: "flex", alignItems: "center", gap: 8, ...props.style } }), children);
|
|
1343
|
+
});
|
|
1317
1344
|
export function DrawerHeaderTitle({ children, action, heading, ...props }) {
|
|
1318
1345
|
const headingElement = heading;
|
|
1319
1346
|
const title = React.isValidElement(headingElement)
|
|
@@ -1321,12 +1348,12 @@ export function DrawerHeaderTitle({ children, action, heading, ...props }) {
|
|
|
1321
1348
|
: React.createElement("h2", { slot: "title", "data-spui-drawer-title": "", style: { margin: 0 }, ...(heading ?? {}) }, children);
|
|
1322
1349
|
return React.createElement(React.Fragment, null, React.createElement("div", useHostProps({ ...props, slot: "title", "data-spui-drawer-title": "", style: { display: "flex", alignItems: "center", ...props.style } }), title), action == null ? null : React.createElement("span", { slot: "header-action", style: { display: "inline-flex", alignItems: "center" } }, action));
|
|
1323
1350
|
}
|
|
1324
|
-
export function DrawerBody({ children, ...props }) {
|
|
1325
|
-
return React.createElement("div", useHostProps({ ...props, style: { minWidth: 0, ...props.style } }), children);
|
|
1326
|
-
}
|
|
1327
|
-
export function DrawerFooter({ children, ...props }) {
|
|
1328
|
-
return React.createElement("div", useHostProps({ ...props, slot: "actions", style: { display: "flex", alignItems: "center", justifyContent: "flex-end", flexWrap: "wrap", gap: 8, ...props.style } }), children);
|
|
1329
|
-
}
|
|
1351
|
+
export const DrawerBody = /* @__PURE__ */ React.forwardRef(function DrawerBody({ children, ...props }, forwardedRef) {
|
|
1352
|
+
return React.createElement("div", useHostProps({ ...props, ref: forwardedRef, style: { minWidth: 0, ...props.style } }), children);
|
|
1353
|
+
});
|
|
1354
|
+
export const DrawerFooter = /* @__PURE__ */ React.forwardRef(function DrawerFooter({ children, ...props }, forwardedRef) {
|
|
1355
|
+
return React.createElement("div", useHostProps({ ...props, ref: forwardedRef, slot: "actions", style: { display: "flex", alignItems: "center", justifyContent: "flex-end", flexWrap: "wrap", gap: 8, ...props.style } }), children);
|
|
1356
|
+
});
|
|
1330
1357
|
export const InlineDrawer = /* @__PURE__ */ React.forwardRef(function InlineDrawer({ open = false, title, position = "start", size = "small", separator = false, unmountOnClose = true, surfaceMotion, actions, children, ...props }, forwardedRef) {
|
|
1331
1358
|
const context = React.useContext(UIContext);
|
|
1332
1359
|
ensureDefined(defineInlineDrawer);
|
|
@@ -1521,7 +1548,7 @@ export const DatePicker = /* @__PURE__ */ React.forwardRef(function DatePicker(i
|
|
|
1521
1548
|
return React.createElement("spui-date-picker", nativeControlHostProps({ ...props, ref, label, min, max, name, placeholder, required, disabled, "read-only": readOnly, "calendar-label": calendarLabel ?? context.strings.datePickerCalendar, "previous-month-label": previousMonthLabel ?? context.strings.datePickerPreviousMonth, "next-month-label": nextMonthLabel ?? context.strings.datePickerNextMonth, "invalid-date-message": invalidDateMessage ?? context.strings.datePickerInvalid, "required-message": requiredMessage ?? context.strings.datePickerRequired }));
|
|
1522
1549
|
});
|
|
1523
1550
|
export const ComboBox = /* @__PURE__ */ React.forwardRef(function ComboBox(inputProps, forwardedRef) {
|
|
1524
|
-
const { label, selectedLabel, value, defaultValue, selectedValue, selectedOptions, defaultSelectedOptions, multiselect = false, name, input, listbox, mountNode, placeholder, required, disabled, freeform, allowFreeform, noResults, clearable, clearIcon, expandIcon, defaultOpen, disableAutoFocus, inlinePopup, open, appearance, size, positioning, onValueChange, onOptionSelect, onSelectedOptionsChange, onOpenChange, onActiveOptionChange, children, ...props } = useFieldControlProps_unstable(inputProps, { supportsRequired: true, supportsSize: true });
|
|
1551
|
+
const { label, selectedLabel, requiredMessage, value, defaultValue, selectedValue, selectedOptions, defaultSelectedOptions, multiselect = false, name, input, listbox, mountNode, placeholder, required, disabled, freeform, allowFreeform, noResults, clearable, clearIcon, expandIcon, defaultOpen, disableAutoFocus, inlinePopup, open, appearance, size, positioning, onValueChange, onOptionSelect, onSelectedOptionsChange, onOpenChange, onActiveOptionChange, children, ...props } = useFieldControlProps_unstable(inputProps, { supportsRequired: true, supportsSize: true });
|
|
1525
1552
|
const ref = React.useRef(null);
|
|
1526
1553
|
useExposeHostRef(ref, forwardedRef);
|
|
1527
1554
|
;
|
|
@@ -1609,7 +1636,7 @@ export const ComboBox = /* @__PURE__ */ React.forwardRef(function ComboBox(input
|
|
|
1609
1636
|
const expandIconSlot = expandIcon == null ? null : React.isValidElement(expandIcon)
|
|
1610
1637
|
? React.cloneElement(expandIcon, { slot: "expand-icon" })
|
|
1611
1638
|
: React.createElement("span", { slot: "expand-icon", "aria-hidden": true }, expandIcon);
|
|
1612
|
-
return React.createElement(CompoundComboboxContext.Provider, { value: { ...provider, mode: "combobox", value: value ?? provider?.value, selectedOptions: selectedOptions ?? provider?.selectedOptions, multiselect } }, React.createElement(React.Fragment, null, React.createElement("spui-combobox", nativeControlHostProps({ ...props, ref, label, "selected-label": selectedLabel ?? context.strings.selectedOptionsLabel, value: value ?? defaultValue ?? provider?.value, "selected-value": selectedValue, multiselect: multiselect || undefined, name, placeholder, required, disabled, "allow-freeform": freeform ?? allowFreeform, "no-results": noResults ?? context.strings.noResults, clearable, "default-open": open === undefined && provider?.open === undefined ? defaultOpen : undefined, open: open ?? provider?.open ? "" : undefined, "disable-auto-focus": disableAutoFocus, appearance: appearance ?? provider?.appearance, size: size ?? provider?.size, positioning: typeof positioning === "string" ? positioning : positioning?.position ? `${positioning.position}${positioning.align && positioning.align !== "center" ? `-${positioning.align}` : ""}` : undefined, "inline-popup": inlinePopup }), children, inputSlot, clearIconSlot, expandIconSlot, listboxSlot), listboxPortal));
|
|
1639
|
+
return React.createElement(CompoundComboboxContext.Provider, { value: { ...provider, mode: "combobox", value: value ?? provider?.value, selectedOptions: selectedOptions ?? provider?.selectedOptions, multiselect } }, React.createElement(React.Fragment, null, React.createElement("spui-combobox", nativeControlHostProps({ ...props, ref, label, "selected-label": selectedLabel ?? context.strings.selectedOptionsLabel, "required-message": requiredMessage ?? context.strings.required, value: value ?? defaultValue ?? provider?.value, "selected-value": selectedValue, multiselect: multiselect || undefined, name, placeholder, required, disabled, "allow-freeform": freeform ?? allowFreeform, "no-results": noResults ?? context.strings.noResults, clearable, "default-open": open === undefined && provider?.open === undefined ? defaultOpen : undefined, open: open ?? provider?.open ? "" : undefined, "disable-auto-focus": disableAutoFocus, appearance: appearance ?? provider?.appearance, size: size ?? provider?.size, positioning: typeof positioning === "string" ? positioning : positioning?.position ? `${positioning.position}${positioning.align && positioning.align !== "center" ? `-${positioning.align}` : ""}` : undefined, "inline-popup": inlinePopup }), children, inputSlot, clearIconSlot, expandIconSlot, listboxSlot), listboxPortal));
|
|
1613
1640
|
});
|
|
1614
1641
|
export const ComboOption = /* @__PURE__ */ React.forwardRef(function ComboOption({ value, label, disabled, children }, forwardedRef) {
|
|
1615
1642
|
ensureDefined(defineCombobox);
|
|
@@ -1801,8 +1828,14 @@ export const OptionGroup = /* @__PURE__ */ React.forwardRef(function OptionGroup
|
|
|
1801
1828
|
return React.createElement("spui-combobox-option-group", useCustomElementProps({ ref: forwardedRef, ...props, label }), children);
|
|
1802
1829
|
return _jsxs("div", { ...props, ref: forwardedRef, role: "group", "aria-label": label, children: [label ? _jsx("div", { children: label }) : null, children] });
|
|
1803
1830
|
});
|
|
1831
|
+
const richTextEditorModeRank = { plain: 0, restricted: 1, rich: 2, html: 3 };
|
|
1804
1832
|
export const RichTextEditor = /* @__PURE__ */ React.forwardRef(function RichTextEditor(inputProps, forwardedRef) {
|
|
1805
|
-
const { label, editorLabel, value, defaultValue, placeholder, disabled, readOnly, required, name, onValueChange, onImageUpload, ...props } = useFieldControlProps_unstable(inputProps, { supportsRequired: true });
|
|
1833
|
+
const { label, editorLabel, value, defaultValue, placeholder, field, contentMode, allowHyperlink, disabled, readOnly, required, name, onValueChange, onImageUpload, onImageUploadError, linkPicker, onLinkPickerError, ...props } = useFieldControlProps_unstable(inputProps, { supportsRequired: true });
|
|
1834
|
+
const fieldOptions = field ? getRichTextEditorFieldOptions(field) : undefined;
|
|
1835
|
+
const effectiveContentMode = fieldOptions && contentMode
|
|
1836
|
+
? richTextEditorModeRank[contentMode] < richTextEditorModeRank[fieldOptions.contentMode] ? contentMode : fieldOptions.contentMode
|
|
1837
|
+
: contentMode ?? fieldOptions?.contentMode;
|
|
1838
|
+
const effectiveAllowHyperlink = fieldOptions?.allowHyperlink === false ? false : allowHyperlink ?? fieldOptions?.allowHyperlink;
|
|
1806
1839
|
const ref = React.useRef(null);
|
|
1807
1840
|
useExposeHostRef(ref, forwardedRef);
|
|
1808
1841
|
;
|
|
@@ -1812,10 +1845,18 @@ export const RichTextEditor = /* @__PURE__ */ React.forwardRef(function RichText
|
|
|
1812
1845
|
React.useEffect(() => { const element = ref.current; if (element)
|
|
1813
1846
|
element.uploadImage = onImageUpload; return () => { if (element)
|
|
1814
1847
|
delete element.uploadImage; }; }, [onImageUpload]);
|
|
1848
|
+
React.useEffect(() => { const element = ref.current; if (element)
|
|
1849
|
+
element.linkPicker = linkPicker; return () => { if (element)
|
|
1850
|
+
delete element.linkPicker; }; }, [linkPicker]);
|
|
1815
1851
|
useSpuiEvent(ref, "spui-input", value !== undefined || onValueChange ? detail => {
|
|
1816
1852
|
onValueChange?.(String(detail.value ?? ""));
|
|
1817
|
-
|
|
1818
|
-
|
|
1853
|
+
} : undefined);
|
|
1854
|
+
useSpuiEvent(ref, "spui-image-upload-error", onImageUploadError ? detail => {
|
|
1855
|
+
const data = detail;
|
|
1856
|
+
onImageUploadError({ fileName: String(data.fileName ?? ""), error: data.error });
|
|
1857
|
+
} : undefined);
|
|
1858
|
+
useSpuiEvent(ref, "spui-link-picker-error", onLinkPickerError ? detail => {
|
|
1859
|
+
onLinkPickerError(detail.error);
|
|
1819
1860
|
} : undefined);
|
|
1820
1861
|
React.useLayoutEffect(() => {
|
|
1821
1862
|
const element = ref.current;
|
|
@@ -1831,7 +1872,7 @@ export const RichTextEditor = /* @__PURE__ */ React.forwardRef(function RichText
|
|
|
1831
1872
|
element.value = defaultValue;
|
|
1832
1873
|
}
|
|
1833
1874
|
}, [value, defaultValue]);
|
|
1834
|
-
return React.createElement("spui-rich-text-editor", nativeControlHostProps({ ...props, ref, label, placeholder, disabled, "read-only": readOnly, required, name, "required-message": strings.richTextRequired, "editor-label": editorLabel ?? strings.richTextEditorLabel, "bold-label": strings.richTextBold, "italic-label": strings.richTextItalic, "underline-label": strings.richTextUnderline, "bullet-list-label": strings.richTextBulletList, "number-list-label": strings.richTextNumberList, "link-label": strings.richTextLink, "undo-label": strings.richTextUndo, "redo-label": strings.richTextRedo, "insert-table-label": strings.richTextInsertTable, "insert-image-label": strings.richTextInsertImage, "image-input-label": strings.richTextChooseImage, "insert-row-above-label": strings.richTextInsertRowAbove, "insert-row-below-label": strings.richTextInsertRowBelow, "insert-column-before-label": strings.richTextInsertColumnBefore, "insert-column-after-label": strings.richTextInsertColumnAfter, "delete-row-label": strings.richTextDeleteRow, "delete-column-label": strings.richTextDeleteColumn, "delete-table-label": strings.richTextDeleteTable, "toolbar-label": strings.richTextToolbar, "link-prompt": strings.richTextLinkPrompt }));
|
|
1875
|
+
return React.createElement("spui-rich-text-editor", nativeControlHostProps({ ...props, ref, label, placeholder, "content-mode": effectiveContentMode, "allow-hyperlink": effectiveAllowHyperlink === false ? "false" : undefined, disabled, "read-only": readOnly, required, name, "required-message": strings.richTextRequired, "editor-label": editorLabel ?? strings.richTextEditorLabel, "bold-label": strings.richTextBold, "italic-label": strings.richTextItalic, "underline-label": strings.richTextUnderline, "strike-label": strings.richTextStrike ?? "Strikethrough", "subscript-label": strings.richTextSubscript ?? "Subscript", "superscript-label": strings.richTextSuperscript ?? "Superscript", "align-left-label": strings.richTextAlignLeft ?? "Align left", "align-center-label": strings.richTextAlignCenter ?? "Align center", "align-right-label": strings.richTextAlignRight ?? "Align right", "align-justify-label": strings.richTextAlignJustify ?? "Justify text", "clear-formatting-label": strings.richTextClearFormatting ?? "Clear formatting", "format-block-label": strings.richTextFormatBlock ?? "Text style", "font-family-label": strings.richTextFontFamily ?? "Font family", "font-size-label": strings.richTextFontSize ?? "Font size", "paragraph-label": strings.richTextParagraph ?? "Paragraph", "heading-1-label": strings.richTextHeading1 ?? "Heading 1", "heading-2-label": strings.richTextHeading2 ?? "Heading 2", "heading-3-label": strings.richTextHeading3 ?? "Heading 3", "blockquote-label": strings.richTextBlockquote ?? "Quote", "preformatted-label": strings.richTextPreformatted ?? "Preformatted", "bullet-list-label": strings.richTextBulletList, "number-list-label": strings.richTextNumberList, "link-label": strings.richTextLink, "text-color-label": strings.richTextTextColor ?? "Text color", "highlight-color-label": strings.richTextHighlightColor ?? "Highlight color", "custom-color-label": strings.richTextCustomColor ?? "Custom color", "theme-accent-label": strings.richTextThemeAccent ?? "SharePoint theme accent", "color-swatch-label": strings.colorSwatch, "undo-label": strings.richTextUndo, "redo-label": strings.richTextRedo, "insert-table-label": strings.richTextInsertTable, "insert-image-label": strings.richTextInsertImage, "image-input-label": strings.richTextChooseImage, "insert-row-above-label": strings.richTextInsertRowAbove, "insert-row-below-label": strings.richTextInsertRowBelow, "insert-column-before-label": strings.richTextInsertColumnBefore, "insert-column-after-label": strings.richTextInsertColumnAfter, "delete-row-label": strings.richTextDeleteRow, "delete-column-label": strings.richTextDeleteColumn, "delete-table-label": strings.richTextDeleteTable, "toolbar-label": strings.richTextToolbar, "link-prompt": strings.richTextLinkPrompt, "link-dialog-label": strings.richTextLinkDialog ?? "Edit link", "link-text-label": strings.richTextLinkText ?? "Display text", "link-title-label": strings.richTextLinkTitle ?? "Title", "link-apply-label": strings.richTextLinkApply ?? "Apply link", "link-remove-label": strings.richTextLinkRemove ?? "Remove link", "link-cancel-label": strings.richTextLinkCancel ?? strings.close, "link-new-tab-label": strings.richTextLinkNewTab ?? "Open in new tab", "link-invalid-message": strings.richTextLinkInvalid ?? "Enter a valid HTTP, HTTPS, or mailto link.", "link-picker-label": strings.richTextLinkBrowse ?? "Browse SharePoint", "link-picker-loading-label": strings.richTextLinkBrowsing ?? "Opening picker…", "link-picker-error-message": strings.richTextLinkPickerError ?? "Unable to open the SharePoint link picker." }));
|
|
1835
1876
|
});
|
|
1836
1877
|
export const Badge = /* @__PURE__ */ React.forwardRef(function Badge({ children, icon, appearance = "filled", color = "brand", iconPosition = "before", shape = "circular", size = "medium", ...props }, forwardedRef) {
|
|
1837
1878
|
ensureDefined(defineBadge);
|
|
@@ -1843,7 +1884,10 @@ export const CounterBadge = /* @__PURE__ */ React.forwardRef(function CounterBad
|
|
|
1843
1884
|
});
|
|
1844
1885
|
export const PresenceBadge = /* @__PURE__ */ React.forwardRef(function PresenceBadge({ status = "available", outOfOffice = false, size = "medium", icon, ...props }, forwardedRef) {
|
|
1845
1886
|
ensureDefined(definePresenceBadge);
|
|
1846
|
-
|
|
1887
|
+
const strings = React.useContext(UIContext).strings;
|
|
1888
|
+
const statusLabel = strings[presenceStringKeys[status]] ?? status.replaceAll("-", " ");
|
|
1889
|
+
const presenceLabel = outOfOffice && status !== "out-of-office" ? (strings.presenceOutOfOfficeLabel ?? "{status}, out of office").replace("{status}", statusLabel) : statusLabel;
|
|
1890
|
+
return React.createElement("spui-presence-badge", useCustomElementProps({ ref: forwardedRef, ...props, status, "aria-label": props["aria-label"] ?? presenceLabel, "out-of-office": outOfOffice || undefined, size }), icon == null ? null : React.createElement("span", { slot: "icon", "aria-hidden": true }, icon));
|
|
1847
1891
|
});
|
|
1848
1892
|
export const Tag = /* @__PURE__ */ React.forwardRef(function Tag({ children, appearance, size, shape = "rounded", color, value, label, disabled = false, selected = false, dismissible = false, dismissLabel, onDismiss, media, icon, primaryText, secondaryText, dismissIcon, ...props }, forwardedRef) {
|
|
1849
1893
|
const ref = React.useRef(null);
|
|
@@ -1897,7 +1941,7 @@ export const TagGroup = /* @__PURE__ */ React.forwardRef(function TagGroup({ chi
|
|
|
1897
1941
|
}, [selectedValues]);
|
|
1898
1942
|
return React.createElement("spui-tag-group", useCustomElementProps({ ...props, ref, role: props.role ?? "toolbar", orientation, label, appearance, size, disabled: disabled || undefined, dismissible: dismissible || undefined, "default-selected-values": defaultSelectedValues === undefined ? undefined : JSON.stringify(defaultSelectedValues), "aria-label": props["aria-label"] ?? label }), children);
|
|
1899
1943
|
});
|
|
1900
|
-
export const TagPicker = /* @__PURE__ */ React.forwardRef(function TagPicker({ children, label, selectedLabel, selectedOptions, defaultSelectedOptions, selectedValues, defaultSelectedValues, inputValue, open, defaultOpen, positioning, disableAutoFocus = false, inline = false, noPopover = false, disabled, onOpenChange, onOptionSelect, onInputValueChange, onChange, ...props }, forwardedRef) {
|
|
1944
|
+
export const TagPicker = /* @__PURE__ */ React.forwardRef(function TagPicker({ children, label, selectedLabel, requiredMessage, selectedOptions, defaultSelectedOptions, selectedValues, defaultSelectedValues, inputValue, open, defaultOpen, positioning, disableAutoFocus = false, inline = false, noPopover = false, disabled, onOpenChange, onOptionSelect, onInputValueChange, onChange, ...props }, forwardedRef) {
|
|
1901
1945
|
const ref = React.useRef(null);
|
|
1902
1946
|
useExposeHostRef(ref, forwardedRef);
|
|
1903
1947
|
;
|
|
@@ -1937,7 +1981,7 @@ export const TagPicker = /* @__PURE__ */ React.forwardRef(function TagPicker({ c
|
|
|
1937
1981
|
}, [selected, inputValue, open, defaultOpen]);
|
|
1938
1982
|
React.useLayoutEffect(() => { const element = ref.current; if (element)
|
|
1939
1983
|
element.positioning = positioning; }, [positioning]);
|
|
1940
|
-
return React.createElement("spui-tag-picker", useCustomElementProps({ ...props, ref, label, disabled, "disable-auto-focus": disableAutoFocus || undefined, "selected-label": selectedLabel ?? strings.selectedOptionsLabel, "default-selected-options": defaultSelected === undefined ? undefined : JSON.stringify(defaultSelected), "input-value": inputValue, inline: inline || undefined, "no-popover": noPopover || undefined, "no-results": strings.noResults, "remove-label": strings.remove }), children);
|
|
1984
|
+
return React.createElement("spui-tag-picker", useCustomElementProps({ ...props, ref, label, disabled, "disable-auto-focus": disableAutoFocus || undefined, "selected-label": selectedLabel ?? strings.selectedOptionsLabel, "required-message": requiredMessage ?? strings.required, "default-selected-options": defaultSelected === undefined ? undefined : JSON.stringify(defaultSelected), "input-value": inputValue, inline: inline || undefined, "no-popover": noPopover || undefined, "no-results": strings.noResults, "remove-label": strings.remove }), children);
|
|
1941
1985
|
});
|
|
1942
1986
|
export function TagPickerControl({ children, secondaryAction, expandIcon }) {
|
|
1943
1987
|
return React.createElement(React.Fragment, null, children, secondaryAction == null ? null : React.createElement("span", { slot: "secondary-action" }, secondaryAction), expandIcon == null ? null : React.createElement("span", { slot: "expand-icon", "aria-hidden": true }, expandIcon));
|
|
@@ -1962,16 +2006,16 @@ export const TagPickerInput = /* @__PURE__ */ React.forwardRef(function TagPicke
|
|
|
1962
2006
|
export function TagPickerList({ children }) {
|
|
1963
2007
|
return React.createElement(React.Fragment, null, children);
|
|
1964
2008
|
}
|
|
1965
|
-
export function TagPickerButton({ children, appearance = "outline", size = "medium", disabled = false, ...props }) {
|
|
1966
|
-
return React.createElement("button",
|
|
1967
|
-
}
|
|
2009
|
+
export const TagPickerButton = /* @__PURE__ */ React.forwardRef(function TagPickerButton({ children, appearance = "outline", size = "medium", disabled = false, ...props }, forwardedRef) {
|
|
2010
|
+
return React.createElement("button", useHostProps({ ...props, ref: forwardedRef, slot: "button", type: "button", "data-appearance": appearance, "data-size": size, disabled: disabled || undefined }), children);
|
|
2011
|
+
});
|
|
1968
2012
|
export const TagPickerOption = /* @__PURE__ */ React.forwardRef(function TagPickerOption({ value, text, label, group, media, secondaryContent, disabled = false, children, ...props }, forwardedRef) {
|
|
1969
2013
|
return React.createElement("spui-tag-picker-option", useCustomElementProps({ ref: forwardedRef, ...props, value, text, label, group, disabled: disabled || undefined }), media == null ? null : React.createElement("span", { slot: "media" }, media), React.createElement("span", { slot: "label" }, children), secondaryContent == null ? null : React.createElement("span", { slot: "secondary-content" }, secondaryContent));
|
|
1970
2014
|
});
|
|
1971
2015
|
export const TagPickerOptionGroup = /* @__PURE__ */ React.forwardRef(function TagPickerOptionGroup({ children, label, disabled = false }, forwardedRef) {
|
|
1972
2016
|
return React.createElement("spui-tag-picker-option-group", useCustomElementProps({ ref: forwardedRef, label, disabled: disabled || undefined }), children);
|
|
1973
2017
|
});
|
|
1974
|
-
export const Rating = /* @__PURE__ */ React.forwardRef(function Rating({ value, defaultValue = 0, max = 5, step = 1, size = "extra-large", color = "neutral", label, itemLabel, iconFilled, iconOutline, fullValueInput, halfValueInput, name, disabled = false, readOnly = false, required = false, onChange, ...props }, forwardedRef) {
|
|
2018
|
+
export const Rating = /* @__PURE__ */ React.forwardRef(function Rating({ value, defaultValue = 0, max = 5, step = 1, size = "extra-large", color = "neutral", label, requiredMessage, itemLabel, iconFilled, iconOutline, fullValueInput, halfValueInput, name, disabled = false, readOnly = false, required = false, onChange, ...props }, forwardedRef) {
|
|
1975
2019
|
const ref = React.useRef(null);
|
|
1976
2020
|
useExposeHostRef(ref, forwardedRef);
|
|
1977
2021
|
;
|
|
@@ -1995,7 +2039,7 @@ export const Rating = /* @__PURE__ */ React.forwardRef(function Rating({ value,
|
|
|
1995
2039
|
? React.cloneElement(slot, { slot: name, hidden: true, "aria-hidden": true, tabIndex: -1 })
|
|
1996
2040
|
: React.createElement("input", { ...slot, slot: name, hidden: true, "aria-hidden": true, tabIndex: -1 });
|
|
1997
2041
|
};
|
|
1998
|
-
return React.createElement("spui-rating", useCustomElementProps({ ...props, ref, value, "default-value": defaultValue, max, step, size, color, label, name, disabled: disabled || undefined, readonly: readOnly || undefined, required: required || undefined, "item-label": strings.ratingValue }), iconOutline == null ? null : React.createElement("span", { slot: "icon-outline", hidden: true }, React.createElement(iconOutline, { "aria-hidden": true, focusable: "false" })), iconFilled == null ? null : React.createElement("span", { slot: "icon-filled", hidden: true }, React.createElement(iconFilled, { "aria-hidden": true, focusable: "false" })), inputSlot(fullValueInput, "full-value-input"), inputSlot(halfValueInput, "half-value-input"));
|
|
2042
|
+
return React.createElement("spui-rating", useCustomElementProps({ ...props, ref, value, "default-value": defaultValue, max, step, size, color, label, name, disabled: disabled || undefined, readonly: readOnly || undefined, required: required || undefined, "required-message": requiredMessage ?? strings.required, "item-label": strings.ratingValue }), iconOutline == null ? null : React.createElement("span", { slot: "icon-outline", hidden: true }, React.createElement(iconOutline, { "aria-hidden": true, focusable: "false" })), iconFilled == null ? null : React.createElement("span", { slot: "icon-filled", hidden: true }, React.createElement(iconFilled, { "aria-hidden": true, focusable: "false" })), inputSlot(fullValueInput, "full-value-input"), inputSlot(halfValueInput, "half-value-input"));
|
|
1999
2043
|
});
|
|
2000
2044
|
export const RatingItem = /* @__PURE__ */ React.forwardRef(function RatingItem({ value = 1, selectedIcon, unselectedIcon, ...props }, forwardedRef) {
|
|
2001
2045
|
ensureDefined(defineRatingItem);
|
|
@@ -2208,7 +2252,7 @@ export const BreadcrumbDivider = /* @__PURE__ */ React.forwardRef(function Bread
|
|
|
2208
2252
|
ensureDefined(defineBreadcrumbDivider);
|
|
2209
2253
|
return React.createElement("spui-breadcrumb-divider", useCustomElementProps({ ...props, ref: forwardedRef }), children);
|
|
2210
2254
|
});
|
|
2211
|
-
export const Nav = /* @__PURE__ */ React.forwardRef(function Nav({ children, label = "Navigation", selectedValue, defaultSelectedValue, selectedCategoryValue, defaultSelectedCategoryValue, openCategories, defaultOpenCategories = [], open, defaultOpen, collapsed, defaultCollapsed, collapsible = false, multiple = true, density = "medium", openLabel, closeLabel, onItemSelect, onCategoryToggle, onNavItemSelect, onNavCategoryItemToggle, onOpenChange, onCollapsedChange, onClick, onClickCapture, onKeyDown, onKeyDownCapture, onKeyUp, onKeyUpCapture, onKeyPress, onKeyPressCapture, onFocus, onFocusCapture, onBlur, onBlurCapture, onAuxClick, onAuxClickCapture, onContextMenu, onContextMenuCapture, onDoubleClick, onDoubleClickCapture, onMouseDown, onMouseDownCapture, onMouseMove, onMouseMoveCapture, onMouseOut, onMouseOutCapture, onMouseOver, onMouseOverCapture, onMouseUp, onMouseUpCapture, onGotPointerCapture, onGotPointerCaptureCapture, onLostPointerCapture, onLostPointerCaptureCapture, onPointerCancel, onPointerCancelCapture, onPointerDown, onPointerDownCapture, onPointerMove, onPointerMoveCapture, onPointerOut, onPointerOutCapture, onPointerOver, onPointerOverCapture, onPointerUp, onPointerUpCapture, onMouseEnter, onMouseLeave, onPointerEnter, onPointerLeave, ...props }, forwardedRef) {
|
|
2255
|
+
export const Nav = /* @__PURE__ */ React.forwardRef(function Nav({ children, label = "Navigation", selectedValue, defaultSelectedValue, selectedCategoryValue, defaultSelectedCategoryValue, openCategories, defaultOpenCategories = [], open, defaultOpen, collapsed, defaultCollapsed, fullWidth = false, collapsible = false, multiple = true, density = "medium", openLabel, closeLabel, onItemSelect, onCategoryToggle, onNavItemSelect, onNavCategoryItemToggle, onOpenChange, onCollapsedChange, onClick, onClickCapture, onKeyDown, onKeyDownCapture, onKeyUp, onKeyUpCapture, onKeyPress, onKeyPressCapture, onFocus, onFocusCapture, onBlur, onBlurCapture, onAuxClick, onAuxClickCapture, onContextMenu, onContextMenuCapture, onDoubleClick, onDoubleClickCapture, onMouseDown, onMouseDownCapture, onMouseMove, onMouseMoveCapture, onMouseOut, onMouseOutCapture, onMouseOver, onMouseOverCapture, onMouseUp, onMouseUpCapture, onGotPointerCapture, onGotPointerCaptureCapture, onLostPointerCapture, onLostPointerCaptureCapture, onPointerCancel, onPointerCancelCapture, onPointerDown, onPointerDownCapture, onPointerMove, onPointerMoveCapture, onPointerOut, onPointerOutCapture, onPointerOver, onPointerOverCapture, onPointerUp, onPointerUpCapture, onMouseEnter, onMouseLeave, onPointerEnter, onPointerLeave, ...props }, forwardedRef) {
|
|
2212
2256
|
const ref = React.useRef(null);
|
|
2213
2257
|
useExposeHostRef(ref, forwardedRef);
|
|
2214
2258
|
;
|
|
@@ -2246,7 +2290,7 @@ export const Nav = /* @__PURE__ */ React.forwardRef(function Nav({ children, lab
|
|
|
2246
2290
|
element.defaultCollapsed = defaultCollapsed;
|
|
2247
2291
|
defaultsApplied.current = true;
|
|
2248
2292
|
}, [selectedValue, defaultSelectedValue, selectedCategoryValue, defaultSelectedCategoryValue, openCategories, defaultOpenCategories, open, defaultOpen, collapsed, defaultCollapsed]);
|
|
2249
|
-
return React.createElement("spui-nav", nativeControlHostProps({ ...props, ref, label, multiple: multiple ? "" : "false", density, collapsible: collapsible || undefined, "open-label": openLabel ?? strings.navigationMenu ?? "Open navigation", "close-label": closeLabel ?? strings.navigationClose ?? strings.close, "expand-label": strings.navigationExpand ?? "Expand navigation", "collapse-label": strings.navigationCollapse ?? "Collapse navigation" }), children);
|
|
2293
|
+
return React.createElement("spui-nav", nativeControlHostProps({ ...props, ref, label, multiple: multiple ? "" : "false", density, "full-width": fullWidth || undefined, collapsible: collapsible || undefined, "open-label": openLabel ?? strings.navigationMenu ?? "Open navigation", "close-label": closeLabel ?? strings.navigationClose ?? strings.close, "expand-label": strings.navigationExpand ?? "Expand navigation", "collapse-label": strings.navigationCollapse ?? "Collapse navigation" }), children);
|
|
2250
2294
|
});
|
|
2251
2295
|
function renderNavAvatar(avatar) {
|
|
2252
2296
|
return avatar ? React.cloneElement(avatar, { slot: "avatar", ...(avatar.type === Avatar ? { decorative: true } : {}) }) : null;
|
|
@@ -3087,6 +3131,7 @@ export function AvatarGroupPopover({ children, count, indicator, label, triggerL
|
|
|
3087
3131
|
const context = React.useContext(UIContext);
|
|
3088
3132
|
const size = React.useContext(AvatarGroupSizeContext);
|
|
3089
3133
|
const itemCount = count ?? React.Children.count(children);
|
|
3134
|
+
const resolvedLabel = label ?? context.strings.people ?? "More people";
|
|
3090
3135
|
const triggerText = (triggerLabel ?? context.strings.showMorePeople ?? "Show more people ({count})").replace("{count}", String(itemCount));
|
|
3091
3136
|
const showCount = indicator ?? (size < 24 ? "icon" : "count");
|
|
3092
3137
|
const defaultTriggerContent = showCount === "icon"
|
|
@@ -3110,12 +3155,13 @@ export function AvatarGroupPopover({ children, count, indicator, label, triggerL
|
|
|
3110
3155
|
: React.createElement("ul", { ...contentProps, role: contentProps.role ?? "list" }, React.createElement(AvatarGroupOverflowContext.Provider, { value: true }, listChildren));
|
|
3111
3156
|
const surfaceElement = React.isValidElement(popoverSurface) ? popoverSurface : undefined;
|
|
3112
3157
|
const surfaceProps = (surfaceElement ? surfaceElement.props : popoverSurface ?? {});
|
|
3158
|
+
const surfaceLabel = surfaceProps["aria-label"] ?? resolvedLabel;
|
|
3113
3159
|
const surfaceContent = surfaceElement
|
|
3114
|
-
? React.cloneElement(surfaceElement, { "aria-label":
|
|
3115
|
-
: React.createElement(PopoverSurface, { ...surfaceProps, "aria-label":
|
|
3160
|
+
? React.cloneElement(surfaceElement, { "aria-label": surfaceLabel, tabIndex: surfaceProps.tabIndex ?? 0, children: listContent })
|
|
3161
|
+
: React.createElement(PopoverSurface, { ...surfaceProps, "aria-label": surfaceLabel, tabIndex: surfaceProps.tabIndex ?? 0 }, listContent);
|
|
3116
3162
|
return React.createElement(Popover, {
|
|
3117
3163
|
...props,
|
|
3118
|
-
label:
|
|
3164
|
+
label: resolvedLabel,
|
|
3119
3165
|
placement,
|
|
3120
3166
|
open,
|
|
3121
3167
|
trapFocus: true,
|
|
@@ -3123,15 +3169,18 @@ export function AvatarGroupPopover({ children, count, indicator, label, triggerL
|
|
|
3123
3169
|
onOpenChange: (_event, data) => onOpenChange?.(data.open),
|
|
3124
3170
|
}, surfaceContent);
|
|
3125
3171
|
}
|
|
3172
|
+
const presenceStringKeys = { available: "presenceAvailable", busy: "presenceBusy", "do-not-disturb": "presenceDoNotDisturb", away: "presenceAway", offline: "presenceOffline", unknown: "presenceUnknown", "out-of-office": "presenceOutOfOffice", blocked: "presenceBlocked" };
|
|
3126
3173
|
export const Persona = /* @__PURE__ */ React.forwardRef(function Persona({ name, image, initials, primaryText, secondaryText, tertiaryText, quaternaryText, presence, presenceLabel, size = "medium", color = "neutral", textPosition = "after", textAlignment = "start", presenceOnly = false, avatar, children, ...props }, forwardedRef) {
|
|
3127
3174
|
ensureDefined(definePersona);
|
|
3128
3175
|
const ref = React.useRef(null);
|
|
3129
3176
|
useExposeHostRef(ref, forwardedRef);
|
|
3130
3177
|
useNativeControlEvents(ref, ".layout", props.onClick, props.onClickCapture, props);
|
|
3178
|
+
const strings = React.useContext(UIContext).strings;
|
|
3179
|
+
const presenceLabelFromProvider = presence ? strings[presenceStringKeys[presence]] : undefined;
|
|
3131
3180
|
const textSlot = (node, slot) => node == null ? null : React.isValidElement(node)
|
|
3132
3181
|
? React.cloneElement(node, { slot })
|
|
3133
3182
|
: React.createElement("span", { slot }, node);
|
|
3134
|
-
return React.createElement("spui-persona", nativeControlHostProps({ ref, ...props, name, image, initials, "secondary-text": typeof secondaryText === "string" ? secondaryText : undefined, "tertiary-text": typeof tertiaryText === "string" ? tertiaryText : undefined, presence, "presence-label": presenceLabel, size, color, "text-position": textPosition, "text-alignment": textAlignment, "presence-only": presenceOnly || undefined }), textSlot(primaryText, "primary-text"), textSlot(secondaryText, "secondary-text"), textSlot(tertiaryText, "tertiary-text"), textSlot(quaternaryText, "quaternary-text"), avatar === undefined ? null : React.createElement("span", { slot: "avatar" }, avatar), children === undefined ? null : React.createElement("span", { slot: "details" }, children));
|
|
3183
|
+
return React.createElement("spui-persona", nativeControlHostProps({ ref, ...props, name, image, initials, "secondary-text": typeof secondaryText === "string" ? secondaryText : undefined, "tertiary-text": typeof tertiaryText === "string" ? tertiaryText : undefined, presence, "presence-label": presenceLabel ?? presenceLabelFromProvider, size, color, "text-position": textPosition, "text-alignment": textAlignment, "presence-only": presenceOnly || undefined }), textSlot(primaryText, "primary-text"), textSlot(secondaryText, "secondary-text"), textSlot(tertiaryText, "tertiary-text"), textSlot(quaternaryText, "quaternary-text"), avatar === undefined ? null : React.createElement("span", { slot: "avatar" }, avatar), children === undefined ? null : React.createElement("span", { slot: "details" }, children));
|
|
3135
3184
|
});
|
|
3136
3185
|
const VirtualizerScrollViewRootContext = React.createContext(null);
|
|
3137
3186
|
function mergeVirtualizerRootProps(slotProps, rootProps) {
|
|
@@ -3660,7 +3709,7 @@ const EMPTY_DATA_GRID_ITEMS = [];
|
|
|
3660
3709
|
const EMPTY_DATA_GRID_COLUMN_WIDTHS = Object.freeze({});
|
|
3661
3710
|
const EMPTY_DATA_GRID_COLUMN_SIZING_OPTIONS = Object.freeze({});
|
|
3662
3711
|
const DEFAULT_DATA_GRID_RESIZABLE_COLUMNS_OPTIONS = Object.freeze({ autoFitColumns: true });
|
|
3663
|
-
function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroupToggle, columns, getRowId, label: labelProp, height = 400, rowHeight = 40, getRowHeight, overscan = 4, virtualize, virtualizeColumns, focusMode = "cell", subtleSelection = false, selectionAppearance = "brand", selectionMode = "none", selectedKeys, defaultSelectedKeys = [], selectionModel, defaultSelectionModel, onDataSourceSelectionChange, onSelectionChange, sort, defaultSort, onSortChange, multiSort, defaultMultiSort = [], onMultiSortChange, sortPriorityLabel: sortPriorityLabelProp, filterable = false, filterValue, defaultFilterValue = "", onFilterValueChange, filterLabel: filterLabelProp, renderCell, onCellEdit, onCellsEdit, validateCellEdit, rowLabel: rowLabelProp, editHint: editHintProp, emptyMessage: emptyMessageProp, loadingLabel: loadingLabelProp, selectLabel: selectLabelProp, selectAllLabel: selectAllLabelProp, resizableColumns = false, columnWidths, defaultColumnWidths = EMPTY_DATA_GRID_COLUMN_WIDTHS, columnSizingOptions = EMPTY_DATA_GRID_COLUMN_SIZING_OPTIONS, resizableColumnsOptions = DEFAULT_DATA_GRID_RESIZABLE_COLUMNS_OPTIONS, containerWidthOffset = 0, onColumnResize, resizeLabel: resizeLabelProp, reorderableColumns = false, columnOrder, defaultColumnOrder, onColumnOrderChange, reorderLabel: reorderLabelProp, groupBy, collapsedGroupKeys, defaultCollapsedGroupKeys = [], onCollapsedGroupKeysChange, emptyGroupLabel: emptyGroupLabelProp, expandGroupLabel: expandGroupLabelProp, collapseGroupLabel: collapseGroupLabelProp, onRenderedRange, ...props }) {
|
|
3712
|
+
function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroupToggle, columns, getRowId, label: labelProp, height = 400, rowHeight = 40, getRowHeight, overscan = 4, virtualize, virtualizeColumns, focusMode = "cell", subtleSelection = false, selectionAppearance = "brand", selectionMode = "none", selectedKeys, defaultSelectedKeys = [], selectionModel, defaultSelectionModel, onDataSourceSelectionChange, onSelectionChange, sort, defaultSort, onSortChange, multiSort, defaultMultiSort = [], onMultiSortChange, sortPriorityLabel: sortPriorityLabelProp, filterable = false, filterValue, defaultFilterValue = "", onFilterValueChange, filterLabel: filterLabelProp, renderCell, onCellEdit, onCellEditError, onCellsEdit, validateCellEdit, rowLabel: rowLabelProp, editHint: editHintProp, emptyMessage: emptyMessageProp, loadingLabel: loadingLabelProp, selectLabel: selectLabelProp, selectAllLabel: selectAllLabelProp, resizableColumns = false, columnWidths, defaultColumnWidths = EMPTY_DATA_GRID_COLUMN_WIDTHS, columnSizingOptions = EMPTY_DATA_GRID_COLUMN_SIZING_OPTIONS, resizableColumnsOptions = DEFAULT_DATA_GRID_RESIZABLE_COLUMNS_OPTIONS, containerWidthOffset = 0, onColumnResize, resizeLabel: resizeLabelProp, reorderableColumns = false, columnOrder, defaultColumnOrder, onColumnOrderChange, reorderLabel: reorderLabelProp, groupBy, collapsedGroupKeys, defaultCollapsedGroupKeys = [], onCollapsedGroupKeysChange, emptyGroupLabel: emptyGroupLabelProp, expandGroupLabel: expandGroupLabelProp, collapseGroupLabel: collapseGroupLabelProp, onRenderedRange, ...props }) {
|
|
3664
3713
|
selectionMode = selectionMode === "multiselect" ? "multiple" : selectionMode;
|
|
3665
3714
|
const [scrollTop, setScrollTop] = React.useState(0);
|
|
3666
3715
|
const [viewportHeight, setViewportHeight] = React.useState(typeof height === "number" ? height : 400);
|
|
@@ -3996,7 +4045,9 @@ function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroup
|
|
|
3996
4045
|
}
|
|
3997
4046
|
catch (reason) {
|
|
3998
4047
|
const message = reason instanceof Error ? reason.message : String(reason || "The value could not be saved.");
|
|
3999
|
-
updateEditingCell({ ...current, draft, saving: false, error:
|
|
4048
|
+
updateEditingCell({ ...current, draft, saving: false, error: uiStrings.dataGridEditError ?? defaultStrings.dataGridEditError });
|
|
4049
|
+
onCellEditError?.({ item: edit.item, rowId: edit.rowId, columnId: edit.columnId, previousValue: edit.previousValue, value: edit.value, error: message });
|
|
4050
|
+
viewport.current?.dispatchEvent(new CustomEvent("spui-cell-edit-error", { detail: { item: edit.item, rowId: edit.rowId, columnId: edit.columnId, previousValue: edit.previousValue, value: edit.value, error: message }, bubbles: true, composed: true }));
|
|
4000
4051
|
requestAnimationFrame(() => viewport.current?.querySelector("[data-testid='spui-data-grid-editor']")?.focus());
|
|
4001
4052
|
}
|
|
4002
4053
|
};
|
|
@@ -4093,7 +4144,7 @@ function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroup
|
|
|
4093
4144
|
if (controller.signal.aborted)
|
|
4094
4145
|
return;
|
|
4095
4146
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
4096
|
-
setReorderAnnouncement(
|
|
4147
|
+
setReorderAnnouncement(uiStrings.dataGridCopyFailed ?? defaultStrings.dataGridCopyFailed);
|
|
4097
4148
|
viewport.current?.dispatchEvent(new CustomEvent("spui-clipboard-error", { detail: { operation: "copy", message }, bubbles: true, composed: true }));
|
|
4098
4149
|
});
|
|
4099
4150
|
};
|
|
@@ -4177,7 +4228,7 @@ function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroup
|
|
|
4177
4228
|
if (clipboardController.current?.signal.aborted)
|
|
4178
4229
|
return;
|
|
4179
4230
|
const message = reason instanceof Error ? reason.message : String(reason);
|
|
4180
|
-
setReorderAnnouncement(
|
|
4231
|
+
setReorderAnnouncement(uiStrings.dataGridPasteFailed ?? defaultStrings.dataGridPasteFailed);
|
|
4181
4232
|
viewport.current?.dispatchEvent(new CustomEvent("spui-cells-edit-error", { detail: { message, edits }, bubbles: true, composed: true }));
|
|
4182
4233
|
}
|
|
4183
4234
|
};
|
|
@@ -4416,7 +4467,7 @@ function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroup
|
|
|
4416
4467
|
else
|
|
4417
4468
|
setSelection(event.currentTarget.checked ? sortedItems.map(getRowId).map(String) : []); } }) }), orderedColumns.map((column, columnIndex) => _jsxs("div", { role: "columnheader", "data-column-id": column.id, "data-column-index": columnIndex, "aria-colindex": columnIndex + (selectionMode === "none" ? 1 : 2), "aria-sort": column.sortable === false ? undefined : activeSorts[0]?.columnId === column.id ? activeSorts[0].direction : "none", className: "spui-grid-cell spui-grid-header-cell", onDragOver: event => { if (reorderableColumns && draggedColumn.current)
|
|
4418
4469
|
event.preventDefault(); }, onDrop: event => { event.preventDefault(); const rect = event.currentTarget.getBoundingClientRect(); const rtl = getComputedStyle(viewport.current).direction === "rtl"; const after = rtl ? event.clientX < rect.left + rect.width / 2 : event.clientX > rect.left + rect.width / 2; if (reorderableColumns)
|
|
4419
|
-
moveColumn(draggedColumn.current ?? "", column.id, after); draggedColumn.current = undefined; }, children: [reorderableColumns && _jsx("button", { type: "button", className: "spui-grid-reorder-handle", "data-reorder-column": column.id, draggable: true, "aria-label": `${reorderLabel} ${column.label}`, title:
|
|
4470
|
+
moveColumn(draggedColumn.current ?? "", column.id, after); draggedColumn.current = undefined; }, children: [reorderableColumns && _jsx("button", { type: "button", className: "spui-grid-reorder-handle", "data-reorder-column": column.id, draggable: true, "aria-label": `${reorderLabel} ${column.label}`, title: (uiStrings.dataGridReorderHint ?? defaultStrings.dataGridReorderHint).replace("{column}", column.label), onDragStart: event => { draggedColumn.current = column.id; event.dataTransfer.effectAllowed = "move"; event.dataTransfer.setData("text/plain", column.id); }, onDragEnd: () => { draggedColumn.current = undefined; }, children: "\u283F" }), column.sortable === false ? column.label : _jsxs("button", { type: "button", "aria-label": activeSorts.some(entry => entry.columnId === column.id) ? `${column.label}, ${sortPriorityLabel.replace("{priority}", String(activeSorts.findIndex(entry => entry.columnId === column.id) + 1))}` : column.label, onClick: event => changeSort(column.id, event.shiftKey), children: [column.label, activeSorts.some(entry => entry.columnId === column.id) ? ` ${activeSorts.findIndex(entry => entry.columnId === column.id) + 1}${activeSorts.find(entry => entry.columnId === column.id)?.direction === "ascending" ? "▲" : "▼"}` : ""] }), resizableColumns && column.resizable !== false && _jsx("div", { ref: element => { if (element && activeColumnWidths[column.id] === undefined)
|
|
4420
4471
|
element.setAttribute("aria-valuenow", String(Math.round(element.parentElement?.getBoundingClientRect().width ?? 120))); }, className: "spui-grid-resize-handle", "data-resize-column": column.id, role: "separator", "aria-orientation": "vertical", "aria-label": `${resizeLabel} ${column.label}`, "aria-valuemin": getDataGridColumnSizing(column, columnSizingOptions).minWidth, "aria-valuemax": column.maxWidth ?? 1600, "aria-valuenow": activeColumnWidths[column.id] ?? getDataGridColumnSizing(column, columnSizingOptions).defaultWidth, tabIndex: 0, onDoubleClick: event => autoFitResize(column, event), onPointerDown: event => startResize(column, event), onPointerMove: moveResize, onPointerUp: event => endResize(event), onPointerCancel: event => endResize(event, true), onLostPointerCapture: event => endResize(event, true) })] }, column.id))] }) }), _jsx("div", { role: "rowgroup", style: { position: "relative" }, children: (dataSource ? sourceLength : sortedItems.length) === 0 ? _jsx("div", { role: "row", "aria-rowindex": 2, className: "spui-grid-row", style: { gridTemplateColumns: gridColumns }, children: _jsx("div", { role: "gridcell", className: "spui-grid-cell", style: { gridColumn: `1 / span ${columns.length + (selectionMode === "none" ? 0 : 1)}` }, children: shownEmptyMessage }) }) : _jsxs(_Fragment, { children: [_jsx("div", { "aria-hidden": "true", role: "presentation", style: { height: shouldVirtualize ? rowSizes.offset(first) : 0 } }), Array.from({ length: last - first }, (_, offset) => {
|
|
4421
4472
|
const rowIndex = first + offset;
|
|
4422
4473
|
const sourceRow = dataSource ? getDataGridDataSourceRow(dataSource, rowIndex) : undefined;
|
|
@@ -4448,9 +4499,9 @@ function VirtualDataGrid({ items, dataSource, onDataLoadError, onDataSourceGroup
|
|
|
4448
4499
|
else if (event.key === "Enter") {
|
|
4449
4500
|
event.preventDefault();
|
|
4450
4501
|
event.currentTarget.blur();
|
|
4451
|
-
} }, style: { boxSizing: "border-box", width: "100%", minWidth: 0, minHeight: 30, padding: "3px 6px", border: `
|
|
4502
|
+
} }, style: { boxSizing: "border-box", width: "100%", minWidth: 0, minHeight: 30, padding: "3px 6px", border: `2px solid var(${editingCell.error ? "--spui-semantic-danger" : "--spui-ui-accent"},${editingCell.error ? "#d13438" : "#78716c"})`, outline: "none", borderRadius: "var(--spui-control-radius,4px)", background: "var(--spui-base-surface,var(--spui-ui-surface,#fff))", color: "var(--spui-ui-text,var(--spui-semantic-body-text,#242424))", font: "inherit" } })] }) : Object.hasOwn(editedCells, editedKey) ? String(displayValue ?? "") : renderCell ? renderCell(item, column, itemIndex) : String(displayValue ?? "") }, column.id);
|
|
4452
4503
|
})] }, key);
|
|
4453
|
-
}), _jsx("div", { "aria-hidden": "true", role: "presentation", style: { height: shouldVirtualize ? Math.max(0, rowSizes.totalSize - rowSizes.offset(last)) : 0 } })] }) })] }), _jsx("div", { className: "spui-grid-reorder-status", role: "status", "aria-live": "polite", children: sourceError ?
|
|
4504
|
+
}), _jsx("div", { "aria-hidden": "true", role: "presentation", style: { height: shouldVirtualize ? Math.max(0, rowSizes.totalSize - rowSizes.offset(last)) : 0 } })] }) })] }), _jsx("div", { className: "spui-grid-reorder-status", role: "status", "aria-live": "polite", children: sourceError ? uiStrings.dataGridLoadError ?? defaultStrings.dataGridLoadError : reorderAnnouncement })] });
|
|
4454
4505
|
}
|
|
4455
4506
|
const defaultDataGridContextValue = {
|
|
4456
4507
|
items: [], totalRows: 0, firstRow: 0, lastRow: 0, rowHeight: 40, sourceBusy: false, sourceError: "",
|
|
@@ -4523,7 +4574,7 @@ function useDataGridContextSelector(selector) {
|
|
|
4523
4574
|
export function useDataGridContext_unstable(selector) {
|
|
4524
4575
|
return useDataGridContextSelector(context => selector(context ?? defaultDataGridContextValue));
|
|
4525
4576
|
}
|
|
4526
|
-
function ComposedDataGrid({ items = [], dataSource, onDataLoadError, onDataSourceSelectionChange, onDataSourceGroupToggle, onRenderedRange, rowHeight: requestedRowHeight = 40, overscan = 4, virtualize, loadingLabel: loadingLabelProp, expandGroupLabel: expandGroupLabelProp, collapseGroupLabel: collapseGroupLabelProp, groupCountLabel: groupCountLabelProp, columns, getRowId, selectionMode = "none", selectionAppearance = "brand", subtleSelection = false, focusMode = "cell", selectedItems, defaultSelectedItems = new Set(), selectionModel, defaultSelectionModel, onSelectionChange, sortState, defaultSortState, onSortChange, onCellEdit, validateCellEdit, rowLabel: rowLabelProp, editHint: editHintProp, label: labelProp, resizableColumns = false, columnWidths, defaultColumnWidths = EMPTY_DATA_GRID_COLUMN_WIDTHS, columnSizingOptions = EMPTY_DATA_GRID_COLUMN_SIZING_OPTIONS, resizableColumnsOptions = DEFAULT_DATA_GRID_RESIZABLE_COLUMNS_OPTIONS, containerWidthOffset = 0, onColumnResize, resizeLabel: resizeLabelProp, reorderableColumns = false, columnOrder, defaultColumnOrder, onColumnOrderChange, reorderLabel: reorderLabelProp, children, onKeyDown: onGridKeyDown, ...props }) {
|
|
4577
|
+
function ComposedDataGrid({ items = [], dataSource, onDataLoadError, onDataSourceSelectionChange, onDataSourceGroupToggle, onRenderedRange, rowHeight: requestedRowHeight = 40, overscan = 4, virtualize, loadingLabel: loadingLabelProp, expandGroupLabel: expandGroupLabelProp, collapseGroupLabel: collapseGroupLabelProp, groupCountLabel: groupCountLabelProp, columns, getRowId, selectionMode = "none", selectionAppearance = "brand", subtleSelection = false, focusMode = "cell", selectedItems, defaultSelectedItems = new Set(), selectionModel, defaultSelectionModel, onSelectionChange, sortState, defaultSortState, onSortChange, onCellEdit, onCellEditError, validateCellEdit, rowLabel: rowLabelProp, editHint: editHintProp, label: labelProp, resizableColumns = false, columnWidths, defaultColumnWidths = EMPTY_DATA_GRID_COLUMN_WIDTHS, columnSizingOptions = EMPTY_DATA_GRID_COLUMN_SIZING_OPTIONS, resizableColumnsOptions = DEFAULT_DATA_GRID_RESIZABLE_COLUMNS_OPTIONS, containerWidthOffset = 0, onColumnResize, resizeLabel: resizeLabelProp, reorderableColumns = false, columnOrder, defaultColumnOrder, onColumnOrderChange, reorderLabel: reorderLabelProp, children, onKeyDown: onGridKeyDown, ...props }) {
|
|
4527
4578
|
const compositionStrings = React.useContext(UIContext).strings;
|
|
4528
4579
|
const label = labelProp ?? (typeof props["aria-label"] === "string" ? props["aria-label"] : compositionStrings.dataGridLabel ?? defaultStrings.dataGridLabel);
|
|
4529
4580
|
const loadingLabel = loadingLabelProp ?? compositionStrings.dataGridLoadingLabel ?? defaultStrings.dataGridLoadingLabel;
|
|
@@ -4878,7 +4929,7 @@ function ComposedDataGrid({ items = [], dataSource, onDataLoadError, onDataSourc
|
|
|
4878
4929
|
},
|
|
4879
4930
|
};
|
|
4880
4931
|
}, [orderedColumns, columnSizingOptions, activeWidths, resizeColumn, resizableColumns, resizeLabel, keyboardSizingColumns]);
|
|
4881
|
-
const context = React.useMemo(() => ({ items: contextItems, dataSource, totalRows, firstRow, lastRow, rowHeight: safeRowHeight, sourceBusy, sourceError, expandGroupLabel, collapseGroupLabel, groupCountLabel, toggleGroup, columns: contextColumns, getRowId, selectionMode, selectionAppearance, subtleSelection, focusMode, selectedItems: selected, selectionModel: activeSelectionModel, setSelectionModel, isItemSelected, isRowSelected, setSelectedItems, sortState: activeSort, setSortState: setSort, activeCell, setActiveCell, columnWidths: activeWidths, resizeColumn, columnSizingOptions, resizableColumns, autoFitColumns, resizeLabel, orderedColumns, reorderColumn: moveColumn, reorderableColumns, reorderLabel, draggedColumn, editHint, rowLabel, editedCells, onCellEdit, validateCellEdit, setEditedCell, getRows: fluentRows, selection: fluentSelection, sort: fluentSort, tableRef: gridRoot, columnSizing_unstable: fluentSizing, selectableRows: selectionMode !== "none", compositeRowTabsterAttribute: tableRowNavigationAttribute }), [contextItems, contextColumns, dataSource, totalRows, firstRow, lastRow, safeRowHeight, sourceBusy, sourceError, expandGroupLabel, collapseGroupLabel, groupCountLabel, onDataSourceGroupToggle, columns, getRowId, selectionMode, selectionAppearance, subtleSelection, focusMode, selected, selectionModel, activeSelectionModel, setSelectionModel, isItemSelected, isRowSelected, setSelectedItems, onSelectionChange, onDataSourceSelectionChange, activeSort, sortState, onSortChange, activeCell, activeWidths, columnWidths, columnSizingOptions, onColumnResize, resizableColumns, autoFitColumns, resizeLabel, orderedColumns, columnOrder, onColumnOrderChange, reorderableColumns, reorderLabel, editHint, rowLabel, editedCells, onCellEdit, validateCellEdit, fluentRows, fluentSelection, fluentSort, fluentSizing]);
|
|
4932
|
+
const context = React.useMemo(() => ({ items: contextItems, dataSource, totalRows, firstRow, lastRow, rowHeight: safeRowHeight, sourceBusy, sourceError, expandGroupLabel, collapseGroupLabel, groupCountLabel, toggleGroup, columns: contextColumns, getRowId, selectionMode, selectionAppearance, subtleSelection, focusMode, selectedItems: selected, selectionModel: activeSelectionModel, setSelectionModel, isItemSelected, isRowSelected, setSelectedItems, sortState: activeSort, setSortState: setSort, activeCell, setActiveCell, columnWidths: activeWidths, resizeColumn, columnSizingOptions, resizableColumns, autoFitColumns, resizeLabel, orderedColumns, reorderColumn: moveColumn, reorderableColumns, reorderLabel, draggedColumn, editHint, rowLabel, editedCells, onCellEdit, onCellEditError, validateCellEdit, setEditedCell, getRows: fluentRows, selection: fluentSelection, sort: fluentSort, tableRef: gridRoot, columnSizing_unstable: fluentSizing, selectableRows: selectionMode !== "none", compositeRowTabsterAttribute: tableRowNavigationAttribute }), [contextItems, contextColumns, dataSource, totalRows, firstRow, lastRow, safeRowHeight, sourceBusy, sourceError, expandGroupLabel, collapseGroupLabel, groupCountLabel, onDataSourceGroupToggle, columns, getRowId, selectionMode, selectionAppearance, subtleSelection, focusMode, selected, selectionModel, activeSelectionModel, setSelectionModel, isItemSelected, isRowSelected, setSelectedItems, onSelectionChange, onDataSourceSelectionChange, activeSort, sortState, onSortChange, activeCell, activeWidths, columnWidths, columnSizingOptions, onColumnResize, resizableColumns, autoFitColumns, resizeLabel, orderedColumns, columnOrder, onColumnOrderChange, reorderableColumns, reorderLabel, editHint, rowLabel, editedCells, onCellEdit, onCellEditError, validateCellEdit, fluentRows, fluentSelection, fluentSort, fluentSizing]);
|
|
4882
4933
|
const focusBy = (event) => {
|
|
4883
4934
|
if (event.ctrlKey && (event.key === "Home" || event.key === "End")) {
|
|
4884
4935
|
event.preventDefault();
|
|
@@ -4950,7 +5001,7 @@ function ComposedDataGrid({ items = [], dataSource, onDataLoadError, onDataSourc
|
|
|
4950
5001
|
const rtl = getComputedStyle(event.currentTarget).direction === "rtl";
|
|
4951
5002
|
moveColumn(from, to, rtl ? event.clientX < rect.left + rect.width / 2 : event.clientX > rect.left + rect.width / 2);
|
|
4952
5003
|
draggedColumn.current = undefined;
|
|
4953
|
-
} props.onDrop?.(event); }, "data-selection-appearance": selectionAppearance, "data-spui-composed-grid": "", style: { boxSizing: "border-box", width: "100%", overflow: "auto", border: "1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1))", borderRadius: "var(--spui-control-radius,6px)", background: "var(--spui-base-surface,var(--spui-ui-surface,#fff))", color: "var(--spui-ui-text,var(--spui-semantic-body-text,#242424))", fontFamily: "var(--spui-font-family,inherit)", "--spui-composed-grid-columns": tracks, ...props.style } }), children: children }), sourceBusy && _jsx("div", { role: "status", "aria-live": "polite", className: "spui-sr-only", children: loadingLabel }), sourceError && _jsx("div", { role: "alert", children:
|
|
5004
|
+
} props.onDrop?.(event); }, "data-selection-appearance": selectionAppearance, "data-spui-composed-grid": "", style: { boxSizing: "border-box", width: "100%", overflow: "auto", border: "1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1))", borderRadius: "var(--spui-control-radius,6px)", background: "var(--spui-base-surface,var(--spui-ui-surface,#fff))", color: "var(--spui-ui-text,var(--spui-semantic-body-text,#242424))", fontFamily: "var(--spui-font-family,inherit)", "--spui-composed-grid-columns": tracks, ...props.style } }), children: children }), sourceBusy && _jsx("div", { role: "status", "aria-live": "polite", className: "spui-sr-only", children: loadingLabel }), sourceError && _jsx("div", { role: "alert", children: compositionStrings.dataGridLoadError ?? defaultStrings.dataGridLoadError }), _jsx("div", { className: "spui-grid-reorder-status", role: "status", "aria-live": "polite", style: { position: "absolute", width: 1, height: 1, overflow: "hidden", clipPath: "inset(50%)" }, children: reorderAnnouncement })] }) });
|
|
4954
5005
|
}
|
|
4955
5006
|
export function DataGrid(props) {
|
|
4956
5007
|
if ("children" in props && props.children !== undefined)
|
|
@@ -5077,6 +5128,7 @@ export function DataGridCell({ children, columnId, rowIndex = 1, columnIndex = 0
|
|
|
5077
5128
|
return _jsx(ComposedDataGridCell, { ...props, item: item, context: context, cellKey: cellKey, rowIndex: rowIndex, columnIndex: effectiveColumnIndex, columnId: id, focusMode: focusMode, editable: editable, value: value, editType: editType, editLabel: editLabel, children: children });
|
|
5078
5129
|
}
|
|
5079
5130
|
function ComposedDataGridCell({ children, item, context, cellKey, rowIndex = 1, columnIndex, columnId, focusMode, editable, value, editType, editLabel, ...props }) {
|
|
5131
|
+
const uiStrings = React.useContext(UIContext).strings;
|
|
5080
5132
|
const [editing, setEditing] = React.useState(false);
|
|
5081
5133
|
const [draft, setDraft] = React.useState("");
|
|
5082
5134
|
const [error, setError] = React.useState("");
|
|
@@ -5131,8 +5183,9 @@ function ComposedDataGridCell({ children, item, context, cellKey, rowIndex = 1,
|
|
|
5131
5183
|
}
|
|
5132
5184
|
catch (reason) {
|
|
5133
5185
|
const message = reason instanceof Error ? reason.message : String(reason || "The value could not be saved.");
|
|
5134
|
-
setError(
|
|
5135
|
-
|
|
5186
|
+
setError(uiStrings.dataGridEditError ?? defaultStrings.dataGridEditError);
|
|
5187
|
+
context.onCellEditError?.({ item: edit.item, rowId: edit.rowId, columnId: edit.columnId, previousValue: edit.previousValue, value: edit.value, error: message });
|
|
5188
|
+
cell.current?.dispatchEvent(new CustomEvent("spui-cell-edit-error", { bubbles: true, composed: true, detail: { item: edit.item, rowId: edit.rowId, columnId: edit.columnId, previousValue: edit.previousValue, value: edit.value, error: message } }));
|
|
5136
5189
|
requestAnimationFrame(() => input.current?.focus());
|
|
5137
5190
|
}
|
|
5138
5191
|
finally {
|
|
@@ -5171,10 +5224,11 @@ function ComposedDataGridCell({ children, item, context, cellKey, rowIndex = 1,
|
|
|
5171
5224
|
}
|
|
5172
5225
|
else if (event.key.startsWith("Arrow"))
|
|
5173
5226
|
event.stopPropagation(); }, onBlur: () => { if (!savingRef.current && !cancelledRef.current)
|
|
5174
|
-
void commit(); }, style: { width: "100%", minWidth: 0, boxSizing: "border-box", font: "inherit", color: "inherit", background: "var(--spui-base-surface,var(--spui-ui-surface,#fff))", border: "
|
|
5227
|
+
void commit(); }, style: { width: "100%", minWidth: 0, boxSizing: "border-box", font: "inherit", color: "inherit", background: "var(--spui-base-surface,var(--spui-ui-surface,#fff))", border: error ? "2px solid var(--spui-semantic-danger,var(--spui-ui-danger,#d13438))" : "2px solid var(--spui-ui-accent,var(--spui-semantic-primary-button-background,#0078d4))", outline: "none", borderRadius: "var(--spui-control-radius,4px)", padding: "4px 6px" } }), error && _jsx("span", { id: `${cellKey}-error`, role: "alert", className: "spui-sr-only", children: error })] }) : rendered });
|
|
5175
5228
|
}
|
|
5176
5229
|
export function DataGridHeaderCell({ children, columnId, rowIndex = 0, columnIndex = 0, sortable = true, sortDirection: explicitSortDirection, focusMode = "cell", aside, sortIcon, button, ...props }) {
|
|
5177
5230
|
const context = useDataGridComposition();
|
|
5231
|
+
const uiStrings = React.useContext(UIContext).strings;
|
|
5178
5232
|
const contextualColumnId = React.useContext(DataGridColumnIdContext);
|
|
5179
5233
|
const grid = useDataGridComposition();
|
|
5180
5234
|
const id = contextualColumnId ?? columnId;
|
|
@@ -5239,7 +5293,7 @@ export function DataGridHeaderCell({ children, columnId, rowIndex = 0, columnInd
|
|
|
5239
5293
|
event.stopPropagation();
|
|
5240
5294
|
grid.reorderColumn(String(id), ids[nextIndex], nextIndex > index);
|
|
5241
5295
|
};
|
|
5242
|
-
return _jsxs("div", { ...props, role: "columnheader", "aria-sort": sortDirection, "data-column-id": id == null ? undefined : String(id), style: { boxSizing: "border-box", position: "relative", display: "flex", gridColumn: effectiveColumnIndex + 1, width: "100%", minWidth: 0, borderBlockEnd: "1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1))", fontWeight: 600, ...props.style }, children: [grid?.reorderableColumns && id !== undefined && _jsx("button", { type: "button", draggable: true, "aria-label": `${grid.reorderLabel ?? "Reorder column"} ${headerLabel}`, title:
|
|
5296
|
+
return _jsxs("div", { ...props, role: "columnheader", "aria-sort": sortDirection, "data-column-id": id == null ? undefined : String(id), style: { boxSizing: "border-box", position: "relative", display: "flex", gridColumn: effectiveColumnIndex + 1, width: "100%", minWidth: 0, borderBlockEnd: "1px solid var(--spui-ui-stroke,var(--spui-semantic-body-divider,#d1d1d1))", fontWeight: 600, ...props.style }, children: [grid?.reorderableColumns && id !== undefined && _jsx("button", { type: "button", draggable: true, "aria-label": `${grid.reorderLabel ?? "Reorder column"} ${headerLabel}`, title: (uiStrings.dataGridReorderHint ?? defaultStrings.dataGridReorderHint).replace("{column}", headerLabel), "data-reorder-column": String(id), "data-testid": `data-grid-reorder-${String(id)}`, onKeyDown: reorderKey, onDragStart: event => { event.dataTransfer.effectAllowed = "move"; event.dataTransfer.setData("text/plain", String(id)); }, style: { flex: "none", width: 26, minHeight: 40, padding: 0, border: 0, background: "transparent", color: "var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161))", cursor: "grab" }, children: "\u283F" }), headerControl, renderSpanSlot(aside), grid?.resizableColumns && id !== undefined && _jsx("div", { ref: handleRef, role: "separator", "aria-orientation": "vertical", "aria-label": `${grid.resizeLabel} ${headerLabel}`, "aria-valuemin": getDataGridColumnSizing({ id: String(id), label: String(id) }, grid.columnSizingOptions).minWidth, "aria-valuemax": 1600, "aria-valuenow": width, tabIndex: 0, "data-testid": `data-grid-resize-${String(id)}`, onKeyDown: resizeKey, onDoubleClick: fit, onPointerDown: event => { if (event.button !== 0)
|
|
5243
5297
|
return; resizeStart.current = { x: event.clientX, width: width ?? getDataGridColumnSizing({ id: String(id), label: String(id) }, grid.columnSizingOptions).defaultWidth }; event.currentTarget.setPointerCapture(event.pointerId); event.preventDefault(); }, onPointerMove: event => { if (!resizeStart.current)
|
|
5244
5298
|
return; const direction = getComputedStyle(event.currentTarget).direction === "rtl" ? -1 : 1; grid.resizeColumn(String(id), resizeStart.current.width + (event.clientX - resizeStart.current.x) * direction, event.nativeEvent); }, onPointerUp: event => { resizeStart.current = null; if (event.currentTarget.hasPointerCapture(event.pointerId))
|
|
5245
5299
|
event.currentTarget.releasePointerCapture(event.pointerId); }, style: { position: "absolute", zIndex: 1, insetBlock: 0, insetInlineEnd: 0, width: 10, cursor: "col-resize", touchAction: "none", outline: "none" } })] });
|
|
@@ -5399,7 +5453,7 @@ export function Tree({ items, children, label, selectionMode = "none", selectedK
|
|
|
5399
5453
|
const allEntries = React.useMemo(() => flattenAllTree(treeItems), [treeItems]);
|
|
5400
5454
|
const currentActiveKey = visible.some(entry => entry.key === activeKey) ? activeKey : visible[0]?.key ?? "";
|
|
5401
5455
|
const lang = String(props.lang ?? context.lang ?? (typeof document === "undefined" ? "" : document.documentElement.lang)).toLowerCase();
|
|
5402
|
-
const languageIsRtl =
|
|
5456
|
+
const languageIsRtl = getDirectionFromLanguage(lang) === "rtl";
|
|
5403
5457
|
const direction = props.dir ?? context.dir;
|
|
5404
5458
|
const isRtl = direction === "rtl" || (direction === "auto" && languageIsRtl) || (direction === undefined && (languageIsRtl || (typeof document !== "undefined" && getComputedStyle(document.documentElement).direction === "rtl")));
|
|
5405
5459
|
const updateSelected = (node, event) => {
|
|
@@ -5596,7 +5650,7 @@ export const TextField = /* @__PURE__ */ React.forwardRef(function TextField(inp
|
|
|
5596
5650
|
return React.createElement("spui-field", useCustomElementProps({ ...props, ref, label, value }));
|
|
5597
5651
|
});
|
|
5598
5652
|
/** Pair one form control with a theme-aware label, hint, and validation message. */
|
|
5599
|
-
export function Field({ children, label, hint, validationMessage, validationMessageIcon, validationState, required, disabled, orientation = "vertical", size = "medium", className, style, ...props }) {
|
|
5653
|
+
export const Field = /* @__PURE__ */ React.forwardRef(function Field({ children, label, hint, validationMessage, validationMessageIcon, validationState, required, disabled, orientation = "vertical", size = "medium", className, style, ...props }, forwardedRef) {
|
|
5600
5654
|
const generatedId = React.useId();
|
|
5601
5655
|
const initialControl = React.isValidElement(children) && children.type !== React.Fragment ? children : undefined;
|
|
5602
5656
|
const initialControlProps = initialControl?.props ?? {};
|
|
@@ -5678,8 +5732,8 @@ export function Field({ children, label, hint, validationMessage, validationMess
|
|
|
5678
5732
|
hintId,
|
|
5679
5733
|
disabled: Boolean(disabled || controlProps.disabled),
|
|
5680
5734
|
};
|
|
5681
|
-
return _jsxs("div", { ...useHostProps({ ...props, className: ["spui-form-field", className].filter(Boolean).join(" "), style: gridStyle, "data-orientation": orientation, "data-size": size, "data-validation-state": state }), children: [label == null ? null : _jsx(Label, { id: labelId, htmlFor: controlId, size: size, required: requiredValue, disabled: Boolean(disabled || controlProps.disabled), style: { gridArea: orientation === "horizontal" ? "1 / 1 / span 3 / 2" : undefined }, children: label }), _jsx("div", { style: { gridArea: orientation === "horizontal" ? "1 / 2 / span 3 / 3" : undefined, minWidth: 0 }, children: _jsx(FieldContext.Provider, { value: fieldContextValue, children: enhancedControl }) }), hint == null ? null : _jsx("div", { id: hintId, style: { gridArea: orientation === "horizontal" ? "2 / 2" : undefined, color: "var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161))", fontSize: "var(--spui-field-hint-size,12px)" }, children: hint }), !hasValidationMessage ? null : _jsxs("div", { id: messageId, "data-field-validation": state, role: state === "error" || state === "warning" ? "alert" : undefined, style: { gridArea: orientation === "horizontal" ? "3 / 2" : undefined, display: "flex", alignItems: "baseline", gap: 6, color: tokens?.foreground, fontSize: "var(--spui-field-message-size,12px)" }, children: [state === "none" ? null : _jsx("span", { "data-slot": "validationMessageIcon", "aria-hidden": "true", children: validationMessageIcon ?? (state === "success" ? "✓" : "!") }), validationMessage] })] });
|
|
5682
|
-
}
|
|
5735
|
+
return _jsxs("div", { ...useHostProps({ ...props, ref: forwardedRef, className: ["spui-form-field", className].filter(Boolean).join(" "), style: gridStyle, "data-orientation": orientation, "data-size": size, "data-validation-state": state }), children: [label == null ? null : _jsx(Label, { id: labelId, htmlFor: controlId, size: size, required: requiredValue, disabled: Boolean(disabled || controlProps.disabled), style: { gridArea: orientation === "horizontal" ? "1 / 1 / span 3 / 2" : undefined }, children: label }), _jsx("div", { style: { gridArea: orientation === "horizontal" ? "1 / 2 / span 3 / 3" : undefined, minWidth: 0 }, children: _jsx(FieldContext.Provider, { value: fieldContextValue, children: enhancedControl }) }), hint == null ? null : _jsx("div", { id: hintId, style: { gridArea: orientation === "horizontal" ? "2 / 2" : undefined, color: "var(--spui-ui-muted,var(--spui-semantic-body-subtext,#616161))", fontSize: "var(--spui-field-hint-size,12px)" }, children: hint }), !hasValidationMessage ? null : _jsxs("div", { id: messageId, "data-field-validation": state, role: state === "error" || state === "warning" ? "alert" : undefined, style: { gridArea: orientation === "horizontal" ? "3 / 2" : undefined, display: "flex", alignItems: "baseline", gap: 6, color: tokens?.foreground, fontSize: "var(--spui-field-message-size,12px)" }, children: [state === "none" ? null : _jsx("span", { "data-slot": "validationMessageIcon", "aria-hidden": "true", children: validationMessageIcon ?? (state === "success" ? "✓" : "!") }), validationMessage] })] });
|
|
5736
|
+
});
|
|
5683
5737
|
/** Bare input primitive. Supply aria-label or aria-labelledby; use TextField when a shadow-safe visible label is needed. */
|
|
5684
5738
|
export const Input = /* @__PURE__ */ React.forwardRef(function Input(inputProps, forwardedRef) {
|
|
5685
5739
|
const { type = "text", value, defaultValue, checked, defaultChecked, input: inputControl, onValueChange, onChange, contentBefore, contentAfter, size = "medium", appearance = "outline", disabled, required, readOnly, placeholder, capture, formNoValidate, ...props } = useFieldControlProps_unstable(inputProps, { supportsRequired: true, supportsSize: true });
|
|
@@ -5889,6 +5943,95 @@ export const AlphaSlider = /* @__PURE__ */ React.forwardRef(function AlphaSlider
|
|
|
5889
5943
|
element.defaultColor = defaultColor; }, [color, defaultColor]);
|
|
5890
5944
|
return React.createElement("spui-alpha-slider", nativeControlHostProps({ ...props, ref, color: undefined, defaultColor: undefined, shape, transparency: transparency || undefined, vertical: vertical || undefined, slot: "alpha", "aria-label": props["aria-label"] || context.strings.colorOpacity }));
|
|
5891
5945
|
});
|
|
5946
|
+
/** Load and persist a user's compact command-shelf choice in this browser. Use a site/app-scoped key. */
|
|
5947
|
+
export function useStoredOverflowCompactMode(storageKey, defaultCompact = false) {
|
|
5948
|
+
const key = `spfx-fast:overflow-compact:${storageKey}`;
|
|
5949
|
+
const [compact, setCompactState] = React.useState(defaultCompact);
|
|
5950
|
+
const [ready, setReady] = React.useState(false);
|
|
5951
|
+
React.useEffect(() => {
|
|
5952
|
+
const read = (value) => {
|
|
5953
|
+
if (value === "true" || value === "false")
|
|
5954
|
+
setCompactState(value === "true");
|
|
5955
|
+
else
|
|
5956
|
+
setCompactState(defaultCompact);
|
|
5957
|
+
};
|
|
5958
|
+
try {
|
|
5959
|
+
read(globalThis.localStorage?.getItem(key) ?? null);
|
|
5960
|
+
}
|
|
5961
|
+
catch {
|
|
5962
|
+
setCompactState(defaultCompact);
|
|
5963
|
+
}
|
|
5964
|
+
setReady(true);
|
|
5965
|
+
const onStorage = (event) => { if (event.key === key)
|
|
5966
|
+
read(event.newValue); };
|
|
5967
|
+
globalThis.addEventListener?.("storage", onStorage);
|
|
5968
|
+
return () => globalThis.removeEventListener?.("storage", onStorage);
|
|
5969
|
+
}, [key, defaultCompact]);
|
|
5970
|
+
const setCompact = React.useCallback((value) => {
|
|
5971
|
+
setCompactState(value);
|
|
5972
|
+
try {
|
|
5973
|
+
globalThis.localStorage?.setItem(key, String(value));
|
|
5974
|
+
}
|
|
5975
|
+
catch { /* Keep the current-session choice if storage is unavailable. */ }
|
|
5976
|
+
}, [key]);
|
|
5977
|
+
const toggleCompact = React.useCallback(() => setCompact(!compact), [compact, setCompact]);
|
|
5978
|
+
return { compact, ready, setCompact, toggleCompact };
|
|
5979
|
+
}
|
|
5980
|
+
export function useSavedSwatchPalettes(store) {
|
|
5981
|
+
const [palettes, setPalettes] = React.useState([]);
|
|
5982
|
+
const [loading, setLoading] = React.useState(true);
|
|
5983
|
+
const [error, setError] = React.useState(null);
|
|
5984
|
+
const request = React.useRef(0);
|
|
5985
|
+
const mounted = React.useRef(false);
|
|
5986
|
+
const reload = React.useCallback(async () => {
|
|
5987
|
+
const current = ++request.current;
|
|
5988
|
+
setLoading(true);
|
|
5989
|
+
setError(null);
|
|
5990
|
+
try {
|
|
5991
|
+
const result = await store.list();
|
|
5992
|
+
if (mounted.current && request.current === current)
|
|
5993
|
+
setPalettes(result);
|
|
5994
|
+
return result;
|
|
5995
|
+
}
|
|
5996
|
+
catch (cause) {
|
|
5997
|
+
if (mounted.current && request.current === current)
|
|
5998
|
+
setError(cause);
|
|
5999
|
+
throw cause;
|
|
6000
|
+
}
|
|
6001
|
+
finally {
|
|
6002
|
+
if (mounted.current && request.current === current)
|
|
6003
|
+
setLoading(false);
|
|
6004
|
+
}
|
|
6005
|
+
}, [store]);
|
|
6006
|
+
React.useEffect(() => { mounted.current = true; void reload().catch(() => { }); return () => { mounted.current = false; request.current++; }; }, [reload]);
|
|
6007
|
+
const save = React.useCallback(async (palette) => {
|
|
6008
|
+
if (mounted.current)
|
|
6009
|
+
setError(null);
|
|
6010
|
+
try {
|
|
6011
|
+
await store.save(palette);
|
|
6012
|
+
await reload();
|
|
6013
|
+
}
|
|
6014
|
+
catch (cause) {
|
|
6015
|
+
if (mounted.current)
|
|
6016
|
+
setError(cause);
|
|
6017
|
+
throw cause;
|
|
6018
|
+
}
|
|
6019
|
+
}, [store, reload]);
|
|
6020
|
+
const remove = React.useCallback(async (id) => {
|
|
6021
|
+
if (mounted.current)
|
|
6022
|
+
setError(null);
|
|
6023
|
+
try {
|
|
6024
|
+
await store.remove(id);
|
|
6025
|
+
await reload();
|
|
6026
|
+
}
|
|
6027
|
+
catch (cause) {
|
|
6028
|
+
if (mounted.current)
|
|
6029
|
+
setError(cause);
|
|
6030
|
+
throw cause;
|
|
6031
|
+
}
|
|
6032
|
+
}, [store, reload]);
|
|
6033
|
+
return { palettes, loading, error, reload, save, remove };
|
|
6034
|
+
}
|
|
5892
6035
|
export const SwatchPicker = /* @__PURE__ */ React.forwardRef(function SwatchPicker({ children, selectedValue, defaultSelectedValue, selectedValues, defaultSelectedValues, selectionMode = "single", layout = "grid", size = "medium", shape = "square", spacing = "medium", focusMode = "arrow", columns = 6, onSelectionChange, ...props }, forwardedRef) {
|
|
5893
6036
|
const strings = React.useContext(UIContext).strings;
|
|
5894
6037
|
const ref = React.useRef(null);
|
|
@@ -5907,6 +6050,12 @@ export const ColorSwatch = /* @__PURE__ */ React.forwardRef(function ColorSwatch
|
|
|
5907
6050
|
ensureDefined(defineNativeSwatchPicker);
|
|
5908
6051
|
return React.createElement("spui-color-swatch", useCustomElementProps({ ref: forwardedRef, ...props, color, value, disabled: disabled || undefined, size, shape, "border-color": borderColor }), children, icon == null ? null : React.createElement("span", { slot: "icon" }, icon), disabledIcon == null ? null : React.createElement("span", { slot: "disabled-icon" }, disabledIcon));
|
|
5909
6052
|
});
|
|
6053
|
+
export function SharePointThemeSwatches({ palette, labelForColor }) {
|
|
6054
|
+
const themePalette = React.useContext(UIContext).theme?.palette;
|
|
6055
|
+
const presets = getSharePointThemeColorPresets(palette ?? themePalette, labelForColor);
|
|
6056
|
+
ensureDefined(defineNativeSwatchPicker);
|
|
6057
|
+
return React.createElement(React.Fragment, null, presets.map(preset => React.createElement(ColorSwatch, { key: preset.name, color: preset.color, value: preset.value, "aria-label": preset.label })));
|
|
6058
|
+
}
|
|
5910
6059
|
export const ImageSwatch = /* @__PURE__ */ React.forwardRef(function ImageSwatch({ src, value, disabled, size, shape, children, ...props }, forwardedRef) {
|
|
5911
6060
|
ensureDefined(defineNativeSwatchPicker);
|
|
5912
6061
|
return React.createElement("spui-image-swatch", useCustomElementProps({ ref: forwardedRef, ...props, src, value, disabled: disabled || undefined, size, shape }), children);
|
|
@@ -6835,3 +6984,114 @@ export const AccordionPanel = /* @__PURE__ */ React.forwardRef(function Accordio
|
|
|
6835
6984
|
const open = React.useContext(AccordionItemOpenContext);
|
|
6836
6985
|
return React.createElement("spui-accordion-panel", useCustomElementProps({ ref: forwardedRef, ...props, slot: "panel", motion: collapseMotion ? true : undefined }), collapseMotion ? React.createElement(collapseMotion, { visible: open, appear: true, unmountOnExit: true }, children) : children);
|
|
6837
6986
|
});
|
|
6987
|
+
/** Render a SharePoint field recipe using the library's matching form control. */
|
|
6988
|
+
export function SharePointField({ field, value, defaultValue, options: providedOptions, onValueChange, disabled = false, hint, validationMessage, renderUnsupported, addChoiceLabel = "Add another choice", emptyOptionLabel = "Select an option", className, style, ...hostProps }) {
|
|
6989
|
+
const adapter = getSharePointFieldAdapter(field);
|
|
6990
|
+
const [internalValue, setInternalValue] = React.useState(defaultValue);
|
|
6991
|
+
const [fillInValue, setFillInValue] = React.useState("");
|
|
6992
|
+
if (adapter.hidden)
|
|
6993
|
+
return null;
|
|
6994
|
+
const currentValue = value === undefined ? internalValue : value;
|
|
6995
|
+
const updateValue = (next) => {
|
|
6996
|
+
if (value === undefined)
|
|
6997
|
+
setInternalValue(next);
|
|
6998
|
+
onValueChange?.(next);
|
|
6999
|
+
};
|
|
7000
|
+
const label = adapter.label || adapter.name || adapter.fieldType;
|
|
7001
|
+
const name = adapter.name || undefined;
|
|
7002
|
+
const stringValue = adapter.control === "date-picker" ? toSharePointDateControlString(currentValue) : toSharePointControlString(currentValue);
|
|
7003
|
+
const choices = providedOptions ?? (adapter.choices ?? []).map(choice => ({ value: choice, label: choice }));
|
|
7004
|
+
const controlDisabled = disabled || (adapter.readOnly && !["input", "textarea", "rich-text-editor"].includes(adapter.control));
|
|
7005
|
+
let control;
|
|
7006
|
+
switch (adapter.control) {
|
|
7007
|
+
case "input":
|
|
7008
|
+
control = _jsx(Input, { type: adapter.inputType ?? "text", name: name, value: stringValue, min: adapter.min, max: adapter.max, step: adapter.step, maxLength: adapter.maxLength, required: adapter.required, disabled: disabled, readOnly: adapter.readOnly, onValueChange: next => updateValue(next) });
|
|
7009
|
+
break;
|
|
7010
|
+
case "textarea":
|
|
7011
|
+
control = _jsx(TextArea, { name: name, value: stringValue, maxLength: adapter.maxLength, required: adapter.required, disabled: disabled, readOnly: adapter.readOnly, onValueChange: next => updateValue(next) });
|
|
7012
|
+
break;
|
|
7013
|
+
case "rich-text-editor":
|
|
7014
|
+
control = _jsx(RichTextEditor, { name: name, value: stringValue, field: field, required: adapter.required, disabled: disabled, readOnly: adapter.readOnly, onValueChange: next => updateValue(next) });
|
|
7015
|
+
break;
|
|
7016
|
+
case "select":
|
|
7017
|
+
control = adapter.allowFillIn
|
|
7018
|
+
? _jsx(ComboBox, { name: name, value: stringValue, selectedValue: stringValue, placeholder: emptyOptionLabel, freeform: true, allowFreeform: true, required: adapter.required, disabled: controlDisabled, onValueChange: next => updateValue(next), onOptionSelect: (_, data) => updateValue(data.optionValue ?? null), children: choices.map(option => _jsx(Option, { value: String(option.value), text: option.label, disabled: option.disabled, children: option.label }, String(option.value))) })
|
|
7019
|
+
: _jsxs(Select, { name: name, value: stringValue, required: adapter.required, disabled: controlDisabled, onValueChange: next => updateValue(next), children: [_jsx("option", { value: "", disabled: adapter.required, children: emptyOptionLabel }), choices.map(option => _jsx("option", { value: String(option.value), disabled: option.disabled, children: option.label }, String(option.value)))] });
|
|
7020
|
+
break;
|
|
7021
|
+
case "radio-group":
|
|
7022
|
+
control = _jsx(RadioGroup, { name: name, value: stringValue, required: adapter.required, disabled: controlDisabled, onValueChange: next => updateValue(next), children: choices.map(option => _jsx(Radio, { value: String(option.value), label: option.label, disabled: option.disabled }, String(option.value))) });
|
|
7023
|
+
break;
|
|
7024
|
+
case "checkbox":
|
|
7025
|
+
control = _jsx(Checkbox, { name: name, checked: currentValue === true || currentValue === "true", disabled: controlDisabled, onCheckedChange: next => updateValue(next) });
|
|
7026
|
+
break;
|
|
7027
|
+
case "multi-choice": {
|
|
7028
|
+
const selected = Array.isArray(currentValue) ? currentValue.map(String) : [];
|
|
7029
|
+
const visibleOptions = [...choices];
|
|
7030
|
+
for (const selectedValue of selected) {
|
|
7031
|
+
if (!visibleOptions.some(option => String(option.value) === selectedValue))
|
|
7032
|
+
visibleOptions.push({ value: selectedValue, label: selectedValue });
|
|
7033
|
+
}
|
|
7034
|
+
const setSelected = (choice, checked) => {
|
|
7035
|
+
const next = checked ? [...new Set([...selected, choice])] : selected.filter(item => item !== choice);
|
|
7036
|
+
updateValue(next);
|
|
7037
|
+
};
|
|
7038
|
+
const addFillIn = () => {
|
|
7039
|
+
const next = fillInValue.trim();
|
|
7040
|
+
if (!next || selected.includes(next))
|
|
7041
|
+
return;
|
|
7042
|
+
updateValue([...selected, next]);
|
|
7043
|
+
setFillInValue("");
|
|
7044
|
+
};
|
|
7045
|
+
control = _jsxs(_Fragment, { children: [visibleOptions.map(option => _jsx(Checkbox, { label: option.label, checked: selected.includes(String(option.value)), disabled: controlDisabled || option.disabled, onCheckedChange: checked => setSelected(String(option.value), checked) }, String(option.value))), adapter.allowFillIn ? _jsxs("div", { style: { display: "flex", alignItems: "end", gap: 8, marginBlockStart: 8 }, children: [_jsx(Input, { type: "text", value: fillInValue, "aria-label": addChoiceLabel, disabled: controlDisabled, onValueChange: setFillInValue, onKeyDown: event => { if (event.key === "Enter") {
|
|
7046
|
+
event.preventDefault();
|
|
7047
|
+
addFillIn();
|
|
7048
|
+
} } }), _jsx(Button, { type: "button", appearance: "outline", disabled: controlDisabled || !fillInValue.trim(), onClick: addFillIn, children: addChoiceLabel })] }) : null] });
|
|
7049
|
+
break;
|
|
7050
|
+
}
|
|
7051
|
+
case "date-picker":
|
|
7052
|
+
control = _jsx(DatePicker, { name: name, value: stringValue, required: adapter.required, disabled: controlDisabled, readOnly: adapter.readOnly, onValueChange: next => updateValue(next) });
|
|
7053
|
+
break;
|
|
7054
|
+
case "combobox":
|
|
7055
|
+
control = _jsx(ComboBox, { name: name, multiselect: adapter.multiple, selectedValue: adapter.multiple ? undefined : stringValue, selectedOptions: adapter.multiple && Array.isArray(currentValue) ? currentValue.map(String) : undefined, required: adapter.required, disabled: controlDisabled, placeholder: emptyOptionLabel, onOptionSelect: (_, data) => { if (!adapter.multiple)
|
|
7056
|
+
updateValue(data.optionValue ?? null); }, onSelectedOptionsChange: next => { if (adapter.multiple)
|
|
7057
|
+
updateValue(next); }, children: choices.map(option => _jsx(Option, { value: String(option.value), text: option.label, disabled: option.disabled, children: option.label }, String(option.value))) });
|
|
7058
|
+
break;
|
|
7059
|
+
case "read-only":
|
|
7060
|
+
control = _jsx(TextField, { name: name, value: stringValue, readOnly: true });
|
|
7061
|
+
break;
|
|
7062
|
+
case "unsupported": {
|
|
7063
|
+
const fallback = renderUnsupported?.(field, adapter.unsupportedReason ?? "No renderer is registered for this SharePoint field type.");
|
|
7064
|
+
control = fallback ?? _jsxs("div", { role: "note", children: ["This SharePoint field type needs a custom renderer (", adapter.fieldType, ")."] });
|
|
7065
|
+
break;
|
|
7066
|
+
}
|
|
7067
|
+
}
|
|
7068
|
+
if (adapter.control === "multi-choice") {
|
|
7069
|
+
return _jsx(Field, { ...hostProps, hint: hint ?? adapter.description, validationMessage: validationMessage, disabled: disabled, className: className, style: style, children: _jsx(SharePointMultiChoiceGroup, { label: label, required: adapter.required, disabled: disabled, children: control }) });
|
|
7070
|
+
}
|
|
7071
|
+
return _jsx(Field, { ...hostProps, label: label, hint: hint ?? adapter.description, validationMessage: validationMessage, required: adapter.required, disabled: disabled, className: className, style: style, children: control });
|
|
7072
|
+
}
|
|
7073
|
+
function toSharePointControlString(value) {
|
|
7074
|
+
if (value == null)
|
|
7075
|
+
return "";
|
|
7076
|
+
if (typeof value === "string" || typeof value === "number")
|
|
7077
|
+
return String(value);
|
|
7078
|
+
if (value instanceof Date) {
|
|
7079
|
+
const pad = (part) => String(part).padStart(2, "0");
|
|
7080
|
+
return `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}T${pad(value.getHours())}:${pad(value.getMinutes())}`;
|
|
7081
|
+
}
|
|
7082
|
+
if (typeof value === "object" && "url" in value)
|
|
7083
|
+
return value.url;
|
|
7084
|
+
return "";
|
|
7085
|
+
}
|
|
7086
|
+
function SharePointMultiChoiceGroup({ label, required, disabled, children }) {
|
|
7087
|
+
const fieldProps = useFieldControlProps_unstable({ role: "group", "aria-label": label }, { supportsRequired: false });
|
|
7088
|
+
return _jsxs("fieldset", { ...fieldProps, "aria-required": required || undefined, disabled: disabled, style: { minWidth: 0, margin: 0, padding: 0, border: 0 }, children: [_jsxs("legend", { children: [label, required ? _jsx("span", { "aria-hidden": "true", children: " *" }) : null] }), children] });
|
|
7089
|
+
}
|
|
7090
|
+
function toSharePointDateControlString(value) {
|
|
7091
|
+
if (value instanceof Date) {
|
|
7092
|
+
const pad = (part) => String(part).padStart(2, "0");
|
|
7093
|
+
return `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}`;
|
|
7094
|
+
}
|
|
7095
|
+
const text = toSharePointControlString(value);
|
|
7096
|
+
return /^\d{4}-\d{2}-\d{2}/.exec(text)?.[0] ?? text;
|
|
7097
|
+
}
|