fluentui-extended 2026.8.70 → 2026.8.72
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/CHANGELOG.md +40 -1
- package/README.md +82 -0
- package/dist/index.d.mts +578 -2
- package/dist/index.d.ts +578 -2
- package/dist/index.js +1951 -437
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1931 -434
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,7 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
> Version format: `YYYY.M.DD` (e.g., `2026.8.30` = August 30, 2026)
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 2026.8.72
|
|
6
|
+
|
|
7
|
+
- ✨ **[FluentShell](docs/FluentShell.md)** — the outermost element of a Dynamics 365 web resource,
|
|
8
|
+
sizing the app to whatever chrome hosts its iframe. The correct gutter is not a constant: it depends
|
|
9
|
+
on what the host already pads and on where the form's content column sits, and both move with the
|
|
10
|
+
window and the D365 release. The shell walks its own iframe's ancestors for the padding already
|
|
11
|
+
applied, lines its edges up with the form column, and adds only the difference. Ships a console API
|
|
12
|
+
(`__fluentShell`) for measuring and tuning a deployed web resource without a rebuild.
|
|
13
|
+
- ✨ **[FluentContainer](docs/FluentContainer.md)** — a card matching the surface D365 draws on a
|
|
14
|
+
model-driven form, measured from a live form rather than approximated: `shadow4`, an 8px radius, and
|
|
15
|
+
a *transparent* hairline border. Clipping is opt-in via `scrolls`, because a shadow paints outside
|
|
16
|
+
the border box and any ancestor clipping at the card's own bounds erases it — a bug that reads as
|
|
17
|
+
"the card looks slightly flat" rather than as anything obviously wrong. In development the container
|
|
18
|
+
warns when its nearest clipping ancestor is too tight; the check compiles out of production.
|
|
19
|
+
- ✨ **[D365TestHarness](docs/D365TestHarness.md)** — a local stand-in for the Dynamics 365 form that
|
|
20
|
+
hosts a web resource. On a bare dev server there is no chrome to measure, so `FluentShell` falls
|
|
21
|
+
back to its standalone behaviour and the layout being developed is not the one that ships. The
|
|
22
|
+
harness hosts the app in a genuine same-origin iframe and reproduces the geometry a live form
|
|
23
|
+
measures, so the same gutters resolve locally as in the org. Content is rendered into the frame
|
|
24
|
+
with Fluent's own cross-document support — a Griffel renderer bound to the frame's document —
|
|
25
|
+
rather than by copying stylesheets across. Inactive outside a local host, so the wrapper ships to
|
|
26
|
+
Dynamics as a no-op.
|
|
27
|
+
- 🔧 **The test harness is now a simulated Dynamics form.** Every example renders inside a
|
|
28
|
+
`D365TestHarness`, so components are judged at the width and against the chrome they will really
|
|
29
|
+
have, and the component list is the sitemap rather than a tab strip. Each page opens with when to
|
|
30
|
+
reach for the component and when to reach for something else, and each example carries a "Show
|
|
31
|
+
code" panel.
|
|
32
|
+
- 🔧 **`npm run gen:samples`** generates those snippets. Per-section samples are the library elements
|
|
33
|
+
lifted from the example files' own source, so the code shown is the code running; per-page samples
|
|
34
|
+
come from the README, whose blocks `verify:readme` compiles. The script also inserts the panels, so
|
|
35
|
+
a new example gets one by being written. Idempotent, and it fails loudly if a source heading moves.
|
|
36
|
+
- 🔧 A **Documentation** tab gathers the guidance and every snippet into one reference, assembled
|
|
37
|
+
from the same sources the pages use — so it cannot fall out of step with them.
|
|
38
|
+
- 🐛 The ParentPortal harness example imported `../../src/components/ParentPortal`, one level short,
|
|
39
|
+
so it failed to resolve and was never wired to a tab. `tsconfig.json` covers `src/**/*` only, so
|
|
40
|
+
`npm run typecheck` does not see the harness and could not catch it.
|
|
41
|
+
- 📝 Component documentation moved to `docs/`, with the README carrying a short showcase and a
|
|
42
|
+
"read more" link. The README is close to the ~64KB cap npm applies to the package page, and two
|
|
43
|
+
components' full reference would have pushed it past — `docs/` is not in `files`, so it costs
|
|
44
|
+
nothing in the published tarball.
|
|
6
45
|
|
|
7
46
|
- ✨ **[ParentPortal](README.md#parentportal)** — new component that renders Fluent UI content in the
|
|
8
47
|
parent document, escaping iframe boundaries with full Griffel styling and theme token sync. Designed
|
package/README.md
CHANGED
|
@@ -51,6 +51,26 @@ The two shadow variants are deprecated in Fluent and will be removed there. They
|
|
|
51
51
|
existing callers keep working, but `Combobox` and `Dropdown` never supported them, so a component
|
|
52
52
|
containing those narrows to the closest non-shadow fill rather than dropping the value.
|
|
53
53
|
|
|
54
|
+
## New here? Run the harness
|
|
55
|
+
|
|
56
|
+
The fastest way to understand this library is to see every component working, in a simulated
|
|
57
|
+
Dynamics 365 form, with the code beside it:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
git clone https://github.com/garethcheyne/npm-fluentui-extended.git
|
|
61
|
+
cd npm-fluentui-extended
|
|
62
|
+
npm install
|
|
63
|
+
npm run harness
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
That opens a mock model-driven app — top bar, sitemap, record form — with each component on its own
|
|
67
|
+
page: what it is for, when to reach for it, when to reach for something else, and a "Show code"
|
|
68
|
+
panel on every example holding the exact source that is running. The **Documentation** entry in the
|
|
69
|
+
sitemap gathers all of it in one page.
|
|
70
|
+
|
|
71
|
+
No Dynamics connection is needed; the examples run on mock data. To point them at a real org, see
|
|
72
|
+
[Local development](https://github.com/garethcheyne/npm-fluentui-extended/blob/main/docs/local-development.md).
|
|
73
|
+
|
|
54
74
|
## Components
|
|
55
75
|
|
|
56
76
|
### Lookup
|
|
@@ -173,6 +193,68 @@ function MyDialog({ open, onClose }) {
|
|
|
173
193
|
|
|
174
194
|
> **Requires same-origin:** The iframe and parent must be on the same domain (standard for D365 web resources).
|
|
175
195
|
|
|
196
|
+
### FluentShell
|
|
197
|
+
|
|
198
|
+
The outermost element of a Dynamics 365 web resource, fitting the app to whatever chrome hosts its iframe. The right gutter is not a constant - it depends on what the host already pads and where the form's content column sits, both of which move with the window and the D365 release - so `FluentShell` measures both and adds only the difference.
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
import { FluentProvider, webLightTheme } from '@fluentui/react-components';
|
|
202
|
+
import { FluentShell } from 'fluentui-extended';
|
|
203
|
+
|
|
204
|
+
function Root() {
|
|
205
|
+
return (
|
|
206
|
+
<FluentProvider theme={webLightTheme} style={{ height: '100%' }}>
|
|
207
|
+
<FluentShell>
|
|
208
|
+
<div>app</div>
|
|
209
|
+
</FluentShell>
|
|
210
|
+
</FluentProvider>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Nothing below it should set an outer margin - the two compound invisibly.
|
|
216
|
+
**[Read more →](https://github.com/garethcheyne/npm-fluentui-extended/blob/main/docs/FluentShell.md)** - props, surface detection, and the console tooling for a deployed web resource.
|
|
217
|
+
|
|
218
|
+
### FluentContainer
|
|
219
|
+
|
|
220
|
+
A card matching the surface D365 draws on a model-driven form, measured from a live form: `shadow4`, an 8px radius, and a **transparent** hairline border on the neutral page ground.
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import { FluentContainer } from 'fluentui-extended';
|
|
224
|
+
|
|
225
|
+
function Cards() {
|
|
226
|
+
return (
|
|
227
|
+
<FluentContainer fill scrolls="vertical" padding="none">
|
|
228
|
+
<div>grid</div>
|
|
229
|
+
</FluentContainer>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
**[Read more →](https://github.com/garethcheyne/npm-fluentui-extended/blob/main/docs/FluentContainer.md)** - props, and why clipping is opt-in.
|
|
235
|
+
|
|
236
|
+
### D365TestHarness
|
|
237
|
+
|
|
238
|
+
A local stand-in for the D365 form that will host a web resource. On a bare dev server there is no chrome to measure, so `FluentShell` falls back to standalone behaviour and the layout you develop is not the one that ships. The harness hosts your app in a genuine same-origin iframe and reproduces the geometry a live form measures, so the same gutters resolve locally as in the org.
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { D365TestHarness, FluentShell } from 'fluentui-extended';
|
|
242
|
+
|
|
243
|
+
function Root() {
|
|
244
|
+
return (
|
|
245
|
+
<D365TestHarness recordName="Boomer iMAC" entityName="Price List">
|
|
246
|
+
<FluentShell>
|
|
247
|
+
<div>app</div>
|
|
248
|
+
</FluentShell>
|
|
249
|
+
</D365TestHarness>
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
It is inactive outside a local host, so the same tree ships to Dynamics unwrapped.
|
|
255
|
+
**[Read more →](https://github.com/garethcheyne/npm-fluentui-extended/blob/main/docs/D365TestHarness.md)**
|
|
256
|
+
Setting this up in your own project also needs a dev-server proxy to reach Dataverse from `localhost`: see **[Local development](https://github.com/garethcheyne/npm-fluentui-extended/blob/main/docs/local-development.md)**.
|
|
257
|
+
|
|
176
258
|
## Quick Start
|
|
177
259
|
|
|
178
260
|
```tsx
|