@jsenv/navi 0.6.1 → 0.7.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/jsenv_navi.js +248 -81
- package/index.js +5 -0
- package/package.json +1 -1
- package/src/components/action_execution/use_execute_action.js +3 -1
- package/src/components/callout/callout.js +2 -2
- package/src/components/field/button.jsx +4 -13
- package/src/components/field/form.jsx +2 -0
- package/src/components/layout/demos/demo_flex.html +506 -0
- package/src/components/layout/flex.jsx +154 -0
- package/src/components/layout/spacing.jsx +78 -67
- package/src/components/text/text.jsx +13 -0
package/dist/jsenv_navi.js
CHANGED
|
@@ -11735,7 +11735,7 @@ const openCallout = (
|
|
|
11735
11735
|
level = "warning",
|
|
11736
11736
|
onClose,
|
|
11737
11737
|
closeOnClickOutside = level === "info",
|
|
11738
|
-
|
|
11738
|
+
showErrorStack,
|
|
11739
11739
|
debug = false,
|
|
11740
11740
|
} = {},
|
|
11741
11741
|
) => {
|
|
@@ -11803,7 +11803,7 @@ const openCallout = (
|
|
|
11803
11803
|
if (Error.isError(newMessage)) {
|
|
11804
11804
|
const error = newMessage;
|
|
11805
11805
|
newMessage = error.message;
|
|
11806
|
-
if (
|
|
11806
|
+
if (showErrorStack && error.stack) {
|
|
11807
11807
|
newMessage += `<pre class="navi_callout_error_stack">${escapeHtml(String(error.stack))}</pre>`;
|
|
11808
11808
|
}
|
|
11809
11809
|
}
|
|
@@ -13766,6 +13766,7 @@ const useExecuteAction = (
|
|
|
13766
13766
|
elementRef,
|
|
13767
13767
|
{
|
|
13768
13768
|
errorEffect = "show_validation_message", // "show_validation_message" or "throw"
|
|
13769
|
+
errorMapping,
|
|
13769
13770
|
} = {},
|
|
13770
13771
|
) => {
|
|
13771
13772
|
// see https://medium.com/trabe/catching-asynchronous-errors-in-react-using-error-boundaries-5e8a5fd7b971
|
|
@@ -13783,7 +13784,8 @@ const useExecuteAction = (
|
|
|
13783
13784
|
const validationMessageTargetRef = useRef(null);
|
|
13784
13785
|
const addErrorMessage = (error) => {
|
|
13785
13786
|
const validationMessageTarget = validationMessageTargetRef.current;
|
|
13786
|
-
|
|
13787
|
+
const errorMapped = errorMapping ? errorMapping(error) : error;
|
|
13788
|
+
addCustomMessage(validationMessageTarget, "action_error", errorMapped, {
|
|
13787
13789
|
// This error should not prevent <form> submission
|
|
13788
13790
|
// so whenever user tries to submit the form the error is cleared
|
|
13789
13791
|
// (Hitting enter key, clicking on submit button, etc. would allow to re-submit the form in error state)
|
|
@@ -18594,74 +18596,84 @@ const parseStyleString = (styleString) => {
|
|
|
18594
18596
|
};
|
|
18595
18597
|
|
|
18596
18598
|
const consumeSpacingProps = props => {
|
|
18597
|
-
const consume = name => {
|
|
18598
|
-
if (Object.hasOwn(props, name)) {
|
|
18599
|
-
const value = props[name];
|
|
18600
|
-
delete props[name];
|
|
18601
|
-
return value;
|
|
18602
|
-
}
|
|
18603
|
-
return undefined;
|
|
18604
|
-
};
|
|
18605
|
-
const margin = consume("margin");
|
|
18606
|
-
const marginX = consume("marginX");
|
|
18607
|
-
const marginY = consume("marginY");
|
|
18608
|
-
const marginLeft = consume("marginLeft");
|
|
18609
|
-
const marginRight = consume("marginRight");
|
|
18610
|
-
const marginTop = consume("marginTop");
|
|
18611
|
-
const marginBottom = consume("marginBottom");
|
|
18612
18599
|
const style = {};
|
|
18613
|
-
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
18620
|
-
|
|
18621
|
-
|
|
18622
|
-
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
|
|
18640
|
-
|
|
18641
|
-
|
|
18642
|
-
|
|
18643
|
-
|
|
18644
|
-
|
|
18645
|
-
|
|
18646
|
-
|
|
18647
|
-
|
|
18648
|
-
|
|
18649
|
-
|
|
18650
|
-
|
|
18651
|
-
|
|
18652
|
-
|
|
18653
|
-
|
|
18654
|
-
|
|
18655
|
-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18600
|
+
{
|
|
18601
|
+
const margin = props.margin;
|
|
18602
|
+
const marginX = props.marginX;
|
|
18603
|
+
const marginY = props.marginY;
|
|
18604
|
+
const marginLeft = props.marginLeft;
|
|
18605
|
+
const marginRight = props.marginRight;
|
|
18606
|
+
const marginTop = props.marginTop;
|
|
18607
|
+
const marginBottom = props.marginBottom;
|
|
18608
|
+
delete props.margin;
|
|
18609
|
+
delete props.marginX;
|
|
18610
|
+
delete props.marginY;
|
|
18611
|
+
delete props.marginLeft;
|
|
18612
|
+
delete props.marginRight;
|
|
18613
|
+
delete props.marginTop;
|
|
18614
|
+
delete props.marginBottom;
|
|
18615
|
+
if (margin !== undefined) {
|
|
18616
|
+
style.margin = margin;
|
|
18617
|
+
}
|
|
18618
|
+
if (marginLeft !== undefined) {
|
|
18619
|
+
style.marginLeft = marginLeft;
|
|
18620
|
+
} else if (marginX !== undefined) {
|
|
18621
|
+
style.marginLeft = marginX;
|
|
18622
|
+
}
|
|
18623
|
+
if (marginRight !== undefined) {
|
|
18624
|
+
style.marginRight = marginRight;
|
|
18625
|
+
} else if (marginX !== undefined) {
|
|
18626
|
+
style.marginRight = marginX;
|
|
18627
|
+
}
|
|
18628
|
+
if (marginTop !== undefined) {
|
|
18629
|
+
style.marginTop = marginTop;
|
|
18630
|
+
} else if (marginY !== undefined) {
|
|
18631
|
+
style.marginTop = marginY;
|
|
18632
|
+
}
|
|
18633
|
+
if (marginBottom !== undefined) {
|
|
18634
|
+
style.marginBottom = marginBottom;
|
|
18635
|
+
} else if (marginY !== undefined) {
|
|
18636
|
+
style.marginBottom = marginY;
|
|
18637
|
+
}
|
|
18638
|
+
}
|
|
18639
|
+
{
|
|
18640
|
+
const padding = props.padding;
|
|
18641
|
+
const paddingX = props.paddingX;
|
|
18642
|
+
const paddingY = props.paddingY;
|
|
18643
|
+
const paddingLeft = props.paddingLeft;
|
|
18644
|
+
const paddingRight = props.paddingRight;
|
|
18645
|
+
const paddingTop = props.paddingTop;
|
|
18646
|
+
const paddingBottom = props.paddingBottom;
|
|
18647
|
+
delete props.padding;
|
|
18648
|
+
delete props.paddingX;
|
|
18649
|
+
delete props.paddingY;
|
|
18650
|
+
delete props.paddingLeft;
|
|
18651
|
+
delete props.paddingRight;
|
|
18652
|
+
delete props.paddingTop;
|
|
18653
|
+
delete props.paddingBottom;
|
|
18654
|
+
if (padding !== undefined) {
|
|
18655
|
+
style.padding = padding;
|
|
18656
|
+
}
|
|
18657
|
+
if (paddingLeft !== undefined) {
|
|
18658
|
+
style.paddingLeft = paddingLeft;
|
|
18659
|
+
} else if (paddingX !== undefined) {
|
|
18660
|
+
style.paddingLeft = paddingX;
|
|
18661
|
+
}
|
|
18662
|
+
if (paddingRight !== undefined) {
|
|
18663
|
+
style.paddingRight = paddingRight;
|
|
18664
|
+
} else if (paddingX !== undefined) {
|
|
18665
|
+
style.paddingRight = paddingX;
|
|
18666
|
+
}
|
|
18667
|
+
if (paddingTop !== undefined) {
|
|
18668
|
+
style.paddingTop = paddingTop;
|
|
18669
|
+
} else if (paddingY !== undefined) {
|
|
18670
|
+
style.paddingTop = paddingY;
|
|
18671
|
+
}
|
|
18672
|
+
if (paddingBottom !== undefined) {
|
|
18673
|
+
style.paddingBottom = paddingBottom;
|
|
18674
|
+
} else if (paddingY !== undefined) {
|
|
18675
|
+
style.paddingBottom = paddingY;
|
|
18676
|
+
}
|
|
18665
18677
|
}
|
|
18666
18678
|
return style;
|
|
18667
18679
|
};
|
|
@@ -21352,6 +21364,153 @@ const Editable = forwardRef((props, ref) => {
|
|
|
21352
21364
|
});
|
|
21353
21365
|
});
|
|
21354
21366
|
|
|
21367
|
+
installImportMetaCss(import.meta);import.meta.css = /* css */`
|
|
21368
|
+
.navi_flex_row {
|
|
21369
|
+
display: flex;
|
|
21370
|
+
flex-direction: row;
|
|
21371
|
+
align-items: center;
|
|
21372
|
+
gap: 0;
|
|
21373
|
+
}
|
|
21374
|
+
|
|
21375
|
+
.navi_flex_column {
|
|
21376
|
+
display: flex;
|
|
21377
|
+
flex-direction: column;
|
|
21378
|
+
align-items: center;
|
|
21379
|
+
gap: 0;
|
|
21380
|
+
}
|
|
21381
|
+
|
|
21382
|
+
.navi_flex_item {
|
|
21383
|
+
flex-shrink: 0;
|
|
21384
|
+
}
|
|
21385
|
+
`;
|
|
21386
|
+
const FlexDirectionContext = createContext();
|
|
21387
|
+
const FlexRow = ({
|
|
21388
|
+
alignY,
|
|
21389
|
+
gap,
|
|
21390
|
+
style,
|
|
21391
|
+
children,
|
|
21392
|
+
...rest
|
|
21393
|
+
}) => {
|
|
21394
|
+
const innerStyle = withPropsStyle({
|
|
21395
|
+
alignItems: alignY,
|
|
21396
|
+
gap,
|
|
21397
|
+
...consumeSpacingProps(rest)
|
|
21398
|
+
}, style);
|
|
21399
|
+
return jsx("div", {
|
|
21400
|
+
...rest,
|
|
21401
|
+
className: "navi_flex_row",
|
|
21402
|
+
style: innerStyle,
|
|
21403
|
+
children: jsx(FlexDirectionContext.Provider, {
|
|
21404
|
+
value: "row",
|
|
21405
|
+
children: children
|
|
21406
|
+
})
|
|
21407
|
+
});
|
|
21408
|
+
};
|
|
21409
|
+
const FlexColumn = ({
|
|
21410
|
+
alignX,
|
|
21411
|
+
gap,
|
|
21412
|
+
style,
|
|
21413
|
+
children,
|
|
21414
|
+
...rest
|
|
21415
|
+
}) => {
|
|
21416
|
+
const innerStyle = withPropsStyle({
|
|
21417
|
+
alignItems: alignX,
|
|
21418
|
+
gap,
|
|
21419
|
+
...consumeSpacingProps(rest)
|
|
21420
|
+
}, style);
|
|
21421
|
+
return jsx("div", {
|
|
21422
|
+
...rest,
|
|
21423
|
+
className: "navi_flex_column",
|
|
21424
|
+
style: innerStyle,
|
|
21425
|
+
children: jsx(FlexDirectionContext.Provider, {
|
|
21426
|
+
value: "column",
|
|
21427
|
+
children: children
|
|
21428
|
+
})
|
|
21429
|
+
});
|
|
21430
|
+
};
|
|
21431
|
+
const useConsumAlignProps = props => {
|
|
21432
|
+
const flexDirection = useContext(FlexDirectionContext);
|
|
21433
|
+
const alignX = props.alignX;
|
|
21434
|
+
const alignY = props.alignY;
|
|
21435
|
+
delete props.alignX;
|
|
21436
|
+
delete props.alignY;
|
|
21437
|
+
const style = {};
|
|
21438
|
+
if (flexDirection === "row") {
|
|
21439
|
+
// In row direction: alignX controls justify-content, alignY controls align-self
|
|
21440
|
+
// Default alignY is "center" from CSS, so only set alignSelf when different
|
|
21441
|
+
if (alignY !== undefined && alignY !== "center") {
|
|
21442
|
+
style.alignSelf = alignY;
|
|
21443
|
+
}
|
|
21444
|
+
// For row, alignX uses auto margins for positioning
|
|
21445
|
+
// NOTE: Auto margins only work effectively for positioning individual items.
|
|
21446
|
+
// When multiple adjacent items have the same auto margin alignment (e.g., alignX="end"),
|
|
21447
|
+
// only the first item will be positioned as expected because subsequent items
|
|
21448
|
+
// will be positioned relative to the previous item's margins, not the container edge.
|
|
21449
|
+
if (alignX !== undefined) {
|
|
21450
|
+
if (alignX === "start") {
|
|
21451
|
+
style.marginRight = "auto";
|
|
21452
|
+
} else if (alignX === "end") {
|
|
21453
|
+
style.marginLeft = "auto";
|
|
21454
|
+
} else if (alignX === "center") {
|
|
21455
|
+
style.marginLeft = "auto";
|
|
21456
|
+
style.marginRight = "auto";
|
|
21457
|
+
}
|
|
21458
|
+
}
|
|
21459
|
+
} else if (flexDirection === "column") {
|
|
21460
|
+
// In column direction: alignX controls align-self, alignY uses auto margins
|
|
21461
|
+
// Default alignX is "center" from CSS, so only set alignSelf when different
|
|
21462
|
+
if (alignX !== undefined && alignX !== "center") {
|
|
21463
|
+
style.alignSelf = alignX;
|
|
21464
|
+
}
|
|
21465
|
+
// For column, alignY uses auto margins for positioning
|
|
21466
|
+
// NOTE: Same auto margin limitation applies - multiple adjacent items with
|
|
21467
|
+
// the same alignY won't all position relative to container edges.
|
|
21468
|
+
if (alignY !== undefined) {
|
|
21469
|
+
if (alignY === "start") {
|
|
21470
|
+
style.marginBottom = "auto";
|
|
21471
|
+
} else if (alignY === "end") {
|
|
21472
|
+
style.marginTop = "auto";
|
|
21473
|
+
} else if (alignY === "center") {
|
|
21474
|
+
style.marginTop = "auto";
|
|
21475
|
+
style.marginBottom = "auto";
|
|
21476
|
+
}
|
|
21477
|
+
}
|
|
21478
|
+
}
|
|
21479
|
+
return style;
|
|
21480
|
+
};
|
|
21481
|
+
const FlexItem = ({
|
|
21482
|
+
alignX,
|
|
21483
|
+
alignY,
|
|
21484
|
+
grow,
|
|
21485
|
+
shrink,
|
|
21486
|
+
className,
|
|
21487
|
+
style,
|
|
21488
|
+
children,
|
|
21489
|
+
...rest
|
|
21490
|
+
}) => {
|
|
21491
|
+
const flexDirection = useContext(FlexDirectionContext);
|
|
21492
|
+
if (!flexDirection) {
|
|
21493
|
+
console.warn("FlexItem must be used within a FlexRow or FlexColumn component.");
|
|
21494
|
+
}
|
|
21495
|
+
const innerClassName = withPropsClassName("navi_flex_item", className);
|
|
21496
|
+
const alignStyle = useConsumAlignProps({
|
|
21497
|
+
alignX,
|
|
21498
|
+
alignY
|
|
21499
|
+
});
|
|
21500
|
+
const innerStyle = withPropsStyle({
|
|
21501
|
+
flexGrow: grow ? 1 : undefined,
|
|
21502
|
+
flexShrink: shrink ? 1 : undefined,
|
|
21503
|
+
...consumeSpacingProps(rest),
|
|
21504
|
+
...alignStyle
|
|
21505
|
+
}, style);
|
|
21506
|
+
return jsx("div", {
|
|
21507
|
+
...rest,
|
|
21508
|
+
className: innerClassName,
|
|
21509
|
+
style: innerStyle,
|
|
21510
|
+
children: children
|
|
21511
|
+
});
|
|
21512
|
+
};
|
|
21513
|
+
|
|
21355
21514
|
const useFormEvents = (
|
|
21356
21515
|
elementRef,
|
|
21357
21516
|
{
|
|
@@ -21573,7 +21732,8 @@ const ButtonBasic = forwardRef((props, ref) => {
|
|
|
21573
21732
|
autoFocus,
|
|
21574
21733
|
// visual
|
|
21575
21734
|
appearance = "navi",
|
|
21576
|
-
alignX
|
|
21735
|
+
alignX,
|
|
21736
|
+
alignY,
|
|
21577
21737
|
discrete,
|
|
21578
21738
|
className,
|
|
21579
21739
|
style,
|
|
@@ -21599,13 +21759,9 @@ const ButtonBasic = forwardRef((props, ref) => {
|
|
|
21599
21759
|
const innerClassName = withPropsClassName(appearance === "navi" ? "navi_button" : undefined, className);
|
|
21600
21760
|
const innerStyle = withPropsStyle({
|
|
21601
21761
|
...consumeSpacingProps(rest),
|
|
21602
|
-
...(
|
|
21603
|
-
|
|
21604
|
-
|
|
21605
|
-
marginRight: "auto"
|
|
21606
|
-
} : {
|
|
21607
|
-
alignSelf: "end",
|
|
21608
|
-
marginRight: "auto"
|
|
21762
|
+
...useConsumAlignProps({
|
|
21763
|
+
alignX,
|
|
21764
|
+
alignY
|
|
21609
21765
|
})
|
|
21610
21766
|
}, style);
|
|
21611
21767
|
return jsx("button", {
|
|
@@ -22171,6 +22327,7 @@ const FormWithAction = forwardRef((props, ref) => {
|
|
|
22171
22327
|
method,
|
|
22172
22328
|
actionErrorEffect = "show_validation_message",
|
|
22173
22329
|
// "show_validation_message" or "throw"
|
|
22330
|
+
errorMapping,
|
|
22174
22331
|
onActionPrevented,
|
|
22175
22332
|
onActionStart,
|
|
22176
22333
|
onActionAbort,
|
|
@@ -22184,7 +22341,8 @@ const FormWithAction = forwardRef((props, ref) => {
|
|
|
22184
22341
|
useImperativeHandle(ref, () => innerRef.current);
|
|
22185
22342
|
const [actionBoundToUIState] = useActionBoundToOneParam(action, uiState);
|
|
22186
22343
|
const executeAction = useExecuteAction(innerRef, {
|
|
22187
|
-
errorEffect: actionErrorEffect
|
|
22344
|
+
errorEffect: actionErrorEffect,
|
|
22345
|
+
errorMapping
|
|
22188
22346
|
});
|
|
22189
22347
|
const {
|
|
22190
22348
|
actionPending,
|
|
@@ -28053,6 +28211,7 @@ const Text = ({
|
|
|
28053
28211
|
italic,
|
|
28054
28212
|
underline,
|
|
28055
28213
|
style,
|
|
28214
|
+
alignX,
|
|
28056
28215
|
...rest
|
|
28057
28216
|
}) => {
|
|
28058
28217
|
const innerStyle = withPropsStyle({
|
|
@@ -28060,7 +28219,15 @@ const Text = ({
|
|
|
28060
28219
|
fontWeight: bold ? "bold" : undefined,
|
|
28061
28220
|
fontStyle: italic ? "italic" : undefined,
|
|
28062
28221
|
textDecoration: underline ? "underline" : undefined,
|
|
28063
|
-
...consumeSpacingProps(rest)
|
|
28222
|
+
...consumeSpacingProps(rest),
|
|
28223
|
+
...(alignX === "start" ? {} : alignX === "center" ? {
|
|
28224
|
+
alignSelf: "center",
|
|
28225
|
+
marginLeft: "auto",
|
|
28226
|
+
marginRight: "auto"
|
|
28227
|
+
} : {
|
|
28228
|
+
alignSelf: "end",
|
|
28229
|
+
marginLeft: "auto"
|
|
28230
|
+
})
|
|
28064
28231
|
}, style);
|
|
28065
28232
|
return jsx("span", {
|
|
28066
28233
|
...rest,
|
|
@@ -28203,4 +28370,4 @@ const useDependenciesDiff = (inputs) => {
|
|
|
28203
28370
|
return diffRef.current;
|
|
28204
28371
|
};
|
|
28205
28372
|
|
|
28206
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Button, Checkbox, CheckboxList, Col, Colgroup, Details, Editable, ErrorBoundaryContext, FontSizedSvg, Form, Icon, IconAndText, Input, Label, Link, LinkWithIcon, Overflow, Radio, RadioList, Route, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, Select, SelectionContext, Spacing, SummaryMarker, Tab, TabList, Table, TableCell, Tbody, Text, TextAndCount, Thead, Tr, UITransition, actionIntegratedVia, addCustomMessage, createAction, createSelectionKeyboardShortcuts, createUniqueValueConstraint, defineRoutes, enableDebugActions, enableDebugOnDocumentLoading, goBack, goForward, goTo, isCellSelected, isColumnSelected, isRowSelected, openCallout, rawUrlPart, reload, removeCustomMessage, rerunActions, resource, setBaseUrl, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useCellsAndColumns, useDependenciesDiff, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, valueInLocalStorage };
|
|
28373
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Button, Checkbox, CheckboxList, Col, Colgroup, Details, Editable, ErrorBoundaryContext, FlexColumn, FlexItem, FlexRow, FontSizedSvg, Form, Icon, IconAndText, Input, Label, Link, LinkWithIcon, Overflow, Radio, RadioList, Route, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, Select, SelectionContext, Spacing, SummaryMarker, Tab, TabList, Table, TableCell, Tbody, Text, TextAndCount, Thead, Tr, UITransition, actionIntegratedVia, addCustomMessage, createAction, createSelectionKeyboardShortcuts, createUniqueValueConstraint, defineRoutes, enableDebugActions, enableDebugOnDocumentLoading, goBack, goForward, goTo, isCellSelected, isColumnSelected, isRowSelected, openCallout, rawUrlPart, reload, removeCustomMessage, rerunActions, resource, setBaseUrl, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useCellsAndColumns, useDependenciesDiff, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, valueInLocalStorage };
|
package/index.js
CHANGED
|
@@ -93,6 +93,11 @@ export { TextAndCount } from "./src/components/text/text_and_count.jsx";
|
|
|
93
93
|
// Callout, dialogs, ...
|
|
94
94
|
export { openCallout } from "./src/components/callout/callout.js";
|
|
95
95
|
// Layout
|
|
96
|
+
export {
|
|
97
|
+
FlexColumn,
|
|
98
|
+
FlexItem,
|
|
99
|
+
FlexRow,
|
|
100
|
+
} from "./src/components/layout/flex.jsx";
|
|
96
101
|
export { Spacing } from "./src/components/layout/spacing.jsx";
|
|
97
102
|
|
|
98
103
|
// Validation
|
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@ export const useExecuteAction = (
|
|
|
11
11
|
elementRef,
|
|
12
12
|
{
|
|
13
13
|
errorEffect = "show_validation_message", // "show_validation_message" or "throw"
|
|
14
|
+
errorMapping,
|
|
14
15
|
} = {},
|
|
15
16
|
) => {
|
|
16
17
|
// see https://medium.com/trabe/catching-asynchronous-errors-in-react-using-error-boundaries-5e8a5fd7b971
|
|
@@ -28,7 +29,8 @@ export const useExecuteAction = (
|
|
|
28
29
|
const validationMessageTargetRef = useRef(null);
|
|
29
30
|
const addErrorMessage = (error) => {
|
|
30
31
|
const validationMessageTarget = validationMessageTargetRef.current;
|
|
31
|
-
|
|
32
|
+
const errorMapped = errorMapping ? errorMapping(error) : error;
|
|
33
|
+
addCustomMessage(validationMessageTarget, "action_error", errorMapped, {
|
|
32
34
|
// This error should not prevent <form> submission
|
|
33
35
|
// so whenever user tries to submit the form the error is cleared
|
|
34
36
|
// (Hitting enter key, clicking on submit button, etc. would allow to re-submit the form in error state)
|
|
@@ -48,7 +48,7 @@ export const openCallout = (
|
|
|
48
48
|
level = "warning",
|
|
49
49
|
onClose,
|
|
50
50
|
closeOnClickOutside = level === "info",
|
|
51
|
-
|
|
51
|
+
showErrorStack,
|
|
52
52
|
debug = false,
|
|
53
53
|
} = {},
|
|
54
54
|
) => {
|
|
@@ -116,7 +116,7 @@ export const openCallout = (
|
|
|
116
116
|
if (Error.isError(newMessage)) {
|
|
117
117
|
const error = newMessage;
|
|
118
118
|
newMessage = error.message;
|
|
119
|
-
if (
|
|
119
|
+
if (showErrorStack && error.stack) {
|
|
120
120
|
newMessage += `<pre class="navi_callout_error_stack">${escapeHtml(String(error.stack))}</pre>`;
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -14,6 +14,7 @@ import { FormActionContext } from "../action_execution/form_context.js";
|
|
|
14
14
|
import { renderActionableComponent } from "../action_execution/render_actionable_component.jsx";
|
|
15
15
|
import { useAction } from "../action_execution/use_action.js";
|
|
16
16
|
import { useExecuteAction } from "../action_execution/use_execute_action.js";
|
|
17
|
+
import { useConsumAlignProps } from "../layout/flex.jsx";
|
|
17
18
|
import { consumeSpacingProps } from "../layout/spacing.jsx";
|
|
18
19
|
import { LoaderBackground } from "../loader/loader_background.jsx";
|
|
19
20
|
import { withPropsClassName } from "../props_composition/with_props_class_name.js";
|
|
@@ -211,7 +212,8 @@ const ButtonBasic = forwardRef((props, ref) => {
|
|
|
211
212
|
|
|
212
213
|
// visual
|
|
213
214
|
appearance = "navi",
|
|
214
|
-
alignX
|
|
215
|
+
alignX,
|
|
216
|
+
alignY,
|
|
215
217
|
discrete,
|
|
216
218
|
className,
|
|
217
219
|
style,
|
|
@@ -243,18 +245,7 @@ const ButtonBasic = forwardRef((props, ref) => {
|
|
|
243
245
|
const innerStyle = withPropsStyle(
|
|
244
246
|
{
|
|
245
247
|
...consumeSpacingProps(rest),
|
|
246
|
-
...(alignX
|
|
247
|
-
? {}
|
|
248
|
-
: alignX === "center"
|
|
249
|
-
? {
|
|
250
|
-
alignSelf: "center",
|
|
251
|
-
marginLeft: "auto",
|
|
252
|
-
marginRight: "auto",
|
|
253
|
-
}
|
|
254
|
-
: {
|
|
255
|
-
alignSelf: "end",
|
|
256
|
-
marginRight: "auto",
|
|
257
|
-
}),
|
|
248
|
+
...useConsumAlignProps({ alignX, alignY }),
|
|
258
249
|
},
|
|
259
250
|
style,
|
|
260
251
|
);
|
|
@@ -121,6 +121,7 @@ const FormWithAction = forwardRef((props, ref) => {
|
|
|
121
121
|
action,
|
|
122
122
|
method,
|
|
123
123
|
actionErrorEffect = "show_validation_message", // "show_validation_message" or "throw"
|
|
124
|
+
errorMapping,
|
|
124
125
|
onActionPrevented,
|
|
125
126
|
onActionStart,
|
|
126
127
|
onActionAbort,
|
|
@@ -135,6 +136,7 @@ const FormWithAction = forwardRef((props, ref) => {
|
|
|
135
136
|
const [actionBoundToUIState] = useActionBoundToOneParam(action, uiState);
|
|
136
137
|
const executeAction = useExecuteAction(innerRef, {
|
|
137
138
|
errorEffect: actionErrorEffect,
|
|
139
|
+
errorMapping,
|
|
138
140
|
});
|
|
139
141
|
const { actionPending, actionRequester: formActionRequester } =
|
|
140
142
|
useRequestedActionStatus(innerRef);
|