@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/AGENTS.md
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Use this page as the short route from a SharePoint task to a working component. The library is designed for SPFx 1.24 and React 18, but its custom elements can be used without React.
|
|
4
4
|
|
|
5
|
+
For the predictable cross-component pattern and copy-ready Tooltip/Persona composition, start with [`QUICKSTART.md`](./QUICKSTART.md). Component pages and their linked JSON slices supply the exact component-specific props, slots, and callback signatures.
|
|
6
|
+
|
|
5
7
|
## Pick the smallest entry point
|
|
6
8
|
|
|
7
9
|
- In an SPFx React web part, import the React adapter from `@spfx-fast/sharepoint-ui/react` and import only the components used.
|
|
8
10
|
- In plain HTML or another framework, import a leaf definition such as `@spfx-fast/sharepoint-ui/elements/button`, then call `defineButton()` once. For native form labels, use `createLabel()` from `@spfx-fast/sharepoint-ui/elements/label`; it returns a real `<label>` so `htmlFor`/`for` association works.
|
|
9
11
|
- `defineSharePointUIElements()` registers the full current catalog; use it only when the whole catalog is needed.
|
|
12
|
+
- Set `brandColor` in `SharePointUIProvider` theme data to derive matching accent, focus, selection, surface, hover, and border tokens. Explicit design tokens override the derived values; the theme API also has a framework-free `@spfx-fast/sharepoint-ui/theme` entry point.
|
|
10
13
|
|
|
11
14
|
For temporary feedback, mount one `Toaster` near the app root and dispatch from descendants with `useToastController()`. For a controller outside the Toaster subtree or when an app has multiple toast regions, set `toasterId` on the target Toaster and pass the same ID to `useToastController(toasterId)`. The controller supports both `updateToast(id, update)` and Fluent's `updateToast({ toastId, content, ...options })` form. Use a permanent status surface as well when the information must remain available after the toast expires.
|
|
12
15
|
|
|
@@ -33,7 +36,7 @@ Use `ContextMenu` for commands attached to a surface: right-click its trigger, o
|
|
|
33
36
|
|
|
34
37
|
Use `SearchBox` for a free-form query, not `ComboBox` when users are choosing from suggestions. It supports controlled `value` or initial `defaultValue`, `onValueChange`, Enter submission through `onSearch`, and a localized clear button. The custom element participates in form value/reset and required validation.
|
|
35
38
|
|
|
36
|
-
Use `Nav` for app destinations: `NavItem` and `NavSubItem` preserve native anchor navigation when given `href`; `NavCategoryItem` only expands/collapses its category. Any of these accepts an `Avatar` through `avatar={<Avatar name="Team" image={photoUrl} size={28} />}`; the React adapter marks it decorative so the item text stays the accessible name. Direct custom elements use `slot="avatar"` and should mark the Avatar `decorative`. Keep destination activation and category disclosure separate. `selectedValue`/`openCategories` are controlled; use `defaultSelectedValue`/`defaultOpenCategories` for initial state. `multiple` allows several categories open. Items follow normal Tab and native Enter/Space behavior. At 640px and below Nav becomes a 44px menu button with a theme-derived drawer at the logical start; Escape, outside click, and destination selection dismiss it. Use controlled `open`/`onOpenChange` or `defaultOpen`, and localize `openLabel`/`closeLabel` or provider strings `navigationMenu`/`navigationClose`. Set
|
|
39
|
+
Use `Nav` for app destinations: `NavItem` and `NavSubItem` preserve native anchor navigation when given `href`; `NavCategoryItem` only expands/collapses its category. Any of these accepts an `Avatar` through `avatar={<Avatar name="Team" image={photoUrl} size={28} />}`; the React adapter marks it decorative so the item text stays the accessible name. Direct custom elements use `slot="avatar"` and should mark the Avatar `decorative`. Keep destination activation and category disclosure separate. `selectedValue`/`openCategories` are controlled; use `defaultSelectedValue`/`defaultOpenCategories` for initial state. `multiple` allows several categories open. Items follow normal Tab and native Enter/Space behavior. At 640px and below Nav becomes a 44px menu button with a theme-derived drawer at the logical start; Escape, outside click, and destination selection dismiss it. Use controlled `open`/`onOpenChange` or `defaultOpen`, and localize `openLabel`/`closeLabel` or provider strings `navigationMenu`/`navigationClose`. Set the provider `lang`; it derives LTR/RTL, and an explicit `dir` overrides that choice. The desktop rail defaults to 260px (`--spui-nav-width`).
|
|
37
40
|
|
|
38
41
|
For a Fluent-shaped application shell, compose `NavDrawer` with `NavDrawerHeader`, `NavDrawerBody`, and `NavDrawerFooter`; choose `type="overlay"` or `type="inline"`. Its default `tabbable={false}` follows roving arrow navigation; opt into `tabbable` when each destination should be a Tab stop. Use `selectedCategoryValue`/`defaultSelectedCategoryValue` for the selected category and the Fluent callback names `onNavItemSelect`/`onNavCategoryItemToggle` when sharing code with Fluent. `AppItem` is a destination, `AppItemStatic` is decorative identity text, and `SplitNavItem` keeps its primary destination independent from optional action, menu, and toggle buttons; add matching tooltip slots for accessible labels. Connect `Hamburger.onClick` to the owning controlled `open` state.
|
|
39
42
|
|
|
@@ -146,11 +149,14 @@ For a people stack with named overflow details, compose `AvatarGroupItem` childr
|
|
|
146
149
|
- React refs are supported on 157 catalogued adapters and target the rendered root element (normally the custom-element host; `InfoLabel` targets its `span`; standalone `Option`/`OptionGroup` render a `div` outside a ComboBox). `Input` and `TextArea` refs also expose `focus()` and `select()`. `npm run verify:react-refs` checks every ref-enabled catalog entry in Chromium.
|
|
147
150
|
- Override CSS variables for broad design changes and `::part(...)` for one component detail. Fonts inherit through `--spui-font-family`.
|
|
148
151
|
- In tests, prefer role/name queries and stable user-visible semantics. Add `data-testid` to the component host only when semantics are insufficient; custom elements accept it directly, and React adapters forward it to the host. Avoid selectors based on shadow DOM internals or generated IDs.
|
|
149
|
-
- Set `lang`
|
|
152
|
+
- Set `lang` for content language; `SharePointUIProvider` derives `dir` from it. Set `dir` only when the region's direction should override its language. Supply localized provider strings for every built-in label used by the page.
|
|
150
153
|
- Use the `fluent`, `ios`, `windows`, or `linux` base appearance. The no-host-theme accent fallback is stone (`DEFAULT_ACCENT`, `#78716c`); SharePoint semantic theme colors override it when provided. Accent hover, focus fallback, and glass tint derive from the active accent. `glass` derives surface and spacing from its selected base appearance and theme.
|
|
151
154
|
|
|
152
155
|
## Data and rich text
|
|
153
156
|
|
|
157
|
+
- For metadata-driven React forms, render `<SharePointField field={field} value={values[name]} onValueChange={...} options={lookupOptions[name]} />` from `@spfx-fast/sharepoint-ui/react`. It selects the matching control, applies accessible field labels and constraints, and supports rich-text Notes. The host supplies Lookup/User options from an authorized data source; built-in Choice values come from SharePoint metadata. For custom layouts, use `getSharePointFieldAdapter(field)` and render its recipe explicitly. Use `serializeSharePointFieldValues(fields, valuesByInternalName)` for one PATCH body: omitted values stay untouched, `null` clears optional fields, and invalid or unknown values throw. It validates supplied values only; new-item forms must include every required value. `getSharePointListItemUrl(webUrl, listId, itemId)` constructs the item endpoint; the host still owns authorization, ETag, and REST entity-type metadata. The adapter's `required`, `readOnly`, `step`, `min`, `max`, and `maxLength` metadata should drive the UI. Generic and focused serializers reject read-only or empty required values and enforce configured numeric precision and bounds. URL recipes expose `urlFormat` (`hyperlink` or `picture`) for record views. Use `getSharePointNextPageUrl(webUrl, nextLink)` to safely follow same-origin OData pages. `getSharePointLookupOptionsUrl(field, sourceWebUrl)` builds lookup requests. These helpers validate and shape data but do not send requests or replace SharePoint permissions and server validation; people search remains tenant-authorized app work.
|
|
158
|
+
|
|
159
|
+
- Forward SharePoint adapter `min`, `max`, and `maxLength` to matching controls when present. The serializers enforce those numeric bounds and text limits too; SharePoint remains the final validator.
|
|
154
160
|
- Use `ColorPicker` when users need a theme-aware color choice. Its `value` is `#RRGGBB`, `alpha` is `0`–`1`, and `onValueChange(value, alpha)` receives both values. Pass `colors` for app-specific swatches; tenant accent, success, warning, and danger swatches are included by default. The element submits `#RRGGBB` or `#RRGGBBAA` as a native form value.
|
|
155
161
|
|
|
156
162
|
- Use `Table` for compact composable rows and `DataGrid` for virtualized/editable data. Compose `TableHeader`, `TableBody`, `TableRow`, `TableHeaderCell`, and `TableCell`; use `TableSelectionCell` for selection, `TableCellLayout`/`TableCellActions` for concise record content, `TableResizeHandle` for consumer-controlled width, and `createTableColumn` for reusable column definitions. Sorting and resizing emit requests: keep that state in the host and pass it back through `sortDirection` or `value`.
|
|
@@ -163,10 +169,24 @@ For a people stack with named overflow details, compose `AvatarGroupItem` childr
|
|
|
163
169
|
- For framework-neutral Tree, import `defineTree` from `@spfx-fast/sharepoint-ui/elements/tree`, assign `items`, `expandedKeys`, and `selectedKeys` properties, and listen for `spui-tree-expanded-change` and `spui-tree-selection-change`.
|
|
164
170
|
- Localize React defaults with `SharePointUIProvider` strings: `Tree`/`FlatTree` use `treeLabel`, `treeToggleLabel`, `treeEmptyMessage`; `Toolbar`, `Breadcrumb`, and `MenuBar` use their matching `*Label` strings; `SplitButton`, `Hamburger`, and `SplitNavItem` use `splitButtonMenuLabel`, `navigationToggle`, and `splitNavItemActionLabel`; virtualized lists use `virtualizerLabel`; row selection and resize handles use `dataGridSelectRow` and `tableResizeHandle`. Explicit labels take precedence. Direct custom elements use their `label`/`aria-label` attributes.
|
|
165
171
|
- Use `Tag` inside a labelled `TagGroup` for filters and selected values. A dismissible React Tag calls `onDismiss(value, label)`; update the parent array to remove it. Semantic colors and `brand` appearance derive from the active SharePoint theme. For framework-neutral use, import `defineTag` and `defineTagGroup` from `@spfx-fast/sharepoint-ui/elements/tags` and listen for `spui-dismiss`.
|
|
166
|
-
- Use `TagPicker` when users need to search and select multiple values. Supply unique stable option values, a visible label, and controlled `selectedValues`/`onChange`; disabled options cannot be selected. Its `name` submits repeated values in native forms. For framework-neutral use, import `defineTagPicker` from `@spfx-fast/sharepoint-ui/elements/tag-picker`, assign the `value` array, and listen for `spui-change`.
|
|
172
|
+
- Use `TagPicker` when users need to search and select multiple values. Supply unique stable option values, a visible label, and controlled `selectedValues`/`onChange`; disabled options cannot be selected. Its popup flips and sizes within the viewport and clipping ancestors, including SharePoint sections; set `positioning` for placement, alignment, fallback, offset, or explicit boundary control. Its `name` submits repeated values in native forms. For framework-neutral use, import `defineTagPicker` from `@spfx-fast/sharepoint-ui/elements/tag-picker`, assign the `value` array, and listen for `spui-change`.
|
|
167
173
|
- Use `Rating` for a labelled star score. `value` is controlled; `defaultValue` initializes an uncontrolled rating. Use `step={0.5}` for half stars, set `max` for the scale, and provide `itemLabel` when the radio option labels need custom localization.
|
|
168
174
|
- For framework-neutral `spui-virtual-list`, assign `items`, `renderItem`, and `itemKey` after importing `defineVirtualList`. Set `axis="horizontal"` or its `axis` property, `item-size`/`itemSize` for the estimated width or height, and `measure-items`/`measureItems` to track rendered sizes. `row-height` remains the vertical compatibility alias. Set `--spui-list-width` for a horizontal viewport; direction follows inherited `dir`, including logical RTL scrolling. Use `scrollToIndex(index, "start" | "center" | "end", behavior)` for programmatic navigation.
|
|
169
175
|
- `RichTextEditor` emits allowlist-normalized HTML. Store it in a SharePoint rich-text field and render it back through the editor or another sanitizer-aware view; do not inject saved HTML with raw `innerHTML`. After inserting a table, click a cell to enable row/column insertion and deletion; table removal is available from any selected cell. Editing controls disable for merged cells so row/column changes cannot corrupt their spans. Localize the toolbar through `SharePointUIProvider.strings` (for example, `richTextInsertRowBelow` and `richTextDeleteTable`).
|
|
176
|
+
- Pass a SharePoint multiline field's metadata as React `field={column}` so the editor derives the maximum content mode the field can store. `RichText: false` selects plain text; `RestrictedMode: true` removes enhanced rich actions; `RichTextMode: "Compatible"` selects compatible rich formatting; `"FullHtml"` selects the broad sanitized HTML mode. Explicit `contentMode` may narrow but never exceed that capability ceiling; `allowHyperlink={false}` can further disable links, but cannot override `AllowHyperlink: false`. For framework-neutral custom elements, spread `getRichTextEditorFieldOptions(column)` instead. If no restrictions are available, the editor keeps the broad sanitized HTML mode.
|
|
177
|
+
- Connect the editor's `linkPicker` to the SPFx app's existing page/file picker; this keeps tenant-specific picker dependencies out of the UI package. Return `null` on cancel, otherwise map the selected item's absolute URL and optional label into `RichTextEditorLink`. The editor validates the URL and leaves it for review before Apply.
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { RichTextEditor, type RichTextEditorLink } from "@spfx-fast/sharepoint-ui/react";
|
|
181
|
+
|
|
182
|
+
const linkPicker = async (current: RichTextEditorLink | null) => {
|
|
183
|
+
const selected = await pageFilePicker.open({ initialUrl: current?.href });
|
|
184
|
+
return selected ? { href: selected.url, text: selected.name, title: selected.name } : null;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
<RichTextEditor value={html} onValueChange={setHtml} linkPicker={linkPicker}
|
|
188
|
+
onLinkPickerError={error => console.error("SharePoint link picker failed", error)} />
|
|
189
|
+
```
|
|
170
190
|
- Persist through `SPHttpClient` in the web part. Include loading, saved, and error states, and verify important writes by reading the item back.
|
|
171
191
|
|
|
172
192
|
## Before handing off a web part
|
package/QUICKSTART.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# SharePoint UI quickstart
|
|
2
|
+
|
|
3
|
+
Install `@spfx-fast/sharepoint-ui`. Use the component page’s React export, properties, slots, and callback table as the source of truth.
|
|
4
|
+
|
|
5
|
+
## React in an SPFx web part
|
|
6
|
+
|
|
7
|
+
Wrap the web part view once. Pass the current page culture; the provider applies the locale and text direction. Keep SharePoint reads, writes, and business rules in the web part.
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { Button, SharePointUIProvider, ViewCard } from "@spfx-fast/sharepoint-ui/react";
|
|
11
|
+
|
|
12
|
+
type Request = { id: number; title: string; status: string };
|
|
13
|
+
|
|
14
|
+
export function RequestList({
|
|
15
|
+
requests,
|
|
16
|
+
locale,
|
|
17
|
+
openRequest,
|
|
18
|
+
}: {
|
|
19
|
+
requests: Request[];
|
|
20
|
+
locale: string;
|
|
21
|
+
openRequest: (id: number) => void;
|
|
22
|
+
}) {
|
|
23
|
+
return (
|
|
24
|
+
<SharePointUIProvider lang={locale}>
|
|
25
|
+
{requests.map(request => (
|
|
26
|
+
<ViewCard key={request.id} kind="list-item" title={request.title} description={request.status}>
|
|
27
|
+
<Button slot="actions" onClick={() => openRequest(request.id)}>Open</Button>
|
|
28
|
+
</ViewCard>
|
|
29
|
+
))}
|
|
30
|
+
</SharePointUIProvider>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
In the web part, pass `this.context.pageContext.cultureInfo.currentUICultureName` as `locale`. For a single control, import its React export from `/react`; import only what the view uses.
|
|
36
|
+
|
|
37
|
+
Set `brandColor` on the provider theme to derive a coordinated accent, focus, selection, surface, hover, and border palette. Explicit design tokens override the derived values; see the [theme guide](https://vystartasv.github.io/sharepoint-ui/guides/theming-and-direction/).
|
|
38
|
+
|
|
39
|
+
## The shared component pattern
|
|
40
|
+
|
|
41
|
+
- Every React adapter is a named export from `@spfx-fast/sharepoint-ui/react`. React imports register the element automatically; do not call `defineX()` in React.
|
|
42
|
+
- Put `SharePointUIProvider` once around the view. Theme, font, locale, direction, and provider strings flow to descendants.
|
|
43
|
+
- Compose components with children. Use a named slot or a component-specific prop only when its page documents one; the `Slots` table shows the exact names.
|
|
44
|
+
- When an API has controlled state, pass its state prop and update it in the documented callback. `defaultX` supplies initial state where supported. State names and callback arguments are component-specific; copy them from that component’s page rather than guessing.
|
|
45
|
+
- Styling and host attributes belong on the component host. Use inherited theme tokens, documented CSS custom properties or `::part` hooks; do not target shadow-DOM internals.
|
|
46
|
+
- Keep labels, accessible names, and app behavior in the host view. The component handles its documented interaction and reports changes; the web part handles SharePoint data and persistence.
|
|
47
|
+
|
|
48
|
+
Use composition like this:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
import { Avatar, Button, Persona, Tooltip } from "@spfx-fast/sharepoint-ui/react";
|
|
52
|
+
|
|
53
|
+
export function RequestActions({ openRequest, photoUrl }: { openRequest: () => void; photoUrl: string }) {
|
|
54
|
+
return (
|
|
55
|
+
<>
|
|
56
|
+
<Tooltip content="Opens the request details">
|
|
57
|
+
<Button onClick={openRequest}>Open request</Button>
|
|
58
|
+
</Tooltip>
|
|
59
|
+
<Persona
|
|
60
|
+
name="Ada Lovelace"
|
|
61
|
+
primaryText="Ada Lovelace"
|
|
62
|
+
secondaryText="Engineering"
|
|
63
|
+
avatar={<Avatar name="Ada Lovelace" image={photoUrl} decorative />}
|
|
64
|
+
/>
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
`Tooltip` uses its children as the trigger and its `content` as the tooltip. `Persona` accepts identity text directly and an optional composed `Avatar`. Other components follow the same import, provider, children, and host-styling rules; use their own page for their specific props, slots, and callback signatures. For Tooltip controlled visibility, use `open` with `onOpenChange`; `visible` and `onVisibleChange` remain compatibility aliases.
|
|
71
|
+
|
|
72
|
+
For a responsive command shelf, let `Overflow` move lower-priority actions into its menu. `useStoredOverflowCompactMode` remembers a per-browser compact spacing choice; include the app and site in its key so separate workspaces do not share a setting:
|
|
73
|
+
|
|
74
|
+
```tsx
|
|
75
|
+
import { Button, Overflow, OverflowItem, ToggleButton, useStoredOverflowCompactMode } from "@spfx-fast/sharepoint-ui/react";
|
|
76
|
+
|
|
77
|
+
function RequestCommands({ siteId }: { siteId: string }) {
|
|
78
|
+
const { compact, setCompact } = useStoredOverflowCompactMode(`requests:${siteId}`);
|
|
79
|
+
return <>
|
|
80
|
+
<ToggleButton pressed={compact} onPressedChange={setCompact}>Compact commands</ToggleButton>
|
|
81
|
+
<Overflow label="Request actions" density={compact ? "compact" : "comfortable"}>
|
|
82
|
+
<OverflowItem id="open" priority={2}><Button>Open</Button></OverflowItem>
|
|
83
|
+
<OverflowItem id="share" priority={1}><Button>Share</Button></OverflowItem>
|
|
84
|
+
</Overflow>
|
|
85
|
+
</>;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
For custom elements, set `density="compact"` on `<spui-overflow>` and persist the toggle with the app's preferred storage. Token-sized controls remain at least 44px tall on coarse-pointer devices; explicit component sizes stay in effect.
|
|
90
|
+
|
|
91
|
+
## Another framework or plain HTML
|
|
92
|
+
|
|
93
|
+
Import only the component’s leaf factory, register it once, then use its documented custom-element tag:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { defineButton } from "@spfx-fast/sharepoint-ui/elements/button";
|
|
97
|
+
|
|
98
|
+
defineButton();
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<spui-button appearance="primary">Open</spui-button>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## SPFx 1.24 Copilot UX components
|
|
106
|
+
|
|
107
|
+
For a Copilot surface that reads SharePoint data, updates the visible-state context, and saves through `SPHttpClient`, use the [SPFx CLI template](https://github.com/vystartasv/sharepoint-ui/tree/main/templates/spfx-fast-copilot-access-review) or the [complete tenant-connected example](https://github.com/vystartasv/sharepoint-ui/tree/main/examples/spfx124-copilot-ux). Both are framework-free and import only the custom elements they use.
|
|
108
|
+
|
|
109
|
+
For a metadata-driven form, use `<SharePointField>` from `/react` or `<spui-sharepoint-field>` without React. Both select the control from SharePoint metadata, apply accessible labels and field rules, and support rich-text Notes. Load Lookup/User options in the host; Choice values come from field metadata. For custom elements, register once and set object data as properties:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { defineSharePointField } from "@spfx-fast/sharepoint-ui/elements/sharepoint-fields";
|
|
113
|
+
|
|
114
|
+
defineSharePointField();
|
|
115
|
+
const control = document.querySelector("spui-sharepoint-field")!;
|
|
116
|
+
control.field = column;
|
|
117
|
+
control.value = item[column.InternalName];
|
|
118
|
+
control.options = lookupOptions;
|
|
119
|
+
control.addEventListener("spui-field-value-change", event => updateDraft(event.detail.field, event.detail.value));
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
For custom layouts, request definitions with `getSharePointFieldMetadataUrl(webUrl, listId)` and inspect each `getSharePointFieldAdapter(field)` recipe. Use `serializeSharePointFieldValues(fields, valuesByInternalName)` to assemble a PATCH body: omitted values stay untouched and `null` clears optional fields. New-item forms must include every required value. `getSharePointListItemUrl(webUrl, listId, itemId)` builds a validated item endpoint; the host supplies authorization, ETag, and REST entity-type metadata. Generic and focused serializers reject empty required values and read-only writes, enforce configured numeric precision and bounds, and reject values over the configured text length. `getSharePointNextPageUrl(webUrl, nextLink)` safely resolves same-origin OData paging links; `getSharePointLookupOptionsUrl(field, sourceWebUrl)` builds lookup requests. The app supplies authorized fetches, people search, permissions, and persistence.
|
|
123
|
+
|
|
124
|
+
Forward adapter `min`, `max`, and `maxLength` to matching controls when present. The serializers enforce numeric bounds and text lengths too; SharePoint remains the final validator.
|
|
125
|
+
|
|
126
|
+
## Build from a component page
|
|
127
|
+
|
|
128
|
+
1. Copy the React export or custom-element tag and its property/slot table.
|
|
129
|
+
2. Use the matching component JSON slice linked from that page for exact types and callbacks.
|
|
130
|
+
3. Use the shared `agentContract` included in every component JSON slice, then follow that component’s exact state props, callbacks, and slots.
|
|
131
|
+
4. Keep app state and persistence in the host; connect documented callbacks to it.
|
|
132
|
+
|
|
133
|
+
The same pattern applies across components. Add `SharePointUIProvider` once at the view root for React; custom elements inherit theme and direction from their host context. Each component slice links to its module event inventory. `detailPropertiesComplete` tells whether the listed event detail keys are exhaustive. Events are module-scoped: when several tags share a module, check the event target before handling them. Use the [component conventions guide](https://vystartasv.github.io/sharepoint-ui/guides/component-patterns/) for human-readable composition examples and the component page plus its JSON slice for exact APIs.
|