@dataverse-kit/surface-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/columns-BlpFO5VD.d.cts +7 -0
- package/dist/columns-BlpFO5VD.d.ts +7 -0
- package/dist/core.cjs +100 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +38 -0
- package/dist/core.d.ts +38 -0
- package/dist/core.mjs +61 -0
- package/dist/core.mjs.map +1 -0
- package/dist/index.cjs +1202 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +445 -0
- package/dist/index.d.ts +445 -0
- package/dist/index.mjs +1122 -0
- package/dist/index.mjs.map +1 -0
- package/dist/responsive.cjs +122 -0
- package/dist/responsive.cjs.map +1 -0
- package/dist/responsive.d.cts +25 -0
- package/dist/responsive.d.ts +25 -0
- package/dist/responsive.mjs +89 -0
- package/dist/responsive.mjs.map +1 -0
- package/package.json +72 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1122 @@
|
|
|
1
|
+
// src/core/sizePresets.ts
|
|
2
|
+
var DIALOG_SIZE_PX = {
|
|
3
|
+
sm: 600,
|
|
4
|
+
md: 900,
|
|
5
|
+
lg: 1200,
|
|
6
|
+
xl: 1600
|
|
7
|
+
};
|
|
8
|
+
function dialogWidthPx(opts = {}) {
|
|
9
|
+
if (typeof opts.width === "number") return opts.width;
|
|
10
|
+
const size = opts.size ?? "lg";
|
|
11
|
+
if (size === "fullscreen") return DIALOG_SIZE_PX.xl;
|
|
12
|
+
return DIALOG_SIZE_PX[size];
|
|
13
|
+
}
|
|
14
|
+
function dialogWidthCss(opts = {}) {
|
|
15
|
+
if (opts.size === "fullscreen" && opts.width == null) return "95vw";
|
|
16
|
+
return `${dialogWidthPx(opts)}px`;
|
|
17
|
+
}
|
|
18
|
+
function dialogHeightCss(height) {
|
|
19
|
+
return height != null && height <= 100 ? `${height}vh` : "95vh";
|
|
20
|
+
}
|
|
21
|
+
var MODAL_AUTOSIZE_MIN_WIDTH = 1e3;
|
|
22
|
+
var PANEL_DEFAULT_WIDTH = 480;
|
|
23
|
+
function panelKindFromWidth(width) {
|
|
24
|
+
return (width ?? PANEL_DEFAULT_WIDTH) > 500 ? "medium" : "custom";
|
|
25
|
+
}
|
|
26
|
+
function panelCustomWidthPx(width) {
|
|
27
|
+
return width ?? PANEL_DEFAULT_WIDTH;
|
|
28
|
+
}
|
|
29
|
+
var CALLOUT_DEFAULT_WIDTH = 320;
|
|
30
|
+
var calloutFormDefaults = {
|
|
31
|
+
width: CALLOUT_DEFAULT_WIDTH,
|
|
32
|
+
directionalHint: "bottomLeftEdge"
|
|
33
|
+
};
|
|
34
|
+
function calloutWidthPx(width) {
|
|
35
|
+
return width ?? CALLOUT_DEFAULT_WIDTH;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/core/columns.ts
|
|
39
|
+
function gridTemplateForColumns(columns) {
|
|
40
|
+
return `repeat(${columns}, 1fr)`;
|
|
41
|
+
}
|
|
42
|
+
function clampSpan(span, columns) {
|
|
43
|
+
if (!Number.isFinite(span)) return 1;
|
|
44
|
+
return Math.max(1, Math.min(Math.round(span), columns));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/responsive/breakpoints.ts
|
|
48
|
+
var BREAKPOINTS = {
|
|
49
|
+
xs: 0,
|
|
50
|
+
sm: 480,
|
|
51
|
+
md: 768,
|
|
52
|
+
lg: 1024,
|
|
53
|
+
xl: 1366
|
|
54
|
+
};
|
|
55
|
+
var CARD_REFLOW_WIDTH = 900;
|
|
56
|
+
var DESCENDING = ["xl", "lg", "md", "sm", "xs"];
|
|
57
|
+
var ASCENDING = ["xs", "sm", "md", "lg", "xl"];
|
|
58
|
+
function resolveBreakpoint(width) {
|
|
59
|
+
for (const bp of DESCENDING) {
|
|
60
|
+
if (width >= BREAKPOINTS[bp]) return bp;
|
|
61
|
+
}
|
|
62
|
+
return "xs";
|
|
63
|
+
}
|
|
64
|
+
function isResponsiveMap(v) {
|
|
65
|
+
return typeof v === "object" && v !== null && ASCENDING.some((bp) => bp in v);
|
|
66
|
+
}
|
|
67
|
+
function resolveResponsiveValue(value, breakpoint) {
|
|
68
|
+
if (!isResponsiveMap(value)) return value;
|
|
69
|
+
const map = value;
|
|
70
|
+
const idx = ASCENDING.indexOf(breakpoint);
|
|
71
|
+
for (let i = idx; i >= 0; i--) {
|
|
72
|
+
const v = map[ASCENDING[i]];
|
|
73
|
+
if (v !== void 0) return v;
|
|
74
|
+
}
|
|
75
|
+
for (let i = idx + 1; i < ASCENDING.length; i++) {
|
|
76
|
+
const v = map[ASCENDING[i]];
|
|
77
|
+
if (v !== void 0) return v;
|
|
78
|
+
}
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/responsive/builders.ts
|
|
83
|
+
function atRule(mode, maxPx) {
|
|
84
|
+
return mode === "container" ? `@container (max-width: ${maxPx}px)` : `@media (max-width: ${maxPx}px)`;
|
|
85
|
+
}
|
|
86
|
+
function fieldGridStyle(columns, mode = "media") {
|
|
87
|
+
const capped = Math.min(columns, 2);
|
|
88
|
+
return {
|
|
89
|
+
display: "grid",
|
|
90
|
+
gridTemplateColumns: gridTemplateForColumns(columns),
|
|
91
|
+
gap: "4px 24px",
|
|
92
|
+
selectors: {
|
|
93
|
+
[atRule(mode, BREAKPOINTS.md)]: { gridTemplateColumns: gridTemplateForColumns(capped) },
|
|
94
|
+
[atRule(mode, BREAKPOINTS.sm)]: { gridTemplateColumns: "1fr" }
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
function sectionStackingStyle(gridTemplateColumns, mode = "media") {
|
|
99
|
+
return {
|
|
100
|
+
display: "grid",
|
|
101
|
+
gridTemplateColumns,
|
|
102
|
+
gap: 16,
|
|
103
|
+
alignItems: "start",
|
|
104
|
+
selectors: {
|
|
105
|
+
[atRule(mode, BREAKPOINTS.md)]: { gridTemplateColumns: "1fr" }
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function fieldRowStyle(labelWidth = "130px", mode = "media") {
|
|
110
|
+
return {
|
|
111
|
+
display: "grid",
|
|
112
|
+
gridTemplateColumns: `${labelWidth} 1fr`,
|
|
113
|
+
alignItems: "center",
|
|
114
|
+
gap: 8,
|
|
115
|
+
minHeight: 38,
|
|
116
|
+
selectors: {
|
|
117
|
+
[atRule(mode, BREAKPOINTS.sm)]: { gridTemplateColumns: "1fr", alignItems: "flex-start", minHeight: 0, gap: 4 }
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/tokens/tokens.ts
|
|
123
|
+
var colors = {
|
|
124
|
+
brand: "#0078d4",
|
|
125
|
+
brandHover: "#106ebe",
|
|
126
|
+
brandDark: "#005a9e",
|
|
127
|
+
borderNeutral: "#edebe9",
|
|
128
|
+
textPrimary: "#323130",
|
|
129
|
+
textSecondary: "#605e5c",
|
|
130
|
+
surface: "#ffffff",
|
|
131
|
+
surfaceAlt: "#f5f5f5",
|
|
132
|
+
// App canvas behind cards/forms (matches the Dynamics model-driven form background).
|
|
133
|
+
canvas: "#fafafa",
|
|
134
|
+
// Required-field asterisk / error accent (Fluent error red).
|
|
135
|
+
danger: "#a4262c",
|
|
136
|
+
// Field input: subtle idle fill + neutral border (Dynamics-style).
|
|
137
|
+
fieldFill: "#faf9f8",
|
|
138
|
+
fieldFillReadonly: "#f3f2f1",
|
|
139
|
+
fieldBorder: "#e1dfdd"
|
|
140
|
+
};
|
|
141
|
+
var spacing = {
|
|
142
|
+
xs: 4,
|
|
143
|
+
sm: 8,
|
|
144
|
+
md: 12,
|
|
145
|
+
lg: 16,
|
|
146
|
+
xl: 24,
|
|
147
|
+
xxl: 40
|
|
148
|
+
};
|
|
149
|
+
var typography = {
|
|
150
|
+
fontFamily: '"Segoe UI", Arial, sans-serif',
|
|
151
|
+
fontFamilySemibold: '"Segoe UI Semibold", "Segoe UI", sans-serif',
|
|
152
|
+
fontSize: {
|
|
153
|
+
sm: "12px",
|
|
154
|
+
smPlus: "13px",
|
|
155
|
+
md: "14px",
|
|
156
|
+
lg: "17px"
|
|
157
|
+
},
|
|
158
|
+
fontWeight: {
|
|
159
|
+
regular: 400,
|
|
160
|
+
semibold: 600
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
var radius = {
|
|
164
|
+
card: "4px",
|
|
165
|
+
// Softer rounding for the outer form shell (matches Dynamics cards).
|
|
166
|
+
lg: "8px"
|
|
167
|
+
};
|
|
168
|
+
var layout = {
|
|
169
|
+
// Width of the label column in a two-column "Label : input" field row.
|
|
170
|
+
labelColWidth: "130px"
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// src/tokens/theme.ts
|
|
174
|
+
import { createTheme } from "@fluentui/react";
|
|
175
|
+
function createDynamicsTheme() {
|
|
176
|
+
return createTheme({
|
|
177
|
+
palette: {
|
|
178
|
+
themePrimary: colors.brand,
|
|
179
|
+
themeDarkAlt: colors.brandHover,
|
|
180
|
+
themeDark: colors.brandDark,
|
|
181
|
+
themeDarker: colors.brandDark,
|
|
182
|
+
neutralPrimary: colors.textPrimary,
|
|
183
|
+
neutralSecondary: colors.textSecondary,
|
|
184
|
+
neutralLight: colors.borderNeutral,
|
|
185
|
+
neutralLighter: colors.surfaceAlt,
|
|
186
|
+
white: colors.surface,
|
|
187
|
+
redDark: colors.danger
|
|
188
|
+
},
|
|
189
|
+
defaultFontStyle: {
|
|
190
|
+
fontFamily: typography.fontFamily
|
|
191
|
+
},
|
|
192
|
+
semanticColors: {
|
|
193
|
+
errorText: colors.danger,
|
|
194
|
+
inputBorder: colors.fieldBorder,
|
|
195
|
+
inputBackground: colors.fieldFill,
|
|
196
|
+
bodyBackground: colors.surface
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// src/tokens/density.ts
|
|
202
|
+
var densityScale = {
|
|
203
|
+
comfortable: 1,
|
|
204
|
+
compact: 0.75
|
|
205
|
+
};
|
|
206
|
+
function scaleSpacing(value, density = "comfortable") {
|
|
207
|
+
return Math.round(value * densityScale[density]);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// src/hooks/useContainerSize.ts
|
|
211
|
+
import { useState, useEffect } from "react";
|
|
212
|
+
function useContainerSize(ref) {
|
|
213
|
+
const [size, setSize] = useState({ width: 0, height: 0, inlineSize: 0, blockSize: 0 });
|
|
214
|
+
useEffect(() => {
|
|
215
|
+
if (!ref.current || typeof ResizeObserver === "undefined") return;
|
|
216
|
+
const observer = new ResizeObserver((entries) => {
|
|
217
|
+
for (const entry of entries) {
|
|
218
|
+
const { width, height } = entry.contentRect;
|
|
219
|
+
const inlineSize = entry.borderBoxSize?.[0]?.inlineSize ?? width;
|
|
220
|
+
const blockSize = entry.borderBoxSize?.[0]?.blockSize ?? height;
|
|
221
|
+
setSize({ width, height, inlineSize, blockSize });
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
observer.observe(ref.current);
|
|
225
|
+
return () => observer.disconnect();
|
|
226
|
+
}, [ref]);
|
|
227
|
+
return size;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/hooks/useContainerWidth.ts
|
|
231
|
+
import { useRef } from "react";
|
|
232
|
+
function useContainerWidth() {
|
|
233
|
+
const ref = useRef(null);
|
|
234
|
+
const { width } = useContainerSize(ref);
|
|
235
|
+
return [ref, width];
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/hooks/useContainerBreakpoint.ts
|
|
239
|
+
function useContainerBreakpoint() {
|
|
240
|
+
const [ref, width] = useContainerWidth();
|
|
241
|
+
return [ref, resolveBreakpoint(width), width];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// src/hooks/useResponsiveValue.ts
|
|
245
|
+
function useResponsiveValue(value) {
|
|
246
|
+
const [ref, breakpoint] = useContainerBreakpoint();
|
|
247
|
+
return [ref, resolveResponsiveValue(value, breakpoint)];
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// src/hooks/useMediaQuery.ts
|
|
251
|
+
import { useState as useState2, useEffect as useEffect2 } from "react";
|
|
252
|
+
function useMediaQuery(query) {
|
|
253
|
+
const [matches, setMatches] = useState2(() => {
|
|
254
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false;
|
|
255
|
+
return window.matchMedia(query).matches;
|
|
256
|
+
});
|
|
257
|
+
useEffect2(() => {
|
|
258
|
+
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
259
|
+
const mql = window.matchMedia(query);
|
|
260
|
+
const onChange = () => setMatches(mql.matches);
|
|
261
|
+
onChange();
|
|
262
|
+
mql.addEventListener("change", onChange);
|
|
263
|
+
return () => mql.removeEventListener("change", onChange);
|
|
264
|
+
}, [query]);
|
|
265
|
+
return matches;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// src/layouts/ColumnLayout.tsx
|
|
269
|
+
import { mergeStyles } from "@fluentui/react";
|
|
270
|
+
import { jsx } from "react/jsx-runtime";
|
|
271
|
+
var ColumnLayout = ({
|
|
272
|
+
columns,
|
|
273
|
+
gap = "4px 24px",
|
|
274
|
+
responsive = true,
|
|
275
|
+
mode = "media",
|
|
276
|
+
className,
|
|
277
|
+
style,
|
|
278
|
+
children
|
|
279
|
+
}) => {
|
|
280
|
+
const base = responsive ? fieldGridStyle(columns, mode) : { display: "grid", gridTemplateColumns: gridTemplateForColumns(columns) };
|
|
281
|
+
const cls = mergeStyles(base, { gap }, className);
|
|
282
|
+
return /* @__PURE__ */ jsx("div", { className: cls, style, children });
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
// src/layouts/TwoColumnLayout.tsx
|
|
286
|
+
import { mergeStyles as mergeStyles2 } from "@fluentui/react";
|
|
287
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
288
|
+
var TwoColumnLayout = ({
|
|
289
|
+
gap = 16,
|
|
290
|
+
collapseBelow = "sm",
|
|
291
|
+
className,
|
|
292
|
+
style,
|
|
293
|
+
children
|
|
294
|
+
}) => {
|
|
295
|
+
const cls = mergeStyles2(
|
|
296
|
+
{
|
|
297
|
+
display: "grid",
|
|
298
|
+
gridTemplateColumns: "1fr 1fr",
|
|
299
|
+
gap,
|
|
300
|
+
alignItems: "start",
|
|
301
|
+
selectors: {
|
|
302
|
+
[`@media (max-width: ${BREAKPOINTS[collapseBelow]}px)`]: { gridTemplateColumns: "1fr" }
|
|
303
|
+
}
|
|
304
|
+
},
|
|
305
|
+
className
|
|
306
|
+
);
|
|
307
|
+
return /* @__PURE__ */ jsx2("div", { className: cls, style, children });
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// src/layouts/FieldRow.tsx
|
|
311
|
+
import { mergeStyleSets } from "@fluentui/react";
|
|
312
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
313
|
+
var FieldRow = ({
|
|
314
|
+
label,
|
|
315
|
+
required,
|
|
316
|
+
fullWidth,
|
|
317
|
+
labelWidth = "130px",
|
|
318
|
+
labelPosition = "beside",
|
|
319
|
+
className,
|
|
320
|
+
children
|
|
321
|
+
}) => {
|
|
322
|
+
const styles = mergeStyleSets({
|
|
323
|
+
// The beside layout IS the shared responsive builder (130px label grid + @480
|
|
324
|
+
// stack) — no hand-written breakpoint here.
|
|
325
|
+
rowBeside: fieldRowStyle(labelWidth, "media"),
|
|
326
|
+
rowAbove: {
|
|
327
|
+
display: "grid",
|
|
328
|
+
gridTemplateColumns: "1fr",
|
|
329
|
+
gap: 2,
|
|
330
|
+
minHeight: 38
|
|
331
|
+
},
|
|
332
|
+
label: {
|
|
333
|
+
fontSize: typography.fontSize.sm,
|
|
334
|
+
fontWeight: typography.fontWeight.semibold,
|
|
335
|
+
color: colors.textPrimary,
|
|
336
|
+
fontFamily: typography.fontFamily,
|
|
337
|
+
lineHeight: "1.3",
|
|
338
|
+
wordBreak: "break-word"
|
|
339
|
+
},
|
|
340
|
+
required: { color: colors.danger, marginLeft: 2, fontWeight: typography.fontWeight.semibold },
|
|
341
|
+
full: { gridColumn: "1 / -1" }
|
|
342
|
+
});
|
|
343
|
+
const cls = [
|
|
344
|
+
labelPosition === "above" ? styles.rowAbove : styles.rowBeside,
|
|
345
|
+
fullWidth ? styles.full : "",
|
|
346
|
+
className
|
|
347
|
+
].filter(Boolean).join(" ");
|
|
348
|
+
return /* @__PURE__ */ jsxs("div", { className: cls, children: [
|
|
349
|
+
label != null && /* @__PURE__ */ jsxs("span", { className: styles.label, children: [
|
|
350
|
+
label,
|
|
351
|
+
required && /* @__PURE__ */ jsx3("span", { className: styles.required, children: "*" })
|
|
352
|
+
] }),
|
|
353
|
+
children
|
|
354
|
+
] });
|
|
355
|
+
};
|
|
356
|
+
|
|
357
|
+
// src/containers/FormSurface.tsx
|
|
358
|
+
import { mergeStyles as mergeStyles3 } from "@fluentui/react";
|
|
359
|
+
|
|
360
|
+
// src/internal/styles.ts
|
|
361
|
+
var sharedTitleStyle = {
|
|
362
|
+
fontWeight: typography.fontWeight.semibold,
|
|
363
|
+
fontSize: typography.fontSize.md,
|
|
364
|
+
color: colors.textPrimary,
|
|
365
|
+
fontFamily: typography.fontFamilySemibold,
|
|
366
|
+
paddingBottom: 0,
|
|
367
|
+
marginBottom: 0
|
|
368
|
+
};
|
|
369
|
+
var dynamicsCardStyle = {
|
|
370
|
+
background: colors.surface,
|
|
371
|
+
border: `1px solid ${colors.borderNeutral}`,
|
|
372
|
+
borderRadius: radius.card,
|
|
373
|
+
overflow: "hidden"
|
|
374
|
+
};
|
|
375
|
+
var cardShadow = "0 1.6px 3.6px rgba(0, 0, 0, 0.08), 0 0.3px 0.9px rgba(0, 0, 0, 0.05)";
|
|
376
|
+
function stackChildrenBelow(maxPx) {
|
|
377
|
+
return {
|
|
378
|
+
selectors: {
|
|
379
|
+
[`@media (max-width: ${maxPx}px)`]: {
|
|
380
|
+
selectors: { "> *": { gridColumn: "1 / -1" } }
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// src/containers/FormSurface.tsx
|
|
387
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
388
|
+
var FormSurface = ({
|
|
389
|
+
columns = 12,
|
|
390
|
+
gap = 20,
|
|
391
|
+
padding = 20,
|
|
392
|
+
background = colors.canvas,
|
|
393
|
+
containerWidth,
|
|
394
|
+
collapseBelow = "sm",
|
|
395
|
+
maxWidth,
|
|
396
|
+
className,
|
|
397
|
+
style,
|
|
398
|
+
children
|
|
399
|
+
}) => {
|
|
400
|
+
const collapsePx = BREAKPOINTS[collapseBelow];
|
|
401
|
+
const forceStack = containerWidth != null && containerWidth <= collapsePx;
|
|
402
|
+
const cls = mergeStyles3(
|
|
403
|
+
{
|
|
404
|
+
display: "grid",
|
|
405
|
+
gridTemplateColumns: forceStack ? "1fr" : `repeat(${columns}, 1fr)`,
|
|
406
|
+
gap,
|
|
407
|
+
padding,
|
|
408
|
+
background,
|
|
409
|
+
alignItems: "start",
|
|
410
|
+
...maxWidth != null ? { maxWidth, marginLeft: "auto", marginRight: "auto" } : {},
|
|
411
|
+
// When the container forces a single column, reset child spans the same way the
|
|
412
|
+
// viewport fallback does — otherwise a Section with `columnStart` references grid
|
|
413
|
+
// lines that no longer exist and escapes the stack. (Mutually exclusive with the
|
|
414
|
+
// @media fallback below, which only applies when containerWidth is unset.)
|
|
415
|
+
...forceStack ? { selectors: { "> *": { gridColumn: "1 / -1" } } } : {},
|
|
416
|
+
// Viewport fallback only when the container width isn't explicitly provided.
|
|
417
|
+
...containerWidth == null ? stackChildrenBelow(collapsePx) : {}
|
|
418
|
+
},
|
|
419
|
+
className
|
|
420
|
+
);
|
|
421
|
+
return /* @__PURE__ */ jsx4("div", { className: cls, style, children });
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
// src/containers/PageSurface.tsx
|
|
425
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
426
|
+
var PageSurface = ({ centered, maxWidth, ...rest }) => /* @__PURE__ */ jsx5(FormSurface, { maxWidth: maxWidth ?? (centered ? 1200 : void 0), ...rest });
|
|
427
|
+
|
|
428
|
+
// src/containers/Section.tsx
|
|
429
|
+
import { useState as useState3 } from "react";
|
|
430
|
+
import { mergeStyleSets as mergeStyleSets3 } from "@fluentui/react";
|
|
431
|
+
|
|
432
|
+
// src/containers/SectionHeader.tsx
|
|
433
|
+
import { mergeStyleSets as mergeStyleSets2, CommandBar, Icon } from "@fluentui/react";
|
|
434
|
+
import { jsx as jsx6, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
435
|
+
var SectionHeader = ({
|
|
436
|
+
title,
|
|
437
|
+
statusText,
|
|
438
|
+
showCommandBar,
|
|
439
|
+
commandBarItems = [],
|
|
440
|
+
actions,
|
|
441
|
+
collapsible,
|
|
442
|
+
collapsed,
|
|
443
|
+
onToggle
|
|
444
|
+
}) => {
|
|
445
|
+
const styles = mergeStyleSets2({
|
|
446
|
+
root: {
|
|
447
|
+
display: "flex",
|
|
448
|
+
justifyContent: "space-between",
|
|
449
|
+
alignItems: "center",
|
|
450
|
+
flexWrap: "nowrap",
|
|
451
|
+
borderBottom: `1px solid ${colors.borderNeutral}`,
|
|
452
|
+
marginBottom: 16,
|
|
453
|
+
minHeight: 48,
|
|
454
|
+
width: "100%"
|
|
455
|
+
},
|
|
456
|
+
left: { display: "flex", alignItems: "center", gap: 8, minWidth: 0 },
|
|
457
|
+
title: sharedTitleStyle,
|
|
458
|
+
status: { marginLeft: 8, fontSize: "0.9em", color: colors.textSecondary },
|
|
459
|
+
chevron: {
|
|
460
|
+
cursor: "pointer",
|
|
461
|
+
border: "none",
|
|
462
|
+
background: "transparent",
|
|
463
|
+
padding: 4,
|
|
464
|
+
display: "flex",
|
|
465
|
+
alignItems: "center",
|
|
466
|
+
color: colors.textSecondary
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
return /* @__PURE__ */ jsxs2("div", { className: styles.root, children: [
|
|
470
|
+
/* @__PURE__ */ jsxs2("div", { className: styles.left, children: [
|
|
471
|
+
collapsible && /* @__PURE__ */ jsx6(
|
|
472
|
+
"button",
|
|
473
|
+
{
|
|
474
|
+
type: "button",
|
|
475
|
+
className: styles.chevron,
|
|
476
|
+
onClick: onToggle,
|
|
477
|
+
"aria-label": collapsed ? "Expand section" : "Collapse section",
|
|
478
|
+
"aria-expanded": !collapsed,
|
|
479
|
+
children: /* @__PURE__ */ jsx6(Icon, { iconName: collapsed ? "ChevronRight" : "ChevronDown" })
|
|
480
|
+
}
|
|
481
|
+
),
|
|
482
|
+
title && /* @__PURE__ */ jsx6("span", { className: styles.title, children: title }),
|
|
483
|
+
statusText && /* @__PURE__ */ jsx6("span", { className: styles.status, children: statusText })
|
|
484
|
+
] }),
|
|
485
|
+
actions ? /* @__PURE__ */ jsx6("div", { children: actions }) : showCommandBar && commandBarItems.length > 0 ? /* @__PURE__ */ jsx6(
|
|
486
|
+
CommandBar,
|
|
487
|
+
{
|
|
488
|
+
items: commandBarItems.slice(0, 2),
|
|
489
|
+
overflowItems: commandBarItems.slice(2),
|
|
490
|
+
styles: { root: { background: "transparent", padding: 0, height: "auto" } }
|
|
491
|
+
}
|
|
492
|
+
) : null
|
|
493
|
+
] });
|
|
494
|
+
};
|
|
495
|
+
|
|
496
|
+
// src/containers/Section.tsx
|
|
497
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
498
|
+
var Section = ({
|
|
499
|
+
title,
|
|
500
|
+
columnSpan = 12,
|
|
501
|
+
columnStart,
|
|
502
|
+
rowPosition,
|
|
503
|
+
internalColumns = 12,
|
|
504
|
+
showCommandBar,
|
|
505
|
+
commandBarItems,
|
|
506
|
+
statusText,
|
|
507
|
+
notification,
|
|
508
|
+
collapsible,
|
|
509
|
+
defaultCollapsed = false,
|
|
510
|
+
collapsed: controlledCollapsed,
|
|
511
|
+
onCollapsedChange,
|
|
512
|
+
variant = "card",
|
|
513
|
+
minHeight = 80,
|
|
514
|
+
className,
|
|
515
|
+
style,
|
|
516
|
+
children
|
|
517
|
+
}) => {
|
|
518
|
+
const [internalCollapsed, setInternalCollapsed] = useState3(defaultCollapsed);
|
|
519
|
+
const collapsed = controlledCollapsed ?? internalCollapsed;
|
|
520
|
+
const toggle = () => {
|
|
521
|
+
const next = !collapsed;
|
|
522
|
+
if (controlledCollapsed == null) setInternalCollapsed(next);
|
|
523
|
+
onCollapsedChange?.(next);
|
|
524
|
+
};
|
|
525
|
+
const gridColumn = columnStart ? `${columnStart} / span ${columnSpan}` : `span ${columnSpan}`;
|
|
526
|
+
const rootStyle = {
|
|
527
|
+
gridColumn,
|
|
528
|
+
...rowPosition ? { gridRowStart: rowPosition } : {},
|
|
529
|
+
...style
|
|
530
|
+
};
|
|
531
|
+
const styles = mergeStyleSets3({
|
|
532
|
+
card: { ...dynamicsCardStyle, boxShadow: cardShadow, padding: "3px 20px 20px 20px", minWidth: 300, width: "100%" },
|
|
533
|
+
flat: {
|
|
534
|
+
background: colors.surface,
|
|
535
|
+
borderRadius: radius.card,
|
|
536
|
+
padding: "3px 20px 20px 20px",
|
|
537
|
+
minWidth: 300,
|
|
538
|
+
width: "100%",
|
|
539
|
+
overflow: "hidden"
|
|
540
|
+
},
|
|
541
|
+
placeholder: {
|
|
542
|
+
border: `1px dashed ${colors.borderNeutral}`,
|
|
543
|
+
borderRadius: radius.card,
|
|
544
|
+
minHeight,
|
|
545
|
+
width: "100%",
|
|
546
|
+
background: "transparent"
|
|
547
|
+
},
|
|
548
|
+
notification: { marginBottom: 8 },
|
|
549
|
+
body: {
|
|
550
|
+
display: "grid",
|
|
551
|
+
gridTemplateColumns: `repeat(${internalColumns}, 1fr)`,
|
|
552
|
+
gap: 7,
|
|
553
|
+
alignItems: "start",
|
|
554
|
+
selectors: {
|
|
555
|
+
[`@media (max-width: ${BREAKPOINTS.sm}px)`]: { selectors: { "> *": { gridColumn: "1 / -1" } } }
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
if (variant === "placeholder") {
|
|
560
|
+
return /* @__PURE__ */ jsx7("div", { className: [styles.placeholder, className].filter(Boolean).join(" "), style: rootStyle });
|
|
561
|
+
}
|
|
562
|
+
const showHeader = Boolean(title) || showCommandBar || collapsible;
|
|
563
|
+
return /* @__PURE__ */ jsxs3("div", { className: [variant === "flat" ? styles.flat : styles.card, className].filter(Boolean).join(" "), style: rootStyle, children: [
|
|
564
|
+
notification && /* @__PURE__ */ jsx7("div", { className: styles.notification, children: notification }),
|
|
565
|
+
showHeader && /* @__PURE__ */ jsx7(
|
|
566
|
+
SectionHeader,
|
|
567
|
+
{
|
|
568
|
+
title,
|
|
569
|
+
statusText,
|
|
570
|
+
showCommandBar,
|
|
571
|
+
commandBarItems,
|
|
572
|
+
collapsible,
|
|
573
|
+
collapsed,
|
|
574
|
+
onToggle: toggle
|
|
575
|
+
}
|
|
576
|
+
),
|
|
577
|
+
!collapsed && /* @__PURE__ */ jsx7("div", { className: styles.body, children })
|
|
578
|
+
] });
|
|
579
|
+
};
|
|
580
|
+
|
|
581
|
+
// src/containers/SectionCard.tsx
|
|
582
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
583
|
+
var SectionCard = ({
|
|
584
|
+
accentColor = colors.brand,
|
|
585
|
+
accentWidth = 3,
|
|
586
|
+
variant = "card",
|
|
587
|
+
style,
|
|
588
|
+
...rest
|
|
589
|
+
}) => /* @__PURE__ */ jsx8(
|
|
590
|
+
Section,
|
|
591
|
+
{
|
|
592
|
+
variant,
|
|
593
|
+
...rest,
|
|
594
|
+
style: { borderTop: `${accentWidth}px solid ${accentColor}`, ...style }
|
|
595
|
+
}
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
// src/containers/FormHeader.tsx
|
|
599
|
+
import { mergeStyleSets as mergeStyleSets4 } from "@fluentui/react";
|
|
600
|
+
import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
601
|
+
var FormHeader = ({
|
|
602
|
+
title,
|
|
603
|
+
subtitle,
|
|
604
|
+
status,
|
|
605
|
+
titleColor,
|
|
606
|
+
subtitleColor,
|
|
607
|
+
persona,
|
|
608
|
+
actions,
|
|
609
|
+
className
|
|
610
|
+
}) => {
|
|
611
|
+
const styles = mergeStyleSets4({
|
|
612
|
+
root: {
|
|
613
|
+
display: "flex",
|
|
614
|
+
alignItems: "center",
|
|
615
|
+
justifyContent: "space-between",
|
|
616
|
+
gap: 12,
|
|
617
|
+
padding: "12px 24px",
|
|
618
|
+
borderBottom: `1px solid ${colors.borderNeutral}`,
|
|
619
|
+
background: colors.surface
|
|
620
|
+
},
|
|
621
|
+
main: { display: "flex", alignItems: "center", gap: 12, minWidth: 0 },
|
|
622
|
+
titleRow: { display: "flex", alignItems: "baseline", gap: 8, flexWrap: "wrap" },
|
|
623
|
+
title: {
|
|
624
|
+
fontSize: typography.fontSize.lg,
|
|
625
|
+
fontWeight: typography.fontWeight.semibold,
|
|
626
|
+
fontFamily: typography.fontFamilySemibold,
|
|
627
|
+
color: titleColor || colors.textPrimary,
|
|
628
|
+
lineHeight: "1.3"
|
|
629
|
+
},
|
|
630
|
+
status: { fontSize: typography.fontSize.smPlus, color: colors.textSecondary },
|
|
631
|
+
subtitle: { fontSize: typography.fontSize.smPlus, color: subtitleColor || colors.textSecondary, marginTop: 2 }
|
|
632
|
+
});
|
|
633
|
+
return /* @__PURE__ */ jsxs4("div", { className: [styles.root, className].filter(Boolean).join(" "), children: [
|
|
634
|
+
/* @__PURE__ */ jsxs4("div", { className: styles.main, children: [
|
|
635
|
+
persona,
|
|
636
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
637
|
+
/* @__PURE__ */ jsxs4("div", { className: styles.titleRow, children: [
|
|
638
|
+
title != null && /* @__PURE__ */ jsx9("span", { className: styles.title, children: title }),
|
|
639
|
+
status != null && /* @__PURE__ */ jsx9("span", { className: styles.status, children: status })
|
|
640
|
+
] }),
|
|
641
|
+
subtitle != null && /* @__PURE__ */ jsx9("div", { className: styles.subtitle, children: subtitle })
|
|
642
|
+
] })
|
|
643
|
+
] }),
|
|
644
|
+
actions != null && /* @__PURE__ */ jsx9("div", { children: actions })
|
|
645
|
+
] });
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
// src/containers/PivotSurface.tsx
|
|
649
|
+
import { useState as useState4 } from "react";
|
|
650
|
+
import { Pivot, PivotItem } from "@fluentui/react";
|
|
651
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
652
|
+
var PivotSurface = ({
|
|
653
|
+
tabs,
|
|
654
|
+
selectedId,
|
|
655
|
+
defaultSelectedId,
|
|
656
|
+
onTabChange,
|
|
657
|
+
linkFormat = "links",
|
|
658
|
+
className
|
|
659
|
+
}) => {
|
|
660
|
+
const firstEnabledId = tabs.find((t) => !t.disabled)?.id ?? tabs[0]?.id;
|
|
661
|
+
const [internal, setInternal] = useState4(defaultSelectedId ?? firstEnabledId);
|
|
662
|
+
const selected = selectedId ?? internal;
|
|
663
|
+
const handleLinkClick = (item) => {
|
|
664
|
+
const id = item?.props.itemKey;
|
|
665
|
+
if (!id) return;
|
|
666
|
+
if (selectedId == null) setInternal(id);
|
|
667
|
+
onTabChange?.(id);
|
|
668
|
+
};
|
|
669
|
+
const active = tabs.find((t) => t.id === selected) ?? tabs[0];
|
|
670
|
+
return /* @__PURE__ */ jsxs5("div", { className, children: [
|
|
671
|
+
/* @__PURE__ */ jsx10(
|
|
672
|
+
Pivot,
|
|
673
|
+
{
|
|
674
|
+
selectedKey: selected,
|
|
675
|
+
onLinkClick: handleLinkClick,
|
|
676
|
+
linkFormat,
|
|
677
|
+
headersOnly: true,
|
|
678
|
+
children: tabs.map((t) => /* @__PURE__ */ jsx10(
|
|
679
|
+
PivotItem,
|
|
680
|
+
{
|
|
681
|
+
itemKey: t.id,
|
|
682
|
+
headerText: t.label,
|
|
683
|
+
itemIcon: t.iconName,
|
|
684
|
+
headerButtonProps: t.disabled ? { disabled: true } : void 0
|
|
685
|
+
},
|
|
686
|
+
t.id
|
|
687
|
+
))
|
|
688
|
+
}
|
|
689
|
+
),
|
|
690
|
+
/* @__PURE__ */ jsx10("div", { children: active?.content })
|
|
691
|
+
] });
|
|
692
|
+
};
|
|
693
|
+
|
|
694
|
+
// src/containers/CommandSurface.tsx
|
|
695
|
+
import { CommandBar as CommandBar2 } from "@fluentui/react";
|
|
696
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
697
|
+
var CommandSurface = ({ items, overflowItems, farItems, className }) => /* @__PURE__ */ jsx11("div", { className, children: /* @__PURE__ */ jsx11(CommandBar2, { items, overflowItems, farItems, styles: { root: { padding: 0 } } }) });
|
|
698
|
+
|
|
699
|
+
// src/containers/ActionBar.tsx
|
|
700
|
+
import { mergeStyles as mergeStyles4, DefaultButton, PrimaryButton, ActionButton } from "@fluentui/react";
|
|
701
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
702
|
+
function renderButton(b) {
|
|
703
|
+
const common = {
|
|
704
|
+
text: b.label,
|
|
705
|
+
disabled: b.disabled,
|
|
706
|
+
onClick: b.onClick,
|
|
707
|
+
iconProps: b.iconName ? { iconName: b.iconName } : void 0
|
|
708
|
+
};
|
|
709
|
+
if (b.appearance === "primary") return /* @__PURE__ */ jsx12(PrimaryButton, { ...common }, b.id);
|
|
710
|
+
if (b.appearance === "subtle") return /* @__PURE__ */ jsx12(ActionButton, { ...common }, b.id);
|
|
711
|
+
return /* @__PURE__ */ jsx12(DefaultButton, { ...common }, b.id);
|
|
712
|
+
}
|
|
713
|
+
var ActionBar = ({ buttons, alignment = "right", sticky = true, className }) => {
|
|
714
|
+
const justify = alignment === "left" ? "flex-start" : alignment === "center" ? "center" : "flex-end";
|
|
715
|
+
const visible = buttons.filter((b) => !b.hidden);
|
|
716
|
+
const left = visible.filter((b) => b.position === "left");
|
|
717
|
+
const right = visible.filter((b) => b.position !== "left");
|
|
718
|
+
const cls = mergeStyles4(
|
|
719
|
+
{
|
|
720
|
+
display: "flex",
|
|
721
|
+
alignItems: "center",
|
|
722
|
+
justifyContent: left.length ? "space-between" : justify,
|
|
723
|
+
gap: 8,
|
|
724
|
+
padding: "12px 24px",
|
|
725
|
+
borderTop: `1px solid ${colors.borderNeutral}`,
|
|
726
|
+
background: colors.surface,
|
|
727
|
+
...sticky ? { position: "sticky", bottom: 0, zIndex: 1 } : {}
|
|
728
|
+
},
|
|
729
|
+
className
|
|
730
|
+
);
|
|
731
|
+
return /* @__PURE__ */ jsxs6("div", { className: cls, children: [
|
|
732
|
+
left.length > 0 && /* @__PURE__ */ jsx12("div", { style: { display: "flex", gap: 8 }, children: left.map(renderButton) }),
|
|
733
|
+
/* @__PURE__ */ jsx12("div", { style: { display: "flex", gap: 8, justifyContent: justify }, children: right.map(renderButton) })
|
|
734
|
+
] });
|
|
735
|
+
};
|
|
736
|
+
|
|
737
|
+
// src/containers/Footer.tsx
|
|
738
|
+
import { mergeStyles as mergeStyles5 } from "@fluentui/react";
|
|
739
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
740
|
+
var Footer = ({ sticky = true, align = "right", className, children }) => {
|
|
741
|
+
const justify = align === "left" ? "flex-start" : align === "center" ? "center" : "flex-end";
|
|
742
|
+
const cls = mergeStyles5(
|
|
743
|
+
{
|
|
744
|
+
display: "flex",
|
|
745
|
+
alignItems: "center",
|
|
746
|
+
justifyContent: justify,
|
|
747
|
+
gap: 8,
|
|
748
|
+
padding: "12px 24px",
|
|
749
|
+
borderTop: `1px solid ${colors.borderNeutral}`,
|
|
750
|
+
background: colors.surface,
|
|
751
|
+
...sticky ? { position: "sticky", bottom: 0, zIndex: 1 } : {}
|
|
752
|
+
},
|
|
753
|
+
className
|
|
754
|
+
);
|
|
755
|
+
return /* @__PURE__ */ jsx13("div", { className: cls, children });
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
// src/overlays/FormDialogSurface.tsx
|
|
759
|
+
import { Modal, IconButton, mergeStyleSets as mergeStyleSets5 } from "@fluentui/react";
|
|
760
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
761
|
+
var FormDialogSurface = ({
|
|
762
|
+
isOpen,
|
|
763
|
+
onDismiss,
|
|
764
|
+
title,
|
|
765
|
+
subheader,
|
|
766
|
+
size,
|
|
767
|
+
width,
|
|
768
|
+
height,
|
|
769
|
+
isBlocking = true,
|
|
770
|
+
recordCounter,
|
|
771
|
+
footer,
|
|
772
|
+
className,
|
|
773
|
+
children
|
|
774
|
+
}) => {
|
|
775
|
+
const widthCss = dialogWidthCss({ width, size });
|
|
776
|
+
const heightCss = dialogHeightCss(height);
|
|
777
|
+
const styles = mergeStyleSets5({
|
|
778
|
+
header: {
|
|
779
|
+
display: "flex",
|
|
780
|
+
alignItems: "center",
|
|
781
|
+
justifyContent: "space-between",
|
|
782
|
+
gap: 12,
|
|
783
|
+
padding: "12px 20px",
|
|
784
|
+
borderBottom: `1px solid ${colors.borderNeutral}`
|
|
785
|
+
},
|
|
786
|
+
headerLeft: { display: "flex", flexDirection: "column", minWidth: 0 },
|
|
787
|
+
title: {
|
|
788
|
+
fontSize: typography.fontSize.lg,
|
|
789
|
+
fontWeight: typography.fontWeight.semibold,
|
|
790
|
+
fontFamily: typography.fontFamilySemibold,
|
|
791
|
+
color: colors.textPrimary
|
|
792
|
+
},
|
|
793
|
+
subheader: { fontSize: typography.fontSize.smPlus, color: colors.textSecondary, marginTop: 2 },
|
|
794
|
+
headerRight: { display: "flex", alignItems: "center", gap: 8 },
|
|
795
|
+
counter: { fontSize: typography.fontSize.smPlus, color: colors.textSecondary },
|
|
796
|
+
content: { flex: 1, minHeight: 0, overflow: "auto", padding: 20 },
|
|
797
|
+
footer: { borderTop: `1px solid ${colors.borderNeutral}`, padding: "12px 20px" }
|
|
798
|
+
});
|
|
799
|
+
const showHeader = Boolean(title) || Boolean(recordCounter) || Boolean(onDismiss);
|
|
800
|
+
return /* @__PURE__ */ jsxs7(
|
|
801
|
+
Modal,
|
|
802
|
+
{
|
|
803
|
+
isOpen,
|
|
804
|
+
onDismiss,
|
|
805
|
+
isBlocking,
|
|
806
|
+
className,
|
|
807
|
+
styles: {
|
|
808
|
+
main: {
|
|
809
|
+
maxWidth: "95vw",
|
|
810
|
+
width: widthCss,
|
|
811
|
+
height: heightCss,
|
|
812
|
+
maxHeight: "95vh",
|
|
813
|
+
display: "flex",
|
|
814
|
+
flexDirection: "column"
|
|
815
|
+
},
|
|
816
|
+
scrollableContent: {
|
|
817
|
+
overflow: "hidden",
|
|
818
|
+
display: "flex",
|
|
819
|
+
flexDirection: "column",
|
|
820
|
+
flex: 1,
|
|
821
|
+
minHeight: 0
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
children: [
|
|
825
|
+
showHeader && /* @__PURE__ */ jsxs7("div", { className: styles.header, children: [
|
|
826
|
+
/* @__PURE__ */ jsxs7("div", { className: styles.headerLeft, children: [
|
|
827
|
+
title && /* @__PURE__ */ jsx14("span", { className: styles.title, children: title }),
|
|
828
|
+
subheader && /* @__PURE__ */ jsx14("span", { className: styles.subheader, children: subheader })
|
|
829
|
+
] }),
|
|
830
|
+
/* @__PURE__ */ jsxs7("div", { className: styles.headerRight, children: [
|
|
831
|
+
recordCounter && /* @__PURE__ */ jsxs7("span", { className: styles.counter, children: [
|
|
832
|
+
recordCounter.current,
|
|
833
|
+
" of ",
|
|
834
|
+
recordCounter.total
|
|
835
|
+
] }),
|
|
836
|
+
onDismiss && /* @__PURE__ */ jsx14(
|
|
837
|
+
IconButton,
|
|
838
|
+
{
|
|
839
|
+
iconProps: { iconName: "Cancel" },
|
|
840
|
+
ariaLabel: "Close",
|
|
841
|
+
onClick: onDismiss,
|
|
842
|
+
styles: { root: { color: colors.textSecondary } }
|
|
843
|
+
}
|
|
844
|
+
)
|
|
845
|
+
] })
|
|
846
|
+
] }),
|
|
847
|
+
/* @__PURE__ */ jsx14("div", { className: styles.content, children }),
|
|
848
|
+
footer && /* @__PURE__ */ jsx14("div", { className: styles.footer, children: footer })
|
|
849
|
+
]
|
|
850
|
+
}
|
|
851
|
+
);
|
|
852
|
+
};
|
|
853
|
+
|
|
854
|
+
// src/overlays/ModalSurface.tsx
|
|
855
|
+
import { Modal as Modal2, mergeStyleSets as mergeStyleSets6 } from "@fluentui/react";
|
|
856
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
857
|
+
var ModalSurface = ({
|
|
858
|
+
isOpen,
|
|
859
|
+
onDismiss,
|
|
860
|
+
title,
|
|
861
|
+
size,
|
|
862
|
+
width,
|
|
863
|
+
isBlocking = true,
|
|
864
|
+
autoSize,
|
|
865
|
+
footer,
|
|
866
|
+
className,
|
|
867
|
+
children
|
|
868
|
+
}) => {
|
|
869
|
+
const main = autoSize ? { width: "auto", minWidth: MODAL_AUTOSIZE_MIN_WIDTH, maxWidth: "100%" } : { maxWidth: "95vw", width: `${dialogWidthPx({ width, size })}px` };
|
|
870
|
+
const styles = mergeStyleSets6({
|
|
871
|
+
title: {
|
|
872
|
+
fontSize: typography.fontSize.lg,
|
|
873
|
+
fontWeight: typography.fontWeight.semibold,
|
|
874
|
+
fontFamily: typography.fontFamilySemibold,
|
|
875
|
+
color: colors.textPrimary,
|
|
876
|
+
padding: "16px 20px 0"
|
|
877
|
+
},
|
|
878
|
+
content: { padding: 20 },
|
|
879
|
+
footer: {
|
|
880
|
+
borderTop: `1px solid ${colors.borderNeutral}`,
|
|
881
|
+
padding: "12px 20px",
|
|
882
|
+
display: "flex",
|
|
883
|
+
justifyContent: "flex-end",
|
|
884
|
+
gap: 8
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
return /* @__PURE__ */ jsxs8(Modal2, { isOpen, onDismiss, isBlocking, className, styles: { main }, children: [
|
|
888
|
+
title && /* @__PURE__ */ jsx15("div", { className: styles.title, children: title }),
|
|
889
|
+
/* @__PURE__ */ jsx15("div", { className: styles.content, children }),
|
|
890
|
+
footer && /* @__PURE__ */ jsx15("div", { className: styles.footer, children: footer })
|
|
891
|
+
] });
|
|
892
|
+
};
|
|
893
|
+
|
|
894
|
+
// src/overlays/PanelSurface.tsx
|
|
895
|
+
import { Panel, PanelType } from "@fluentui/react";
|
|
896
|
+
import { Fragment, jsx as jsx16 } from "react/jsx-runtime";
|
|
897
|
+
var PanelSurface = ({
|
|
898
|
+
isOpen,
|
|
899
|
+
onDismiss,
|
|
900
|
+
title,
|
|
901
|
+
panelType,
|
|
902
|
+
width,
|
|
903
|
+
hasCloseButton = true,
|
|
904
|
+
isLightDismiss = false,
|
|
905
|
+
isFooterAtBottom = true,
|
|
906
|
+
isNonModal = false,
|
|
907
|
+
footer,
|
|
908
|
+
children
|
|
909
|
+
}) => {
|
|
910
|
+
const kind = panelType ?? panelKindFromWidth(width);
|
|
911
|
+
const resolvedType = PanelType[kind];
|
|
912
|
+
const customWidth = kind === "custom" || kind === "customNear" ? `${panelCustomWidthPx(width)}px` : void 0;
|
|
913
|
+
return /* @__PURE__ */ jsx16(
|
|
914
|
+
Panel,
|
|
915
|
+
{
|
|
916
|
+
isOpen,
|
|
917
|
+
onDismiss,
|
|
918
|
+
headerText: title,
|
|
919
|
+
type: resolvedType,
|
|
920
|
+
customWidth,
|
|
921
|
+
hasCloseButton,
|
|
922
|
+
isLightDismiss,
|
|
923
|
+
isFooterAtBottom,
|
|
924
|
+
isBlocking: !isNonModal,
|
|
925
|
+
onRenderFooterContent: footer ? () => /* @__PURE__ */ jsx16(Fragment, { children: footer }) : void 0,
|
|
926
|
+
children: /* @__PURE__ */ jsx16("div", { style: { padding: "12px 0" }, children })
|
|
927
|
+
}
|
|
928
|
+
);
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
// src/overlays/CalloutSurface.tsx
|
|
932
|
+
import { Callout, DirectionalHint } from "@fluentui/react";
|
|
933
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
934
|
+
var CalloutSurface = ({
|
|
935
|
+
target,
|
|
936
|
+
isOpen = true,
|
|
937
|
+
onDismiss,
|
|
938
|
+
width,
|
|
939
|
+
directionalHint = "bottomLeftEdge",
|
|
940
|
+
isBeakVisible = true,
|
|
941
|
+
beakWidth = 16,
|
|
942
|
+
gapSpace = 0,
|
|
943
|
+
className,
|
|
944
|
+
children
|
|
945
|
+
}) => {
|
|
946
|
+
if (!isOpen) return null;
|
|
947
|
+
return /* @__PURE__ */ jsx17(
|
|
948
|
+
Callout,
|
|
949
|
+
{
|
|
950
|
+
target: target ?? void 0,
|
|
951
|
+
onDismiss,
|
|
952
|
+
directionalHint: DirectionalHint[directionalHint],
|
|
953
|
+
isBeakVisible,
|
|
954
|
+
beakWidth,
|
|
955
|
+
gapSpace,
|
|
956
|
+
className,
|
|
957
|
+
styles: { root: { width: calloutWidthPx(width), padding: 16 } },
|
|
958
|
+
children
|
|
959
|
+
}
|
|
960
|
+
);
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
// src/overlays/TooltipSurface.tsx
|
|
964
|
+
import { TooltipHost, DirectionalHint as DirectionalHint2, TooltipDelay } from "@fluentui/react";
|
|
965
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
966
|
+
var DELAY_MAP = {
|
|
967
|
+
zero: TooltipDelay.zero,
|
|
968
|
+
medium: TooltipDelay.medium,
|
|
969
|
+
long: TooltipDelay.long
|
|
970
|
+
};
|
|
971
|
+
var TooltipSurface = ({
|
|
972
|
+
content,
|
|
973
|
+
directionalHint = "bottomCenter",
|
|
974
|
+
delay = "medium",
|
|
975
|
+
children
|
|
976
|
+
}) => /* @__PURE__ */ jsx18(TooltipHost, { content, directionalHint: DirectionalHint2[directionalHint], delay: DELAY_MAP[delay], children });
|
|
977
|
+
|
|
978
|
+
// src/composites/MasterDetailSurface.tsx
|
|
979
|
+
import { mergeStyles as mergeStyles6 } from "@fluentui/react";
|
|
980
|
+
import { jsx as jsx19, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
981
|
+
var MasterDetailSurface = ({
|
|
982
|
+
master,
|
|
983
|
+
detail,
|
|
984
|
+
detailFallback,
|
|
985
|
+
splitRatio = 0.38,
|
|
986
|
+
collapseBelow = "md",
|
|
987
|
+
className
|
|
988
|
+
}) => {
|
|
989
|
+
const masterFr = Math.min(90, Math.max(10, Math.round(splitRatio * 100)));
|
|
990
|
+
const detailFr = 100 - masterFr;
|
|
991
|
+
const collapsePx = BREAKPOINTS[collapseBelow];
|
|
992
|
+
const rootCls = mergeStyles6(
|
|
993
|
+
{
|
|
994
|
+
display: "grid",
|
|
995
|
+
gridTemplateColumns: `${masterFr}fr ${detailFr}fr`,
|
|
996
|
+
minHeight: 0,
|
|
997
|
+
selectors: { [`@media (max-width: ${collapsePx}px)`]: { gridTemplateColumns: "1fr" } }
|
|
998
|
+
},
|
|
999
|
+
className
|
|
1000
|
+
);
|
|
1001
|
+
const masterCls = mergeStyles6({
|
|
1002
|
+
minWidth: 0,
|
|
1003
|
+
overflow: "auto",
|
|
1004
|
+
borderRight: `1px solid ${colors.borderNeutral}`,
|
|
1005
|
+
selectors: {
|
|
1006
|
+
[`@media (max-width: ${collapsePx}px)`]: {
|
|
1007
|
+
borderRight: "none",
|
|
1008
|
+
borderBottom: `1px solid ${colors.borderNeutral}`
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
const detailCls = mergeStyles6({ minWidth: 0, overflow: "auto" });
|
|
1013
|
+
return /* @__PURE__ */ jsxs9("div", { className: rootCls, children: [
|
|
1014
|
+
/* @__PURE__ */ jsx19("div", { className: masterCls, children: master }),
|
|
1015
|
+
/* @__PURE__ */ jsx19("div", { className: detailCls, children: detail ?? detailFallback })
|
|
1016
|
+
] });
|
|
1017
|
+
};
|
|
1018
|
+
|
|
1019
|
+
// src/composites/DashboardSurface.tsx
|
|
1020
|
+
import { mergeStyles as mergeStyles7 } from "@fluentui/react";
|
|
1021
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
1022
|
+
var DashboardSurface = ({ tiles, columns = 2, gap = 16, className }) => {
|
|
1023
|
+
const cls = mergeStyles7(
|
|
1024
|
+
{
|
|
1025
|
+
display: "grid",
|
|
1026
|
+
gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
|
|
1027
|
+
gap,
|
|
1028
|
+
alignItems: "start",
|
|
1029
|
+
selectors: {
|
|
1030
|
+
[`@media (max-width: ${CARD_REFLOW_WIDTH}px)`]: { gridTemplateColumns: "repeat(2, minmax(0, 1fr))" },
|
|
1031
|
+
[`@media (max-width: ${BREAKPOINTS.sm}px)`]: { gridTemplateColumns: "1fr" }
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
className
|
|
1035
|
+
);
|
|
1036
|
+
return /* @__PURE__ */ jsx20("div", { className: cls, children: tiles.map((tile, i) => /* @__PURE__ */ jsx20("div", { children: tile }, `tile-${i}`)) });
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
// src/adapters/fromFormDefinition.ts
|
|
1040
|
+
function fromFormDefinition(def) {
|
|
1041
|
+
const s = def.settings ?? {};
|
|
1042
|
+
switch (def.type) {
|
|
1043
|
+
case "dialog":
|
|
1044
|
+
return {
|
|
1045
|
+
kind: "dialog",
|
|
1046
|
+
widthPx: dialogWidthPx({ width: s.width }),
|
|
1047
|
+
heightCss: dialogHeightCss(s.height),
|
|
1048
|
+
title: def.name
|
|
1049
|
+
};
|
|
1050
|
+
case "panel": {
|
|
1051
|
+
const panelType = s.panelType ?? panelKindFromWidth(s.width);
|
|
1052
|
+
return {
|
|
1053
|
+
kind: "panel",
|
|
1054
|
+
panelType,
|
|
1055
|
+
customWidthPx: panelType === "custom" ? panelCustomWidthPx(s.width) : void 0,
|
|
1056
|
+
title: def.name
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
case "callout":
|
|
1060
|
+
return { kind: "callout", widthPx: calloutWidthPx(s.width), title: def.name };
|
|
1061
|
+
case "main":
|
|
1062
|
+
default:
|
|
1063
|
+
return { kind: "main" };
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
export {
|
|
1067
|
+
ActionBar,
|
|
1068
|
+
BREAKPOINTS,
|
|
1069
|
+
CALLOUT_DEFAULT_WIDTH,
|
|
1070
|
+
CARD_REFLOW_WIDTH,
|
|
1071
|
+
CalloutSurface,
|
|
1072
|
+
ColumnLayout,
|
|
1073
|
+
CommandSurface,
|
|
1074
|
+
DIALOG_SIZE_PX,
|
|
1075
|
+
DashboardSurface,
|
|
1076
|
+
FieldRow,
|
|
1077
|
+
Footer,
|
|
1078
|
+
FormDialogSurface,
|
|
1079
|
+
FormHeader,
|
|
1080
|
+
FormSurface,
|
|
1081
|
+
MODAL_AUTOSIZE_MIN_WIDTH,
|
|
1082
|
+
MasterDetailSurface,
|
|
1083
|
+
ModalSurface,
|
|
1084
|
+
PANEL_DEFAULT_WIDTH,
|
|
1085
|
+
PageSurface,
|
|
1086
|
+
PanelSurface,
|
|
1087
|
+
PivotSurface,
|
|
1088
|
+
Section,
|
|
1089
|
+
SectionCard,
|
|
1090
|
+
SectionHeader,
|
|
1091
|
+
TooltipSurface,
|
|
1092
|
+
TwoColumnLayout,
|
|
1093
|
+
calloutFormDefaults,
|
|
1094
|
+
calloutWidthPx,
|
|
1095
|
+
clampSpan,
|
|
1096
|
+
colors,
|
|
1097
|
+
createDynamicsTheme,
|
|
1098
|
+
densityScale,
|
|
1099
|
+
dialogHeightCss,
|
|
1100
|
+
dialogWidthCss,
|
|
1101
|
+
dialogWidthPx,
|
|
1102
|
+
fieldGridStyle,
|
|
1103
|
+
fieldRowStyle,
|
|
1104
|
+
fromFormDefinition,
|
|
1105
|
+
gridTemplateForColumns,
|
|
1106
|
+
layout,
|
|
1107
|
+
panelCustomWidthPx,
|
|
1108
|
+
panelKindFromWidth,
|
|
1109
|
+
radius,
|
|
1110
|
+
resolveBreakpoint,
|
|
1111
|
+
resolveResponsiveValue,
|
|
1112
|
+
scaleSpacing,
|
|
1113
|
+
sectionStackingStyle,
|
|
1114
|
+
spacing,
|
|
1115
|
+
typography,
|
|
1116
|
+
useContainerBreakpoint,
|
|
1117
|
+
useContainerSize,
|
|
1118
|
+
useContainerWidth,
|
|
1119
|
+
useMediaQuery,
|
|
1120
|
+
useResponsiveValue
|
|
1121
|
+
};
|
|
1122
|
+
//# sourceMappingURL=index.mjs.map
|