@olenbetong/appframe-ds 0.4.0 → 0.5.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/CHANGELOG.md +16 -0
- package/package.json +10 -10
- package/scripts/copyAssets.mjs +30 -0
- package/src/AfLookup/Combobox.tsx +16 -1
- package/src/AfLookup/Lookup.tsx +37 -6
- package/src/index.ts +3 -0
- package/src/layout/AppLayoutDesktop.tsx +3 -0
- package/src/layout/AppLayoutMobile.tsx +3 -0
- package/src/layout/AppMenu.css +1 -0
- package/src/layout/PageContainer.tsx +6 -0
- package/src/layout/index.tsx +5 -0
- package/src/list/ItemList.css +30 -0
- package/src/list/ItemList.tsx +52 -0
- package/src/list/ItemListItem.tsx +41 -0
- package/src/list/ItemListItemText.tsx +23 -0
- package/src/list/index.ts +3 -0
- package/src/page/Page.css +45 -0
- package/src/page/Page.tsx +70 -0
- package/src/page/PageBlock.css +59 -0
- package/src/page/PageBlock.tsx +78 -0
- package/src/page/PageHeader.css +148 -0
- package/src/page/PageHeader.tsx +184 -0
- package/src/page/index.ts +3 -0
- package/src/paper/Paper.css +35 -0
- package/src/paper/Paper.tsx +50 -0
- package/src/paper/index.ts +1 -0
- package/es/AfLookup/BoundLookup.d.ts +0 -10
- package/es/AfLookup/BoundLookup.js +0 -16
- package/es/AfLookup/Combobox.css +0 -78
- package/es/AfLookup/Combobox.d.ts +0 -31
- package/es/AfLookup/Combobox.js +0 -71
- package/es/AfLookup/Lookup.css +0 -125
- package/es/AfLookup/Lookup.d.ts +0 -35
- package/es/AfLookup/Lookup.js +0 -42
- package/es/AfLookup/LookupEdit.d.ts +0 -21
- package/es/AfLookup/LookupEdit.js +0 -49
- package/es/AfLookup/LookupGrid.css +0 -57
- package/es/AfLookup/LookupGrid.d.ts +0 -13
- package/es/AfLookup/LookupGrid.js +0 -27
- package/es/AfLookup/index.d.ts +0 -5
- package/es/AfLookup/index.js +0 -5
- package/es/binding/BoundCheckbox.d.ts +0 -9
- package/es/binding/BoundCheckbox.js +0 -13
- package/es/binding/BoundDatePicker.d.ts +0 -7
- package/es/binding/BoundDatePicker.js +0 -12
- package/es/binding/BoundDateTimePicker.d.ts +0 -7
- package/es/binding/BoundDateTimePicker.js +0 -14
- package/es/binding/BoundInput.d.ts +0 -6
- package/es/binding/BoundInput.js +0 -12
- package/es/binding/BoundNumericTextField.d.ts +0 -20
- package/es/binding/BoundNumericTextField.js +0 -58
- package/es/binding/BoundSelect.d.ts +0 -9
- package/es/binding/BoundSelect.js +0 -13
- package/es/binding/BoundSwitch.d.ts +0 -9
- package/es/binding/BoundSwitch.js +0 -13
- package/es/binding/BoundTextField.d.ts +0 -7
- package/es/binding/BoundTextField.js +0 -22
- package/es/binding/CancelButton.d.ts +0 -3
- package/es/binding/CancelButton.js +0 -14
- package/es/binding/CancelIconButton.d.ts +0 -2
- package/es/binding/CancelIconButton.js +0 -15
- package/es/binding/DataEditToolbar.d.ts +0 -13
- package/es/binding/DataEditToolbar.js +0 -28
- package/es/binding/DataObjectSelect.d.ts +0 -50
- package/es/binding/DataObjectSelect.js +0 -26
- package/es/binding/DeleteButton.d.ts +0 -8
- package/es/binding/DeleteButton.js +0 -14
- package/es/binding/DeleteIconButton.d.ts +0 -10
- package/es/binding/DeleteIconButton.js +0 -15
- package/es/binding/RefreshButton.d.ts +0 -3
- package/es/binding/RefreshButton.js +0 -14
- package/es/binding/RefreshIconButton.d.ts +0 -2
- package/es/binding/RefreshIconButton.js +0 -16
- package/es/binding/RefreshRowIconButton.d.ts +0 -7
- package/es/binding/RefreshRowIconButton.js +0 -15
- package/es/binding/SaveButton.d.ts +0 -3
- package/es/binding/SaveButton.js +0 -14
- package/es/binding/SaveIconButton.d.ts +0 -2
- package/es/binding/SaveIconButton.js +0 -15
- package/es/binding/index.d.ts +0 -19
- package/es/binding/index.js +0 -19
- package/es/index.d.ts +0 -3
- package/es/index.js +0 -3
- package/es/layout/AppLayoutDesktop.css +0 -65
- package/es/layout/AppLayoutDesktop.d.ts +0 -3
- package/es/layout/AppLayoutDesktop.js +0 -19
- package/es/layout/AppLayoutMobile.css +0 -75
- package/es/layout/AppLayoutMobile.d.ts +0 -3
- package/es/layout/AppLayoutMobile.js +0 -18
- package/es/layout/AppMenu.css +0 -67
- package/es/layout/AppMenu.d.ts +0 -8
- package/es/layout/AppMenu.js +0 -36
- package/es/layout/AppMenuItem.css +0 -97
- package/es/layout/AppMenuItem.d.ts +0 -50
- package/es/layout/AppMenuItem.js +0 -14
- package/es/layout/AppMenuSubheader.css +0 -18
- package/es/layout/AppMenuSubheader.d.ts +0 -4
- package/es/layout/AppMenuSubheader.js +0 -6
- package/es/layout/ErrorBoundary.css +0 -101
- package/es/layout/ErrorBoundary.d.ts +0 -30
- package/es/layout/ErrorBoundary.js +0 -81
- package/es/layout/PageContainer.css +0 -29
- package/es/layout/PageContainer.d.ts +0 -7
- package/es/layout/PageContainer.js +0 -6
- package/es/layout/PartnerToggle.d.ts +0 -5
- package/es/layout/PartnerToggle.js +0 -9
- package/es/layout/constants.d.ts +0 -2
- package/es/layout/constants.js +0 -2
- package/es/layout/index.css +0 -65
- package/es/layout/index.d.ts +0 -33
- package/es/layout/index.js +0 -31
- package/tsconfig.build.tsbuildinfo +0 -1
package/es/AfLookup/Combobox.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "./Combobox.css";
|
|
3
|
-
import { Button, Textfield } from "@digdir/designsystemet-react";
|
|
4
|
-
import { getLocalizedString } from "@olenbetong/appframe-core";
|
|
5
|
-
import { useComboboxData } from "@olenbetong/appframe-react";
|
|
6
|
-
import clsx from "clsx";
|
|
7
|
-
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
8
|
-
import { VariableSizeList as VirtualList } from "react-window";
|
|
9
|
-
import { LookupGrid } from "./LookupGrid.js";
|
|
10
|
-
export function Combobox(props) {
|
|
11
|
-
let { nullable, dataObject, isItemSelected, uniqueIdField = "PrimKey", onChange, onClose } = props;
|
|
12
|
-
let isGrid = props.variant === "grid";
|
|
13
|
-
let columns = isGrid ? props.columns : undefined;
|
|
14
|
-
let listRef = useRef(null);
|
|
15
|
-
let [isDesktop, setIsDesktop] = useState(() => typeof window !== "undefined" && window.matchMedia("(width >= 768px) and (pointer: fine)").matches);
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
let mq = window.matchMedia("(width >= 768px) and (pointer: fine)");
|
|
18
|
-
let handler = (e) => setIsDesktop(e.matches);
|
|
19
|
-
mq.addEventListener("change", handler);
|
|
20
|
-
return () => mq.removeEventListener("change", handler);
|
|
21
|
-
}, []);
|
|
22
|
-
let { id, data, loading, inputValue, setInputValue, currentIndex, currentColumn, getItemId, handleSelectItem, handleKeyDown, } = useComboboxData({
|
|
23
|
-
dataObject,
|
|
24
|
-
uniqueIdField,
|
|
25
|
-
columnCount: columns?.length ?? 1,
|
|
26
|
-
onChange,
|
|
27
|
-
});
|
|
28
|
-
let wrapperRef = useRef(null);
|
|
29
|
-
let [height, setHeight] = useState(0);
|
|
30
|
-
useLayoutEffect(() => {
|
|
31
|
-
if (!wrapperRef.current)
|
|
32
|
-
return;
|
|
33
|
-
let resizeObserver = new ResizeObserver(() => {
|
|
34
|
-
let newHeight = wrapperRef.current.offsetHeight;
|
|
35
|
-
if (newHeight > 0)
|
|
36
|
-
setHeight(newHeight);
|
|
37
|
-
});
|
|
38
|
-
resizeObserver.observe(wrapperRef.current);
|
|
39
|
-
return () => resizeObserver.disconnect();
|
|
40
|
-
}, []);
|
|
41
|
-
let sizeMap = useRef(new Map());
|
|
42
|
-
let getItemSize = (index) => sizeMap.current.get(index) ?? 56;
|
|
43
|
-
let setSize = useCallback((index, size) => {
|
|
44
|
-
if (sizeMap.current.get(index) !== size) {
|
|
45
|
-
sizeMap.current.set(index, size);
|
|
46
|
-
// listRef will not be set on the initial render, so delay resetting
|
|
47
|
-
setTimeout(() => listRef.current?.resetAfterIndex(index, true));
|
|
48
|
-
}
|
|
49
|
-
}, []);
|
|
50
|
-
let Row = ({ index, style: { height, ...style } }) => {
|
|
51
|
-
let rowRef = useRef(null);
|
|
52
|
-
useLayoutEffect(() => {
|
|
53
|
-
if (!rowRef.current)
|
|
54
|
-
return;
|
|
55
|
-
setSize(index, rowRef.current.offsetHeight);
|
|
56
|
-
}, [index]);
|
|
57
|
-
let item = data[index];
|
|
58
|
-
let itemId = getItemId(item);
|
|
59
|
-
let active = index === currentIndex;
|
|
60
|
-
let ItemComponent = props.renderItem;
|
|
61
|
-
return (_jsx(ItemComponent, { className: clsx("ObCombobox-listItem", active && "active", isItemSelected?.(item) && "selected"), "aria-selected": active, onClick: () => handleSelectItem(item), item: item, style: {
|
|
62
|
-
...style,
|
|
63
|
-
padding: isDesktop ? "0 8px" : "8px",
|
|
64
|
-
}, ref: rowRef, id: itemId }, itemId));
|
|
65
|
-
};
|
|
66
|
-
useEffect(() => listRef.current?.scrollToItem(currentIndex, "smart"), [currentIndex]);
|
|
67
|
-
return (_jsxs("div", { className: "ObCombobox-root", id: id, onClick: (evt) => evt.stopPropagation(), children: [_jsxs("div", { className: "ObCombobox-actions", children: [nullable && (_jsx(Button, { className: "ObCombobox-clear", "data-size": isDesktop ? "sm" : "md", variant: "tertiary", onClick: () => {
|
|
68
|
-
onChange?.(null);
|
|
69
|
-
}, children: getLocalizedString("Clear") })), onClose && (_jsx(Button, { "data-size": isDesktop ? "sm" : "md", variant: "tertiary", className: "ObCombobox-close", onClick: onClose, children: getLocalizedString("Close") }))] }), _jsx(Textfield, { type: "search", className: "ObCombobox-input", "aria-label": getLocalizedString("Search"), placeholder: getLocalizedString("Search"), onKeyDown: handleKeyDown, "aria-activedescendant": getItemId(data[currentIndex]) ?? "", value: inputValue, onChange: (event) => setInputValue(event.target.value) }), _jsxs("div", { className: "ObCombobox-listWrap", ref: wrapperRef, children: [loading && (_jsx("div", { className: "ObCombobox-progress", children: _jsx("div", { className: "ObCombobox-progress-bar" }) })), height > 0 &&
|
|
70
|
-
(columns ? (_jsx(LookupGrid, { columns: columns, data: data, height: height, currentIndex: currentIndex, currentColumn: currentColumn, getItemId: getItemId, isItemSelected: isItemSelected, onSelectItem: handleSelectItem })) : (_jsx("div", { className: "ObCombobox-list", role: "listbox", children: _jsx(VirtualList, { ref: listRef, height: height, width: "100%", itemCount: data.length, itemSize: getItemSize, overscanCount: 5, children: Row }) })))] })] }));
|
|
71
|
-
}
|
package/es/AfLookup/Lookup.css
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
.ObLookup-inputWrap {
|
|
2
|
-
position: relative;
|
|
3
|
-
|
|
4
|
-
.ds-input {
|
|
5
|
-
padding-inline-end: var(--ObLookup-buttons-width, 3rem);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.ObLookup-buttons {
|
|
10
|
-
position: absolute;
|
|
11
|
-
inset-inline-end: 0;
|
|
12
|
-
inset-block-end: 0;
|
|
13
|
-
/* Match the .ds-input height so the buttons center on the input row,
|
|
14
|
-
also when a label or description is rendered above the input */
|
|
15
|
-
height: var(--ds-size-12, 3rem);
|
|
16
|
-
display: flex;
|
|
17
|
-
align-items: center;
|
|
18
|
-
padding-inline-end: var(--ds-size-1, 0.25rem);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
.ObLookup-dialog {
|
|
22
|
-
border: 0;
|
|
23
|
-
margin-block-start: 0;
|
|
24
|
-
padding: 1rem;
|
|
25
|
-
overflow: hidden;
|
|
26
|
-
|
|
27
|
-
background-color: whitesmoke;
|
|
28
|
-
|
|
29
|
-
transition:
|
|
30
|
-
display 0.2s allow-discrete,
|
|
31
|
-
transform 0.2s ease-out,
|
|
32
|
-
scale 0.2s ease-out,
|
|
33
|
-
opacity 0.2s ease-out;
|
|
34
|
-
|
|
35
|
-
&::backdrop {
|
|
36
|
-
opacity: 0;
|
|
37
|
-
background: rgb(0 0 0 / 0.2);
|
|
38
|
-
transition:
|
|
39
|
-
display 0.2s allow-discrete,
|
|
40
|
-
opacity 0.2s ease-out;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
&[open]::backdrop {
|
|
44
|
-
opacity: 1;
|
|
45
|
-
|
|
46
|
-
@starting-style {
|
|
47
|
-
opacity: 0;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
@media (width < 768px) {
|
|
52
|
-
inset: 10vh 0.5rem 0;
|
|
53
|
-
|
|
54
|
-
border-radius: 1rem 1rem 0 0;
|
|
55
|
-
height: 90vh;
|
|
56
|
-
width: calc(100vw - 1rem);
|
|
57
|
-
max-width: 100vw;
|
|
58
|
-
transform: translateY(100%);
|
|
59
|
-
z-index: 1500;
|
|
60
|
-
|
|
61
|
-
opacity: 0;
|
|
62
|
-
|
|
63
|
-
&[open] {
|
|
64
|
-
transform: translateY(0);
|
|
65
|
-
opacity: 1;
|
|
66
|
-
|
|
67
|
-
@starting-style {
|
|
68
|
-
transform: translateY(100%);
|
|
69
|
-
opacity: 0;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@media (width >= 768px) {
|
|
75
|
-
inset-block-start: 50%;
|
|
76
|
-
inset-inline-start: 50%;
|
|
77
|
-
translate: -50% -50%;
|
|
78
|
-
scale: 1 0;
|
|
79
|
-
opacity: 0;
|
|
80
|
-
|
|
81
|
-
border-radius: 0.25rem;
|
|
82
|
-
|
|
83
|
-
height: clamp(300px, 80vh, 500px);
|
|
84
|
-
min-width: 320px;
|
|
85
|
-
width: var(--default-width, 400px);
|
|
86
|
-
|
|
87
|
-
&[open] {
|
|
88
|
-
scale: 1;
|
|
89
|
-
opacity: 1;
|
|
90
|
-
|
|
91
|
-
@starting-style {
|
|
92
|
-
scale: 1 0;
|
|
93
|
-
opacity: 0;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
@supports (inset-block-start: anchor(bottom)) {
|
|
99
|
-
@media (width < 768px) or (pointer: coarse) {
|
|
100
|
-
anchor-name: unset !important;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
@media screen and (width >= 768px) and (pointer: fine) {
|
|
104
|
-
inset-block-start: anchor(bottom);
|
|
105
|
-
inset-block-end: unset;
|
|
106
|
-
|
|
107
|
-
inset-inline-start: anchor(left);
|
|
108
|
-
inset-inline-end: unset;
|
|
109
|
-
|
|
110
|
-
translate: unset;
|
|
111
|
-
transform-origin: top left;
|
|
112
|
-
|
|
113
|
-
resize: both;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
&[data-anchor="manual"] {
|
|
118
|
-
inset: unset;
|
|
119
|
-
position: fixed;
|
|
120
|
-
inset-inline-start: var(--lookup-anchor-inline-start, 50%);
|
|
121
|
-
inset-block-start: var(--lookup-anchor-block-start, 50%);
|
|
122
|
-
translate: unset;
|
|
123
|
-
transform: none;
|
|
124
|
-
}
|
|
125
|
-
}
|
package/es/AfLookup/Lookup.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import "./Lookup.css";
|
|
2
|
-
import { type TextfieldProps } from "@digdir/designsystemet-react";
|
|
3
|
-
import { type DistributiveOmit } from "@olenbetong/appframe-react";
|
|
4
|
-
import { type ComboboxProps } from "./Combobox.js";
|
|
5
|
-
export type AfLookupProps<T extends Record<string, unknown>> = DistributiveOmit<ComboboxProps<T>, "value"> & {
|
|
6
|
-
/**
|
|
7
|
-
* Allows the user to enter a value manually that might not be in the list.
|
|
8
|
-
*/
|
|
9
|
-
editable?: boolean;
|
|
10
|
-
fullWidth?: boolean;
|
|
11
|
-
label?: string;
|
|
12
|
-
value?: string | null;
|
|
13
|
-
onChange?: (item: T | null) => void;
|
|
14
|
-
slotProps?: {
|
|
15
|
-
dialog?: Partial<React.HTMLProps<HTMLDialogElement>>;
|
|
16
|
-
textField?: Partial<TextfieldProps>;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
export type LookupProps<T extends Record<string, unknown>> = DistributiveOmit<ComboboxProps<T>, "value"> & {
|
|
20
|
-
slotProps?: {
|
|
21
|
-
dialog?: Partial<React.HTMLProps<HTMLDialogElement>>;
|
|
22
|
-
};
|
|
23
|
-
getAnchorElement?: () => Element | null;
|
|
24
|
-
};
|
|
25
|
-
export declare function useLookup<T extends Record<string, unknown>>({ getAnchorElement, slotProps, ...props }: LookupProps<T>): {
|
|
26
|
-
open: boolean;
|
|
27
|
-
openDialog: () => void;
|
|
28
|
-
onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => void;
|
|
29
|
-
onChange: (item: T | null) => void;
|
|
30
|
-
dialogRef: import("react").RefObject<HTMLDialogElement | null>;
|
|
31
|
-
anchorName: string;
|
|
32
|
-
inputId: string;
|
|
33
|
-
dialog: import("react").ReactPortal;
|
|
34
|
-
};
|
|
35
|
-
export declare function AfLookup<T extends Record<string, unknown>>({ fullWidth, label, slotProps, value, ...props }: AfLookupProps<T>): import("react").JSX.Element;
|
package/es/AfLookup/Lookup.js
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "./Lookup.css";
|
|
3
|
-
import { Button, Textfield } from "@digdir/designsystemet-react";
|
|
4
|
-
import ClearIcon from "@mui/icons-material/Close";
|
|
5
|
-
import SearchIcon from "@mui/icons-material/Search";
|
|
6
|
-
import { getLocalizedString } from "@olenbetong/appframe-core";
|
|
7
|
-
import { useLookupState } from "@olenbetong/appframe-react";
|
|
8
|
-
import clsx from "clsx";
|
|
9
|
-
import { createPortal } from "react-dom";
|
|
10
|
-
import { Combobox } from "./Combobox.js";
|
|
11
|
-
export function useLookup({ getAnchorElement, slotProps, ...props }) {
|
|
12
|
-
let { open, openDialog, onKeyDown, dialogRef, anchorName, inputId } = useLookupState({
|
|
13
|
-
getAnchorElement,
|
|
14
|
-
scrollParentSelector: "[data-virtualized-scroller]",
|
|
15
|
-
});
|
|
16
|
-
function handleChange(item) {
|
|
17
|
-
props.onChange?.(item);
|
|
18
|
-
dialogRef.current?.close();
|
|
19
|
-
}
|
|
20
|
-
return {
|
|
21
|
-
open,
|
|
22
|
-
openDialog,
|
|
23
|
-
onKeyDown,
|
|
24
|
-
onChange: handleChange,
|
|
25
|
-
dialogRef,
|
|
26
|
-
anchorName,
|
|
27
|
-
inputId,
|
|
28
|
-
dialog: createPortal(_jsx("dialog", { ref: dialogRef, className: clsx("ObLookup-dialog", slotProps?.dialog?.className), onKeyDown: (evt) => evt.stopPropagation(), style: { positionAnchor: anchorName, ...slotProps?.dialog?.style }, children: open && _jsx(Combobox, { ...props, onClose: () => dialogRef.current?.close(), onChange: handleChange }) }), document.body, inputId),
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
export function AfLookup({ fullWidth = false, label, slotProps, value, ...props }) {
|
|
32
|
-
let { inputId, open: _open, dialog, anchorName, openDialog, onKeyDown } = useLookup(props);
|
|
33
|
-
let hasClear = !!(props.nullable && value && props.onChange);
|
|
34
|
-
return (_jsxs("div", { style: { anchorName }, children: [_jsxs("div", { className: "ObLookup-inputWrap", style: {
|
|
35
|
-
display: fullWidth ? "block" : "inline-block",
|
|
36
|
-
"--ObLookup-buttons-width": hasClear ? "5.5rem" : "3rem",
|
|
37
|
-
}, children: [_jsx(Textfield, { id: inputId, value: value ?? "", label: label, readOnly: true, onClick: openDialog, onKeyDown: onKeyDown, className: clsx(slotProps?.textField?.className, "ObLookup-input"), ...slotProps?.textField, style: { width: fullWidth ? "100%" : undefined, ...slotProps?.textField?.style } }), _jsxs("div", { className: "ObLookup-buttons", children: [hasClear && (_jsx(Button, { icon: true, variant: "tertiary", "data-size": "sm", "aria-label": getLocalizedString("Clear"), onKeyDown: (evt) => evt.stopPropagation(), onClick: (evt) => {
|
|
38
|
-
evt.stopPropagation();
|
|
39
|
-
props.onChange?.(null);
|
|
40
|
-
document.getElementById(inputId)?.focus();
|
|
41
|
-
}, children: _jsx(ClearIcon, {}) })), _jsx(Button, { icon: true, variant: "tertiary", "data-size": "sm", "aria-label": getLocalizedString("Search"), onClick: openDialog, children: _jsx(SearchIcon, {}) })] })] }), dialog] }));
|
|
42
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import "./Lookup.css";
|
|
2
|
-
import { type TextfieldProps } from "@digdir/designsystemet-react";
|
|
3
|
-
import type { DistributiveOmit } from "@olenbetong/appframe-react";
|
|
4
|
-
import type React from "react";
|
|
5
|
-
import type { ComboboxProps } from "./Combobox.js";
|
|
6
|
-
export type AfLookupEditProps<T extends Record<string, unknown>> = DistributiveOmit<ComboboxProps<T>, "value" | "onChange"> & {
|
|
7
|
-
/**
|
|
8
|
-
* Allows the user to enter a value manually that might not be in the list.
|
|
9
|
-
*/
|
|
10
|
-
editable?: boolean;
|
|
11
|
-
fullWidth?: boolean;
|
|
12
|
-
label?: string;
|
|
13
|
-
value?: string | null;
|
|
14
|
-
lookupField: keyof T;
|
|
15
|
-
onChange?: (evt: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
|
|
16
|
-
slotProps?: {
|
|
17
|
-
dialog?: Partial<React.HTMLProps<HTMLDialogElement>>;
|
|
18
|
-
textField?: Partial<TextfieldProps>;
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
export declare function AfLookupEdit<T extends Record<string, unknown>>({ fullWidth, label, onChange, slotProps, nullable, lookupField, value, ...props }: AfLookupEditProps<T>): React.JSX.Element;
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "./Lookup.css";
|
|
3
|
-
import { Button, Textfield } from "@digdir/designsystemet-react";
|
|
4
|
-
import ClearIcon from "@mui/icons-material/Close";
|
|
5
|
-
import SearchIcon from "@mui/icons-material/Search";
|
|
6
|
-
import { getLocalizedString } from "@olenbetong/appframe-core";
|
|
7
|
-
import clsx from "clsx";
|
|
8
|
-
import { useLookup } from "./Lookup.js";
|
|
9
|
-
export function AfLookupEdit({ fullWidth = false, label, onChange, slotProps, nullable, lookupField, value, ...props }) {
|
|
10
|
-
let { inputId, dialog, anchorName, openDialog, onKeyDown } = useLookup({
|
|
11
|
-
...props,
|
|
12
|
-
nullable,
|
|
13
|
-
slotProps: { dialog: slotProps?.dialog },
|
|
14
|
-
onChange: (item) => applyValue(item),
|
|
15
|
-
});
|
|
16
|
-
// The popup selects a single value from the dataset: the item's lookupField
|
|
17
|
-
// is written to the input through the native value setter so the same
|
|
18
|
-
// change event fires whether the user types or picks from the list/grid.
|
|
19
|
-
function applyValue(item) {
|
|
20
|
-
let input = document.getElementById(inputId);
|
|
21
|
-
let nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, "value")?.set;
|
|
22
|
-
if (input && nativeInputValueSetter) {
|
|
23
|
-
nativeInputValueSetter.call(input, item ? String(item[lookupField]) : "");
|
|
24
|
-
input.dispatchEvent(new Event("input", { bubbles: true }));
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
function handleKeyDown(event) {
|
|
28
|
-
if (event.key === "Enter") {
|
|
29
|
-
event.preventDefault();
|
|
30
|
-
event.stopPropagation();
|
|
31
|
-
openDialog();
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
onKeyDown(event);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
let hasClear = !!(nullable && value && onChange);
|
|
38
|
-
return (_jsxs("div", { style: { anchorName }, children: [_jsxs("div", { className: "ObLookup-inputWrap", style: {
|
|
39
|
-
display: fullWidth ? "block" : "inline-block",
|
|
40
|
-
"--ObLookup-buttons-width": hasClear ? "5.5rem" : "3rem",
|
|
41
|
-
}, children: [_jsx(Textfield, { id: inputId, value: value ?? "", label: label, onChange: onChange, onKeyDown: handleKeyDown, className: clsx(slotProps?.textField?.className, "ObLookup-input"), ...slotProps?.textField, style: { width: fullWidth ? "100%" : undefined, ...slotProps?.textField?.style } }), _jsxs("div", { className: "ObLookup-buttons", children: [hasClear && (_jsx(Button, { icon: true, variant: "tertiary", "data-size": "sm", "aria-label": getLocalizedString("Clear"), onKeyDown: (evt) => evt.stopPropagation(), onClick: (evt) => {
|
|
42
|
-
evt.stopPropagation();
|
|
43
|
-
applyValue(null);
|
|
44
|
-
document.getElementById(inputId)?.focus();
|
|
45
|
-
}, children: _jsx(ClearIcon, {}) })), _jsx(Button, { icon: true, variant: "tertiary", "data-size": "sm", "aria-label": getLocalizedString("Search"), onClick: (evt) => {
|
|
46
|
-
evt.stopPropagation();
|
|
47
|
-
openDialog();
|
|
48
|
-
}, children: _jsx(SearchIcon, {}) })] })] }), dialog] }));
|
|
49
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
.ObLookupGrid-root {
|
|
2
|
-
height: 100%;
|
|
3
|
-
overflow: hidden;
|
|
4
|
-
overscroll-behavior: contain;
|
|
5
|
-
border: 1px solid rgb(0 0 0 / 0.06);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
.ObLookupGrid-header {
|
|
9
|
-
display: grid;
|
|
10
|
-
height: 40px;
|
|
11
|
-
align-items: center;
|
|
12
|
-
border-bottom: 1px solid rgb(0 0 0 / 0.12);
|
|
13
|
-
background-color: rgb(0 0 0 / 0.03);
|
|
14
|
-
font-weight: 600;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.ObLookupGrid-headerCell {
|
|
18
|
-
padding: 0 8px;
|
|
19
|
-
overflow: hidden;
|
|
20
|
-
text-overflow: ellipsis;
|
|
21
|
-
white-space: nowrap;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.ObLookupGrid-row {
|
|
25
|
-
--active-color: oklch(from var(--brand-secondary, #999) l c h / 50%);
|
|
26
|
-
display: grid;
|
|
27
|
-
align-items: center;
|
|
28
|
-
cursor: pointer;
|
|
29
|
-
border-bottom: 1px solid rgb(0 0 0 / 0.06);
|
|
30
|
-
|
|
31
|
-
&.active {
|
|
32
|
-
background-color: var(--active-color);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
&:hover {
|
|
36
|
-
background-color: rgb(0 0 0 / 0.06);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
&.active:hover {
|
|
40
|
-
background-color: oklch(from var(--active-color) calc(l + 0.1) calc(c - 0.04) h);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.ObLookupGrid-cell {
|
|
45
|
-
padding: 0 8px;
|
|
46
|
-
height: 100%;
|
|
47
|
-
display: flex;
|
|
48
|
-
align-items: center;
|
|
49
|
-
overflow: hidden;
|
|
50
|
-
text-overflow: ellipsis;
|
|
51
|
-
white-space: nowrap;
|
|
52
|
-
|
|
53
|
-
&.active {
|
|
54
|
-
outline: 2px solid oklch(from var(--brand-secondary, #666) calc(l - 0.2) c h);
|
|
55
|
-
outline-offset: -2px;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import "./LookupGrid.css";
|
|
2
|
-
import type { LookupColumn } from "@olenbetong/appframe-react";
|
|
3
|
-
export interface LookupGridProps<T extends Record<string, unknown>> {
|
|
4
|
-
columns: LookupColumn<T>[];
|
|
5
|
-
data: T[];
|
|
6
|
-
height: number;
|
|
7
|
-
currentIndex: number;
|
|
8
|
-
currentColumn: number;
|
|
9
|
-
getItemId: (item: T | undefined) => string | undefined;
|
|
10
|
-
isItemSelected?: (item: T) => boolean;
|
|
11
|
-
onSelectItem: (item: T) => void;
|
|
12
|
-
}
|
|
13
|
-
export declare function LookupGrid<T extends Record<string, unknown>>({ columns, data, height, currentIndex, currentColumn, getItemId, isItemSelected, onSelectItem, }: LookupGridProps<T>): import("react").JSX.Element;
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "./LookupGrid.css";
|
|
3
|
-
import { getLocalizedString } from "@olenbetong/appframe-core";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
import { useEffect, useMemo, useRef } from "react";
|
|
6
|
-
import { FixedSizeList as VirtualList } from "react-window";
|
|
7
|
-
const ROW_HEIGHT = 40;
|
|
8
|
-
const HEADER_HEIGHT = 40;
|
|
9
|
-
function getColumnWidth(column) {
|
|
10
|
-
if (typeof column.width === "number") {
|
|
11
|
-
return `${column.width}px`;
|
|
12
|
-
}
|
|
13
|
-
return column.width ?? "minmax(80px, 1fr)";
|
|
14
|
-
}
|
|
15
|
-
export function LookupGrid({ columns, data, height, currentIndex, currentColumn, getItemId, isItemSelected, onSelectItem, }) {
|
|
16
|
-
let listRef = useRef(null);
|
|
17
|
-
let gridTemplateColumns = useMemo(() => columns.map(getColumnWidth).join(" "), [columns]);
|
|
18
|
-
useEffect(() => listRef.current?.scrollToItem(currentIndex, "smart"), [currentIndex]);
|
|
19
|
-
// oxlint-disable-next-line react/no-nested-component-definitions -- react-window row renderer
|
|
20
|
-
let Row = ({ index, style }) => {
|
|
21
|
-
let item = data[index];
|
|
22
|
-
let itemId = getItemId(item);
|
|
23
|
-
let active = index === currentIndex;
|
|
24
|
-
return (_jsx("div", { role: "row", "aria-selected": active, className: clsx("ObLookupGrid-row", active && "active", isItemSelected?.(item) && "selected"), style: { ...style, gridTemplateColumns }, onClick: () => onSelectItem(item), id: itemId, children: columns.map((column, columnIndex) => (_jsx("div", { role: "gridcell", className: clsx("ObLookupGrid-cell", active && columnIndex === currentColumn && "active"), title: String(item[column.field] ?? ""), children: column.renderCell ? column.renderCell(item[column.field], item) : String(item[column.field] ?? "") }, column.field))) }, itemId));
|
|
25
|
-
};
|
|
26
|
-
return (_jsxs("div", { role: "grid", "aria-label": getLocalizedString("Search results"), className: "ObLookupGrid-root", children: [_jsx("div", { role: "row", className: "ObLookupGrid-header", style: { gridTemplateColumns }, children: columns.map((column) => (_jsx("div", { role: "columnheader", className: "ObLookupGrid-headerCell", children: column.headerName ?? column.field }, column.field))) }), _jsx(VirtualList, { ref: listRef, height: Math.max(0, height - HEADER_HEIGHT), width: "100%", itemCount: data.length, itemSize: ROW_HEIGHT, overscanCount: 5, children: Row })] }));
|
|
27
|
-
}
|
package/es/AfLookup/index.d.ts
DELETED
package/es/AfLookup/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type CheckboxProps } from "@digdir/designsystemet-react";
|
|
2
|
-
export type BoundCheckboxProps = Omit<CheckboxProps, "onChange" | "onKeyDown"> & {
|
|
3
|
-
field: string;
|
|
4
|
-
onChange?: (evt: React.ChangeEvent<HTMLInputElement>) => void;
|
|
5
|
-
};
|
|
6
|
-
export declare const BoundCheckbox: import("react").ForwardRefExoticComponent<Omit<CheckboxProps, "onChange" | "onKeyDown"> & {
|
|
7
|
-
field: string;
|
|
8
|
-
onChange?: (evt: React.ChangeEvent<HTMLInputElement>) => void;
|
|
9
|
-
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Checkbox } from "@digdir/designsystemet-react";
|
|
3
|
-
import { useField } from "@olenbetong/appframe-react";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
|
-
export const BoundCheckbox = forwardRef(function BoundCheckbox({ field, onChange: onChangeProp, checked: _checked, ...props }, ref) {
|
|
6
|
-
let { value, setValue, onKeyDown } = useField(field);
|
|
7
|
-
return (_jsx(Checkbox, { checked: value ?? false, onChange: (evt) => {
|
|
8
|
-
onChangeProp?.(evt);
|
|
9
|
-
if (!evt.defaultPrevented) {
|
|
10
|
-
setValue(evt.target.checked);
|
|
11
|
-
}
|
|
12
|
-
}, onKeyDown: (evt) => onKeyDown(evt), ref: ref, name: field, ...props }));
|
|
13
|
-
});
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type TextfieldProps } from "@digdir/designsystemet-react";
|
|
2
|
-
export type BoundDatePickerProps = Omit<TextfieldProps, "value" | "onChange" | "onKeyDown" | "type"> & {
|
|
3
|
-
field: string;
|
|
4
|
-
};
|
|
5
|
-
export declare const BoundDatePicker: import("react").ForwardRefExoticComponent<Omit<TextfieldProps, "onChange" | "onKeyDown" | "type" | "value"> & {
|
|
6
|
-
field: string;
|
|
7
|
-
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Textfield } from "@digdir/designsystemet-react";
|
|
3
|
-
import { useField } from "@olenbetong/appframe-react";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
|
-
export const BoundDatePicker = forwardRef(function BoundDatePicker({ field, ...props }, ref) {
|
|
6
|
-
let { error, value, onChange, onKeyDown } = useField(field);
|
|
7
|
-
let inputValue = value;
|
|
8
|
-
if (value instanceof Date) {
|
|
9
|
-
inputValue = value.toISOString().split("T")[0];
|
|
10
|
-
}
|
|
11
|
-
return (_jsx(Textfield, { type: "date", name: field, error: error ?? undefined, ...props, value: inputValue ?? "", onChange: (evt) => onChange(evt), onKeyDown: (evt) => onKeyDown(evt), ref: ref }));
|
|
12
|
-
});
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { type TextfieldProps } from "@digdir/designsystemet-react";
|
|
2
|
-
export type BoundDateTimePickerProps = Omit<TextfieldProps, "value" | "onChange" | "onKeyDown" | "type"> & {
|
|
3
|
-
field: string;
|
|
4
|
-
};
|
|
5
|
-
export declare const BoundDateTimePicker: import("react").ForwardRefExoticComponent<Omit<TextfieldProps, "onChange" | "onKeyDown" | "type" | "value"> & {
|
|
6
|
-
field: string;
|
|
7
|
-
} & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Textfield } from "@digdir/designsystemet-react";
|
|
3
|
-
import { useField } from "@olenbetong/appframe-react";
|
|
4
|
-
import { forwardRef } from "react";
|
|
5
|
-
export const BoundDateTimePicker = forwardRef(function BoundDateTimePicker({ field, ...props }, ref) {
|
|
6
|
-
let { error, value, onChange, onKeyDown } = useField(field);
|
|
7
|
-
let inputValue = value;
|
|
8
|
-
if (value instanceof Date) {
|
|
9
|
-
inputValue = value.toISOString().replace("Z", "");
|
|
10
|
-
}
|
|
11
|
-
return (_jsx(Textfield, { type: "datetime-local", name: field, error: error ?? undefined, ...props, value: inputValue ?? "", onChange: (evt) => {
|
|
12
|
-
onChange(evt, evt.target.value ? `${evt.target.value}Z` : null);
|
|
13
|
-
}, onKeyDown: (evt) => onKeyDown(evt), ref: ref }));
|
|
14
|
-
});
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type InputProps } from "@digdir/designsystemet-react";
|
|
2
|
-
export type BoundInputProps = Omit<InputProps, "onChange" | "onKeyDown" | "onBlur"> & {
|
|
3
|
-
field: string;
|
|
4
|
-
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
5
|
-
};
|
|
6
|
-
export declare function BoundInput({ field, onChange: onChangeProp, ...props }: BoundInputProps): import("react").JSX.Element;
|
package/es/binding/BoundInput.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Input } from "@digdir/designsystemet-react";
|
|
3
|
-
import { useField } from "@olenbetong/appframe-react";
|
|
4
|
-
export function BoundInput({ field, onChange: onChangeProp, ...props }) {
|
|
5
|
-
let { value, onChange, onKeyDown } = useField(field);
|
|
6
|
-
return (_jsx(Input, { name: field, ...props, value: value ?? "", onChange: (event) => {
|
|
7
|
-
onChangeProp?.(event);
|
|
8
|
-
if (!event.defaultPrevented) {
|
|
9
|
-
onChange(event);
|
|
10
|
-
}
|
|
11
|
-
}, onKeyDown: (evt) => onKeyDown(evt) }));
|
|
12
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { type TextfieldProps } from "@digdir/designsystemet-react";
|
|
2
|
-
/**
|
|
3
|
-
* A Designsystemet `Textfield` bound to an Appframe data source field via `useField`.
|
|
4
|
-
*
|
|
5
|
-
* Adds client-side numeric validation: rejects non-numeric characters and enforces
|
|
6
|
-
* optional `precision` (total digits) and `scale` (decimal places) constraints.
|
|
7
|
-
* Validation errors are reported to the parent via the `onError` callback so the
|
|
8
|
-
* parent can track whether any field is in an error state (e.g., to disable Save).
|
|
9
|
-
*
|
|
10
|
-
* On blur the displayed value is normalized to a JS `Number` (comma decimal separators
|
|
11
|
-
* are converted to dots) so the data source always stores a proper numeric value.
|
|
12
|
-
*/
|
|
13
|
-
export type BoundNumericTextFieldProps = Omit<TextfieldProps, "onChange" | "onKeyDown" | "onError"> & {
|
|
14
|
-
field: string;
|
|
15
|
-
precision?: number;
|
|
16
|
-
scale?: number;
|
|
17
|
-
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
18
|
-
onError?: (error: string | null) => void;
|
|
19
|
-
};
|
|
20
|
-
export declare function BoundNumericTextField({ field, precision, scale, onChange: onChangeProp, onError, ...props }: BoundNumericTextFieldProps): import("react").JSX.Element;
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Textfield } from "@digdir/designsystemet-react";
|
|
3
|
-
import { getLocalizedString, localize } from "@olenbetong/appframe-core";
|
|
4
|
-
import { useField } from "@olenbetong/appframe-react";
|
|
5
|
-
import { useEffect, useState } from "react";
|
|
6
|
-
export function BoundNumericTextField({ field, precision, scale, onChange: onChangeProp, onError, ...props }) {
|
|
7
|
-
let { value, setValue, onChange, onKeyDown } = useField(field);
|
|
8
|
-
let [error, setError] = useState(null);
|
|
9
|
-
function checkNumber(value, precision, scale) {
|
|
10
|
-
if (value[0] === "0") {
|
|
11
|
-
value = value[0].replace("0", "");
|
|
12
|
-
}
|
|
13
|
-
let [integer, decimal] = value.split(",");
|
|
14
|
-
if (value.includes(".")) {
|
|
15
|
-
[integer, decimal] = value.split(".");
|
|
16
|
-
}
|
|
17
|
-
integer = integer.replace("-", "");
|
|
18
|
-
if (integer.length > precision - scale) {
|
|
19
|
-
setError(localize `The amount of whole numbers is too high. Allowed limit is ${precision - scale}`);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
if (decimal && decimal.length > scale) {
|
|
23
|
-
setError(localize `The amount of decimal places is too high. Allowed limit is ${scale}`);
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
setError(null);
|
|
27
|
-
}
|
|
28
|
-
function checkError(value, precision, scale) {
|
|
29
|
-
let regExp = /[a-zA-Z `!@#$%^&*()_+=[\]{};':"\\|<>/?~]/;
|
|
30
|
-
if (regExp.test(value)) {
|
|
31
|
-
setError(getLocalizedString("Please enter a valid number"));
|
|
32
|
-
}
|
|
33
|
-
else if (value.substring(1).includes("-")) {
|
|
34
|
-
setError(getLocalizedString("Please enter a valid number"));
|
|
35
|
-
}
|
|
36
|
-
else if (precision !== undefined && scale !== undefined) {
|
|
37
|
-
checkNumber(value, precision, scale);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
setError(null);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
useEffect(() => {
|
|
44
|
-
onError?.(error);
|
|
45
|
-
}, [error, onError]);
|
|
46
|
-
return (_jsx(Textfield, { name: field, error: error ?? undefined, ...props, value: value ?? "", onChange: (event) => {
|
|
47
|
-
onChangeProp?.(event);
|
|
48
|
-
if (!event.defaultPrevented) {
|
|
49
|
-
checkError(event.target.value, precision, scale);
|
|
50
|
-
onChange(event);
|
|
51
|
-
}
|
|
52
|
-
}, onKeyDown: (evt) => onKeyDown(evt), onBlur: (evt) => {
|
|
53
|
-
const raw = evt.target.value;
|
|
54
|
-
if (raw !== "") {
|
|
55
|
-
setValue(Number(raw.replaceAll(",", ".")));
|
|
56
|
-
}
|
|
57
|
-
} }));
|
|
58
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type SelectProps } from "@digdir/designsystemet-react";
|
|
2
|
-
export type BoundSelectProps = Omit<SelectProps, "onChange" | "value"> & {
|
|
3
|
-
field: string;
|
|
4
|
-
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
5
|
-
};
|
|
6
|
-
export declare const BoundSelect: import("react").ForwardRefExoticComponent<Omit<SelectProps, "onChange" | "value"> & {
|
|
7
|
-
field: string;
|
|
8
|
-
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
9
|
-
} & import("react").RefAttributes<HTMLSelectElement>>;
|