@scm-manager/ui-forms 2.44.2 → 2.44.3-20230527-064447
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/.turbo/turbo-build.log +7 -7
- package/build/index.d.ts +106 -45
- package/build/index.js +525 -255
- package/build/index.mjs +396 -122
- package/package.json +7 -6
- package/src/Form.stories.tsx +22 -0
- package/src/chip-input/ChipInputField.stories.tsx +41 -12
- package/src/chip-input/ChipInputField.tsx +83 -56
- package/src/chip-input/ControlledChipInputField.tsx +12 -4
- package/src/combobox/Combobox.stories.tsx +96 -0
- package/src/combobox/Combobox.tsx +217 -0
- package/src/combobox/ComboboxField.tsx +62 -0
- package/src/combobox/ControlledComboboxField.tsx +96 -0
- package/src/headless-chip-input/ChipInput.tsx +127 -59
- package/src/helpers.ts +23 -0
- package/src/index.ts +4 -0
package/build/index.mjs
CHANGED
|
@@ -21,6 +21,7 @@ import { Button } from "@scm-manager/ui-buttons";
|
|
|
21
21
|
import styled from "styled-components";
|
|
22
22
|
|
|
23
23
|
// src/helpers.ts
|
|
24
|
+
import { forwardRef } from "react";
|
|
24
25
|
function prefixWithoutIndices(path) {
|
|
25
26
|
return path.replace(/(\.\d+)/g, "");
|
|
26
27
|
}
|
|
@@ -38,6 +39,21 @@ function setValues(newValues, setValue, path = "") {
|
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
}
|
|
42
|
+
function withForwardRef(component) {
|
|
43
|
+
return forwardRef(component);
|
|
44
|
+
}
|
|
45
|
+
var defaultOptionFactory = (item) => typeof item === "object" && item !== null && "value" in item && typeof item["label"] === "string" ? item : { label: item, value: item };
|
|
46
|
+
function mergeRefs(...refs) {
|
|
47
|
+
return (el) => refs.forEach((ref) => {
|
|
48
|
+
if (ref) {
|
|
49
|
+
if (typeof ref === "function") {
|
|
50
|
+
ref(el);
|
|
51
|
+
} else {
|
|
52
|
+
ref.current = el;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
41
57
|
|
|
42
58
|
// src/Form.tsx
|
|
43
59
|
var ButtonsContainer = styled.div`
|
|
@@ -614,10 +630,37 @@ import React20, {
|
|
|
614
630
|
createContext,
|
|
615
631
|
useCallback as useCallback3,
|
|
616
632
|
useContext as useContext3,
|
|
617
|
-
useMemo as useMemo3
|
|
633
|
+
useMemo as useMemo3,
|
|
634
|
+
useRef
|
|
618
635
|
} from "react";
|
|
619
636
|
import { Slot } from "@radix-ui/react-slot";
|
|
620
637
|
var ChipInputContext = createContext(null);
|
|
638
|
+
function getChipInputContext() {
|
|
639
|
+
return ChipInputContext;
|
|
640
|
+
}
|
|
641
|
+
var DefaultNewChipInput = React20.forwardRef(
|
|
642
|
+
({ onChange, value, ...props }, ref) => {
|
|
643
|
+
const handleKeyDown = useCallback3(
|
|
644
|
+
(e) => {
|
|
645
|
+
if (e.key === "Enter") {
|
|
646
|
+
e.preventDefault();
|
|
647
|
+
if (e.currentTarget.value) {
|
|
648
|
+
onChange({ label: e.currentTarget.value, value: e.currentTarget.value });
|
|
649
|
+
}
|
|
650
|
+
return false;
|
|
651
|
+
}
|
|
652
|
+
},
|
|
653
|
+
[onChange]
|
|
654
|
+
);
|
|
655
|
+
return /* @__PURE__ */ React20.createElement("div", {
|
|
656
|
+
className: "is-flex-grow-1"
|
|
657
|
+
}, /* @__PURE__ */ React20.createElement("input", {
|
|
658
|
+
onKeyDown: handleKeyDown,
|
|
659
|
+
...props,
|
|
660
|
+
ref
|
|
661
|
+
}));
|
|
662
|
+
}
|
|
663
|
+
);
|
|
621
664
|
var ChipDelete = React20.forwardRef(({ asChild, index, ...props }, ref) => {
|
|
622
665
|
const { remove, disabled } = useContext3(ChipInputContext);
|
|
623
666
|
const Comp = asChild ? Slot : "button";
|
|
@@ -631,29 +674,16 @@ var ChipDelete = React20.forwardRef(({ asChild, index, ...props }, ref) => {
|
|
|
631
674
|
onClick: () => remove(index)
|
|
632
675
|
});
|
|
633
676
|
});
|
|
634
|
-
var NewChipInput =
|
|
635
|
-
const { add,
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
if (e.key === "Enter") {
|
|
639
|
-
e.preventDefault();
|
|
640
|
-
const newValue = e.currentTarget.value.trim();
|
|
641
|
-
if (newValue && !(value == null ? void 0 : value.includes(newValue))) {
|
|
642
|
-
add(newValue);
|
|
643
|
-
e.currentTarget.value = "";
|
|
644
|
-
}
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
|
-
},
|
|
648
|
-
[add, value]
|
|
649
|
-
);
|
|
650
|
-
const Comp = asChild ? Slot : "input";
|
|
651
|
-
return /* @__PURE__ */ React20.createElement(Comp, {
|
|
677
|
+
var NewChipInput = withForwardRef(function NewChipInput2(props, ref) {
|
|
678
|
+
const { add, disabled, readOnly, inputRef } = useContext3(getChipInputContext());
|
|
679
|
+
const Comp = props.children ? Slot : DefaultNewChipInput;
|
|
680
|
+
return React20.createElement(Comp, {
|
|
652
681
|
...props,
|
|
653
|
-
|
|
682
|
+
onChange: add,
|
|
654
683
|
readOnly,
|
|
655
684
|
disabled,
|
|
656
|
-
|
|
685
|
+
value: null,
|
|
686
|
+
ref: mergeRefs(ref, inputRef)
|
|
657
687
|
});
|
|
658
688
|
});
|
|
659
689
|
var Chip = React20.forwardRef(({ asChild, ...props }, ref) => {
|
|
@@ -663,34 +693,45 @@ var Chip = React20.forwardRef(({ asChild, ...props }, ref) => {
|
|
|
663
693
|
ref
|
|
664
694
|
});
|
|
665
695
|
});
|
|
666
|
-
var ChipInput =
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
696
|
+
var ChipInput = withForwardRef(function ChipInput2({ children, value = [], disabled, readOnly, onChange, isNewItemDuplicate, ...props }, ref) {
|
|
697
|
+
const inputRef = useRef(null);
|
|
698
|
+
const isInactive = useMemo3(() => disabled || readOnly, [disabled, readOnly]);
|
|
699
|
+
const add = useCallback3(
|
|
700
|
+
(newItem) => {
|
|
701
|
+
if (!isInactive && !(value == null ? void 0 : value.some(
|
|
702
|
+
(item) => isNewItemDuplicate ? isNewItemDuplicate(item, newItem) : item.label === newItem.label || item.value === newItem.value
|
|
703
|
+
))) {
|
|
704
|
+
if (onChange) {
|
|
705
|
+
onChange([...value ?? [], newItem]);
|
|
706
|
+
}
|
|
707
|
+
if (inputRef.current) {
|
|
708
|
+
inputRef.current.value = "";
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
[isInactive, isNewItemDuplicate, onChange, value]
|
|
713
|
+
);
|
|
714
|
+
const remove = useCallback3(
|
|
715
|
+
(index) => !isInactive && onChange && onChange(value == null ? void 0 : value.filter((_, itdx) => itdx !== index)),
|
|
716
|
+
[isInactive, onChange, value]
|
|
717
|
+
);
|
|
718
|
+
const Context2 = getChipInputContext();
|
|
719
|
+
return /* @__PURE__ */ React20.createElement(Context2.Provider, {
|
|
720
|
+
value: useMemo3(
|
|
721
|
+
() => ({
|
|
722
|
+
disabled,
|
|
723
|
+
readOnly,
|
|
724
|
+
add,
|
|
725
|
+
remove,
|
|
726
|
+
inputRef
|
|
727
|
+
}),
|
|
728
|
+
[add, disabled, readOnly, remove]
|
|
729
|
+
)
|
|
730
|
+
}, /* @__PURE__ */ React20.createElement("ul", {
|
|
731
|
+
...props,
|
|
732
|
+
ref
|
|
733
|
+
}, children));
|
|
734
|
+
});
|
|
694
735
|
var ChipInput_default = Object.assign(ChipInput, {
|
|
695
736
|
Chip: Object.assign(Chip, {
|
|
696
737
|
Delete: ChipDelete
|
|
@@ -712,78 +753,94 @@ var StyledChipInput = styled2(ChipInput_default)`
|
|
|
712
753
|
var StyledInput = styled2(NewChipInput)`
|
|
713
754
|
color: var(--scm-secondary-more-color);
|
|
714
755
|
font-size: 1rem;
|
|
756
|
+
height: initial;
|
|
757
|
+
padding: 0;
|
|
758
|
+
border-radius: 0;
|
|
715
759
|
&:focus {
|
|
716
760
|
outline: none;
|
|
717
761
|
}
|
|
718
762
|
`;
|
|
719
|
-
var
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
helpText,
|
|
723
|
-
readOnly,
|
|
724
|
-
disabled,
|
|
725
|
-
error,
|
|
726
|
-
createDeleteText,
|
|
727
|
-
onChange,
|
|
728
|
-
placeholder,
|
|
729
|
-
value,
|
|
730
|
-
className,
|
|
731
|
-
testId,
|
|
732
|
-
id,
|
|
733
|
-
...props
|
|
734
|
-
}, ref) => {
|
|
735
|
-
const [t] = useTranslation2("commons", { keyPrefix: "form.chipList" });
|
|
736
|
-
const deleteTextCallback = useCallback4(
|
|
737
|
-
(item) => createDeleteText ? createDeleteText(item) : t("delete", { item }),
|
|
738
|
-
[createDeleteText, t]
|
|
739
|
-
);
|
|
740
|
-
const inputId = useGeneratedId3(id ?? testId);
|
|
741
|
-
const labelId = useGeneratedId3();
|
|
742
|
-
const inputDescriptionId = useGeneratedId3();
|
|
743
|
-
const variant = error ? "danger" : void 0;
|
|
744
|
-
return /* @__PURE__ */ React21.createElement(Field_default, {
|
|
745
|
-
className,
|
|
746
|
-
"aria-owns": inputId
|
|
747
|
-
}, /* @__PURE__ */ React21.createElement(Label_default, {
|
|
748
|
-
id: labelId
|
|
749
|
-
}, label, helpText ? /* @__PURE__ */ React21.createElement(Help_default, {
|
|
750
|
-
className: "ml-1",
|
|
751
|
-
text: helpText
|
|
752
|
-
}) : null), /* @__PURE__ */ React21.createElement(StyledChipInput, {
|
|
753
|
-
value,
|
|
754
|
-
onChange,
|
|
755
|
-
className: "is-flex is-flex-wrap-wrap input",
|
|
756
|
-
"aria-labelledby": labelId,
|
|
757
|
-
disabled: readOnly || disabled
|
|
758
|
-
}, value == null ? void 0 : value.map((val, index) => /* @__PURE__ */ React21.createElement(ChipInput_default.Chip, {
|
|
759
|
-
key: `${val}-${index}`,
|
|
760
|
-
className: "tag is-light"
|
|
761
|
-
}, val, /* @__PURE__ */ React21.createElement(ChipInput_default.Chip.Delete, {
|
|
762
|
-
"aria-label": deleteTextCallback(val),
|
|
763
|
-
index,
|
|
764
|
-
className: "delete is-small"
|
|
765
|
-
}))), /* @__PURE__ */ React21.createElement(StyledInput, {
|
|
766
|
-
...props,
|
|
767
|
-
className: classNames12(
|
|
768
|
-
"is-borderless",
|
|
769
|
-
"is-flex-grow-1",
|
|
770
|
-
"has-background-transparent",
|
|
771
|
-
createVariantClass(variant)
|
|
772
|
-
),
|
|
773
|
-
placeholder: !readOnly && !disabled ? placeholder : "",
|
|
774
|
-
id: inputId,
|
|
775
|
-
ref,
|
|
776
|
-
"aria-describedby": inputDescriptionId,
|
|
777
|
-
...createAttributesForTesting4(testId)
|
|
778
|
-
})), /* @__PURE__ */ React21.createElement(VisuallyHidden, {
|
|
779
|
-
"aria-hidden": true,
|
|
780
|
-
id: inputDescriptionId
|
|
781
|
-
}, t("input.description")), error ? /* @__PURE__ */ React21.createElement(FieldMessage_default, {
|
|
782
|
-
variant
|
|
783
|
-
}, error) : null);
|
|
763
|
+
var StyledDelete = styled2(ChipInput_default.Chip.Delete)`
|
|
764
|
+
&:focus {
|
|
765
|
+
outline-offset: 0;
|
|
784
766
|
}
|
|
785
|
-
|
|
786
|
-
var
|
|
767
|
+
`;
|
|
768
|
+
var ChipInputField = function ChipInputField2({
|
|
769
|
+
label,
|
|
770
|
+
helpText,
|
|
771
|
+
readOnly,
|
|
772
|
+
disabled,
|
|
773
|
+
error,
|
|
774
|
+
createDeleteText,
|
|
775
|
+
onChange,
|
|
776
|
+
placeholder,
|
|
777
|
+
value,
|
|
778
|
+
className,
|
|
779
|
+
testId,
|
|
780
|
+
id,
|
|
781
|
+
children,
|
|
782
|
+
isLoading,
|
|
783
|
+
isNewItemDuplicate,
|
|
784
|
+
...props
|
|
785
|
+
}, ref) {
|
|
786
|
+
const [t] = useTranslation2("commons", { keyPrefix: "form.chipList" });
|
|
787
|
+
const deleteTextCallback = useCallback4(
|
|
788
|
+
(item) => createDeleteText ? createDeleteText(item) : t("delete", { item }),
|
|
789
|
+
[createDeleteText, t]
|
|
790
|
+
);
|
|
791
|
+
const inputId = useGeneratedId3(id ?? testId);
|
|
792
|
+
const labelId = useGeneratedId3();
|
|
793
|
+
const inputDescriptionId = useGeneratedId3();
|
|
794
|
+
const variant = error ? "danger" : void 0;
|
|
795
|
+
return /* @__PURE__ */ React21.createElement(Field_default, {
|
|
796
|
+
className,
|
|
797
|
+
"aria-owns": inputId
|
|
798
|
+
}, /* @__PURE__ */ React21.createElement(Label_default, {
|
|
799
|
+
id: labelId
|
|
800
|
+
}, label, helpText ? /* @__PURE__ */ React21.createElement(Help_default, {
|
|
801
|
+
className: "ml-1",
|
|
802
|
+
text: helpText
|
|
803
|
+
}) : null), /* @__PURE__ */ React21.createElement("div", {
|
|
804
|
+
className: classNames12("control", { "is-loading": isLoading })
|
|
805
|
+
}, /* @__PURE__ */ React21.createElement(StyledChipInput, {
|
|
806
|
+
value,
|
|
807
|
+
onChange: (e) => onChange && onChange(e ?? []),
|
|
808
|
+
className: "is-flex is-flex-wrap-wrap input",
|
|
809
|
+
"aria-labelledby": labelId,
|
|
810
|
+
disabled: readOnly || disabled,
|
|
811
|
+
isNewItemDuplicate
|
|
812
|
+
}, value == null ? void 0 : value.map((option, index) => /* @__PURE__ */ React21.createElement(ChipInput_default.Chip, {
|
|
813
|
+
key: option.label,
|
|
814
|
+
className: "tag is-light is-overflow-hidden"
|
|
815
|
+
}, /* @__PURE__ */ React21.createElement("span", {
|
|
816
|
+
className: "is-ellipsis-overflow"
|
|
817
|
+
}, option.label), /* @__PURE__ */ React21.createElement(StyledDelete, {
|
|
818
|
+
"aria-label": deleteTextCallback(option.label),
|
|
819
|
+
index,
|
|
820
|
+
className: "delete is-small"
|
|
821
|
+
}))), /* @__PURE__ */ React21.createElement(StyledInput, {
|
|
822
|
+
...props,
|
|
823
|
+
className: classNames12(
|
|
824
|
+
"is-borderless",
|
|
825
|
+
"has-background-transparent",
|
|
826
|
+
"is-shadowless",
|
|
827
|
+
"input",
|
|
828
|
+
"is-ellipsis-overflow",
|
|
829
|
+
createVariantClass(variant)
|
|
830
|
+
),
|
|
831
|
+
placeholder: !readOnly && !disabled ? placeholder : "",
|
|
832
|
+
id: inputId,
|
|
833
|
+
ref,
|
|
834
|
+
"aria-describedby": inputDescriptionId,
|
|
835
|
+
...createAttributesForTesting4(testId)
|
|
836
|
+
}, children ? children : null))), /* @__PURE__ */ React21.createElement(VisuallyHidden, {
|
|
837
|
+
"aria-hidden": true,
|
|
838
|
+
id: inputDescriptionId
|
|
839
|
+
}, t("input.description")), error ? /* @__PURE__ */ React21.createElement(FieldMessage_default, {
|
|
840
|
+
variant
|
|
841
|
+
}, error) : null);
|
|
842
|
+
};
|
|
843
|
+
var ChipInputField_default = withForwardRef(ChipInputField);
|
|
787
844
|
|
|
788
845
|
// src/chip-input/ControlledChipInputField.tsx
|
|
789
846
|
function ControlledChipInputField({
|
|
@@ -797,6 +854,8 @@ function ControlledChipInputField({
|
|
|
797
854
|
placeholder,
|
|
798
855
|
className,
|
|
799
856
|
createDeleteText,
|
|
857
|
+
children,
|
|
858
|
+
optionFactory = defaultOptionFactory,
|
|
800
859
|
...props
|
|
801
860
|
}) {
|
|
802
861
|
const { control, t, readOnly: formReadonly } = useScmFormContext();
|
|
@@ -812,18 +871,20 @@ function ControlledChipInputField({
|
|
|
812
871
|
name: nameWithPrefix,
|
|
813
872
|
rules,
|
|
814
873
|
defaultValue,
|
|
815
|
-
render: ({ field, fieldState }) => /* @__PURE__ */ React22.createElement(ChipInputField_default, {
|
|
874
|
+
render: ({ field: { value, onChange, ...field }, fieldState }) => /* @__PURE__ */ React22.createElement(ChipInputField_default, {
|
|
816
875
|
label: labelTranslation,
|
|
817
876
|
helpText: helpTextTranslation,
|
|
818
877
|
placeholder: placeholderTranslation,
|
|
819
878
|
"aria-label": ariaLabelTranslation,
|
|
879
|
+
value: value ? value.map(optionFactory) : [],
|
|
880
|
+
onChange: (selectedOptions) => onChange(selectedOptions.map((item) => item.value)),
|
|
820
881
|
...props,
|
|
821
882
|
...field,
|
|
822
883
|
readOnly: readOnly ?? formReadonly,
|
|
823
884
|
className: classNames13("column", className),
|
|
824
885
|
error: fieldState.error ? fieldState.error.message || t(`${prefixedNameWithoutIndices}.error.${fieldState.error.type}`) : void 0,
|
|
825
886
|
testId: testId ?? `input-${nameWithPrefix}`
|
|
826
|
-
})
|
|
887
|
+
}, children)
|
|
827
888
|
});
|
|
828
889
|
}
|
|
829
890
|
var ControlledChipInputField_default = ControlledChipInputField;
|
|
@@ -1013,18 +1074,228 @@ function AddListEntryForm({
|
|
|
1013
1074
|
}
|
|
1014
1075
|
var AddListEntryForm_default = AddListEntryForm;
|
|
1015
1076
|
|
|
1077
|
+
// src/combobox/ControlledComboboxField.tsx
|
|
1078
|
+
import React30 from "react";
|
|
1079
|
+
import { Controller as Controller6 } from "react-hook-form";
|
|
1080
|
+
import classNames17 from "classnames";
|
|
1081
|
+
|
|
1082
|
+
// src/combobox/ComboboxField.tsx
|
|
1083
|
+
import React29 from "react";
|
|
1084
|
+
import { useGeneratedId as useGeneratedId4 } from "@scm-manager/ui-components";
|
|
1085
|
+
|
|
1086
|
+
// src/combobox/Combobox.tsx
|
|
1087
|
+
import React28, {
|
|
1088
|
+
Fragment,
|
|
1089
|
+
useEffect as useEffect3,
|
|
1090
|
+
useRef as useRef2,
|
|
1091
|
+
useState as useState2
|
|
1092
|
+
} from "react";
|
|
1093
|
+
import { Combobox as HeadlessCombobox } from "@headlessui/react";
|
|
1094
|
+
import classNames15 from "classnames";
|
|
1095
|
+
import styled4 from "styled-components";
|
|
1096
|
+
import { createAttributesForTesting as createAttributesForTesting5 } from "@scm-manager/ui-components";
|
|
1097
|
+
var OptionsWrapper = styled4(HeadlessCombobox.Options).attrs({
|
|
1098
|
+
className: "is-flex is-flex-direction-column has-rounded-border has-box-shadow is-overflow-hidden"
|
|
1099
|
+
})`
|
|
1100
|
+
z-index: 400;
|
|
1101
|
+
top: 2.5rem;
|
|
1102
|
+
border: var(--scm-border);
|
|
1103
|
+
background-color: var(--scm-secondary-background);
|
|
1104
|
+
max-width: 35ch;
|
|
1105
|
+
|
|
1106
|
+
&:empty {
|
|
1107
|
+
border: 0;
|
|
1108
|
+
clip: rect(0 0 0 0);
|
|
1109
|
+
height: 1px;
|
|
1110
|
+
margin: -1px;
|
|
1111
|
+
overflow: hidden;
|
|
1112
|
+
padding: 0;
|
|
1113
|
+
position: absolute;
|
|
1114
|
+
white-space: nowrap;
|
|
1115
|
+
width: 1px;
|
|
1116
|
+
}
|
|
1117
|
+
`;
|
|
1118
|
+
var StyledComboboxOption = styled4.li.attrs({
|
|
1119
|
+
className: "px-3 py-2 has-text-inherit is-clickable is-size-6 is-borderless has-background-transparent"
|
|
1120
|
+
})`
|
|
1121
|
+
line-height: inherit;
|
|
1122
|
+
background-color: ${({ isActive }) => isActive ? "var(--scm-column-selection)" : ""};
|
|
1123
|
+
word-break: break-all;
|
|
1124
|
+
&[data-disabled] {
|
|
1125
|
+
color: unset !important;
|
|
1126
|
+
opacity: 40%;
|
|
1127
|
+
cursor: unset !important;
|
|
1128
|
+
}
|
|
1129
|
+
`;
|
|
1130
|
+
function ComboboxComponent(props, ref) {
|
|
1131
|
+
var _a;
|
|
1132
|
+
const [query, setQuery] = useState2("");
|
|
1133
|
+
const { onQueryChange } = props;
|
|
1134
|
+
useEffect3(() => onQueryChange && onQueryChange(query), [onQueryChange, query]);
|
|
1135
|
+
let options;
|
|
1136
|
+
if (Array.isArray(props.children)) {
|
|
1137
|
+
options = props.children;
|
|
1138
|
+
} else if (typeof props.options === "function") {
|
|
1139
|
+
options = /* @__PURE__ */ React28.createElement(ComboboxOptions, {
|
|
1140
|
+
children: props.children,
|
|
1141
|
+
options: props.options,
|
|
1142
|
+
query
|
|
1143
|
+
});
|
|
1144
|
+
} else {
|
|
1145
|
+
options = (_a = props.options) == null ? void 0 : _a.map(
|
|
1146
|
+
(o, index) => typeof props.children === "function" ? props.children(o, index) : /* @__PURE__ */ React28.createElement(HeadlessCombobox.Option, {
|
|
1147
|
+
value: o,
|
|
1148
|
+
key: o.label,
|
|
1149
|
+
as: Fragment
|
|
1150
|
+
}, ({ active }) => /* @__PURE__ */ React28.createElement(StyledComboboxOption, {
|
|
1151
|
+
isActive: active
|
|
1152
|
+
}, o.displayValue ?? o.label))
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
return /* @__PURE__ */ React28.createElement(HeadlessCombobox, {
|
|
1156
|
+
as: "div",
|
|
1157
|
+
value: props.value,
|
|
1158
|
+
onChange: (e) => props.onChange && props.onChange(e),
|
|
1159
|
+
disabled: props.disabled || props.readOnly,
|
|
1160
|
+
onKeyDown: (e) => props.onKeyDown && props.onKeyDown(e),
|
|
1161
|
+
name: props.name,
|
|
1162
|
+
form: props.form,
|
|
1163
|
+
defaultValue: props.defaultValue,
|
|
1164
|
+
nullable: props.nullable,
|
|
1165
|
+
className: "is-relative is-flex-grow-1 is-flex",
|
|
1166
|
+
by: "value"
|
|
1167
|
+
}, /* @__PURE__ */ React28.createElement(HeadlessCombobox.Input, {
|
|
1168
|
+
displayValue: (o) => o == null ? void 0 : o.label,
|
|
1169
|
+
ref,
|
|
1170
|
+
onChange: (e) => setQuery(e.target.value),
|
|
1171
|
+
className: classNames15(props.className, "is-full-width", "input", "is-ellipsis-overflow"),
|
|
1172
|
+
"aria-describedby": props["aria-describedby"],
|
|
1173
|
+
"aria-labelledby": props["aria-labelledby"],
|
|
1174
|
+
"aria-label": props["aria-label"],
|
|
1175
|
+
id: props.id,
|
|
1176
|
+
placeholder: props.placeholder,
|
|
1177
|
+
onBlur: props.onBlur,
|
|
1178
|
+
...createAttributesForTesting5(props.testId)
|
|
1179
|
+
}), /* @__PURE__ */ React28.createElement(OptionsWrapper, {
|
|
1180
|
+
className: "is-absolute"
|
|
1181
|
+
}, options));
|
|
1182
|
+
}
|
|
1183
|
+
function ComboboxOptions({ query, options, children }) {
|
|
1184
|
+
const [optionsData, setOptionsData] = useState2([]);
|
|
1185
|
+
const activePromise = useRef2();
|
|
1186
|
+
useEffect3(() => {
|
|
1187
|
+
const optionsExec = options(query);
|
|
1188
|
+
if (optionsExec instanceof Promise) {
|
|
1189
|
+
activePromise.current = optionsExec;
|
|
1190
|
+
optionsExec.then((newOptions) => {
|
|
1191
|
+
if (activePromise.current === optionsExec) {
|
|
1192
|
+
setOptionsData(newOptions);
|
|
1193
|
+
}
|
|
1194
|
+
}).catch(() => {
|
|
1195
|
+
if (activePromise.current === optionsExec) {
|
|
1196
|
+
setOptionsData([]);
|
|
1197
|
+
}
|
|
1198
|
+
});
|
|
1199
|
+
} else {
|
|
1200
|
+
setOptionsData(optionsExec);
|
|
1201
|
+
}
|
|
1202
|
+
}, [options, query]);
|
|
1203
|
+
return /* @__PURE__ */ React28.createElement(React28.Fragment, null, optionsData == null ? void 0 : optionsData.map(
|
|
1204
|
+
(o, index) => typeof children === "function" ? children(o, index) : /* @__PURE__ */ React28.createElement(HeadlessCombobox.Option, {
|
|
1205
|
+
value: o,
|
|
1206
|
+
key: o.label,
|
|
1207
|
+
as: Fragment
|
|
1208
|
+
}, ({ active }) => /* @__PURE__ */ React28.createElement(StyledComboboxOption, {
|
|
1209
|
+
isActive: active
|
|
1210
|
+
}, o.displayValue ?? o.label))
|
|
1211
|
+
));
|
|
1212
|
+
}
|
|
1213
|
+
var Combobox = Object.assign(withForwardRef(ComboboxComponent), {
|
|
1214
|
+
Option: StyledComboboxOption
|
|
1215
|
+
});
|
|
1216
|
+
var Combobox_default = Combobox;
|
|
1217
|
+
|
|
1218
|
+
// src/combobox/ComboboxField.tsx
|
|
1219
|
+
import classNames16 from "classnames";
|
|
1220
|
+
var ComboboxField = function ComboboxField2({
|
|
1221
|
+
label,
|
|
1222
|
+
helpText,
|
|
1223
|
+
error,
|
|
1224
|
+
className,
|
|
1225
|
+
isLoading,
|
|
1226
|
+
...props
|
|
1227
|
+
}, ref) {
|
|
1228
|
+
const labelId = useGeneratedId4();
|
|
1229
|
+
return /* @__PURE__ */ React29.createElement(Field_default, {
|
|
1230
|
+
className
|
|
1231
|
+
}, /* @__PURE__ */ React29.createElement(Label_default, {
|
|
1232
|
+
id: labelId
|
|
1233
|
+
}, label, helpText ? /* @__PURE__ */ React29.createElement(Help_default, {
|
|
1234
|
+
className: "ml-1",
|
|
1235
|
+
text: helpText
|
|
1236
|
+
}) : null), /* @__PURE__ */ React29.createElement("div", {
|
|
1237
|
+
className: classNames16("control", { "is-loading": isLoading })
|
|
1238
|
+
}, /* @__PURE__ */ React29.createElement(Combobox_default, {
|
|
1239
|
+
...props,
|
|
1240
|
+
ref,
|
|
1241
|
+
"aria-labelledby": labelId
|
|
1242
|
+
})));
|
|
1243
|
+
};
|
|
1244
|
+
var ComboboxField_default = withForwardRef(ComboboxField);
|
|
1245
|
+
|
|
1246
|
+
// src/combobox/ControlledComboboxField.tsx
|
|
1247
|
+
function ControlledComboboxField({
|
|
1248
|
+
name,
|
|
1249
|
+
label,
|
|
1250
|
+
helpText,
|
|
1251
|
+
rules,
|
|
1252
|
+
testId,
|
|
1253
|
+
defaultValue,
|
|
1254
|
+
readOnly,
|
|
1255
|
+
className,
|
|
1256
|
+
optionFactory = defaultOptionFactory,
|
|
1257
|
+
...props
|
|
1258
|
+
}) {
|
|
1259
|
+
const { control, t, readOnly: formReadonly, formId } = useScmFormContext();
|
|
1260
|
+
const formPathPrefix = useScmFormPathContext();
|
|
1261
|
+
const nameWithPrefix = formPathPrefix ? `${formPathPrefix}.${name}` : name;
|
|
1262
|
+
const prefixedNameWithoutIndices = prefixWithoutIndices(nameWithPrefix);
|
|
1263
|
+
const labelTranslation = label || t(`${prefixedNameWithoutIndices}.label`) || "";
|
|
1264
|
+
const helpTextTranslation = helpText || t(`${prefixedNameWithoutIndices}.helpText`);
|
|
1265
|
+
return /* @__PURE__ */ React30.createElement(Controller6, {
|
|
1266
|
+
control,
|
|
1267
|
+
name: nameWithPrefix,
|
|
1268
|
+
rules,
|
|
1269
|
+
defaultValue,
|
|
1270
|
+
render: ({ field: { onChange, value, ...field }, fieldState }) => /* @__PURE__ */ React30.createElement(ComboboxField_default, {
|
|
1271
|
+
form: formId,
|
|
1272
|
+
readOnly: readOnly ?? formReadonly,
|
|
1273
|
+
className: classNames17("column", className),
|
|
1274
|
+
...props,
|
|
1275
|
+
...field,
|
|
1276
|
+
label: labelTranslation,
|
|
1277
|
+
helpText: helpTextTranslation,
|
|
1278
|
+
onChange: (e) => onChange(e == null ? void 0 : e.value),
|
|
1279
|
+
value: optionFactory(value),
|
|
1280
|
+
error: fieldState.error ? fieldState.error.message || t(`${prefixedNameWithoutIndices}.error.${fieldState.error.type}`) : void 0,
|
|
1281
|
+
testId: testId ?? `select-${nameWithPrefix}`
|
|
1282
|
+
})
|
|
1283
|
+
});
|
|
1284
|
+
}
|
|
1285
|
+
var ControlledComboboxField_default = ControlledComboboxField;
|
|
1286
|
+
|
|
1016
1287
|
// src/ConfigurationForm.tsx
|
|
1017
1288
|
import { useConfigLink } from "@scm-manager/ui-api";
|
|
1018
1289
|
import { Loading } from "@scm-manager/ui-components";
|
|
1019
|
-
import
|
|
1290
|
+
import React31 from "react";
|
|
1020
1291
|
import { useTranslation as useTranslation6 } from "react-i18next";
|
|
1021
1292
|
function ConfigurationForm({ link, children, ...formProps }) {
|
|
1022
1293
|
const { initialConfiguration, isReadOnly, update, isLoading } = useConfigLink(link);
|
|
1023
1294
|
const [t] = useTranslation6("commons", { keyPrefix: "form" });
|
|
1024
1295
|
if (isLoading || !initialConfiguration) {
|
|
1025
|
-
return /* @__PURE__ */
|
|
1296
|
+
return /* @__PURE__ */ React31.createElement(Loading, null);
|
|
1026
1297
|
}
|
|
1027
|
-
return /* @__PURE__ */
|
|
1298
|
+
return /* @__PURE__ */ React31.createElement(Form_default, {
|
|
1028
1299
|
onSubmit: update,
|
|
1029
1300
|
defaultValues: initialConfiguration,
|
|
1030
1301
|
readOnly: isReadOnly,
|
|
@@ -1134,10 +1405,13 @@ var Form2 = Object.assign(Form_default, {
|
|
|
1134
1405
|
Table: Object.assign(ControlledTable_default, {
|
|
1135
1406
|
Column: ControlledColumn_default
|
|
1136
1407
|
}),
|
|
1137
|
-
ChipInput: ControlledChipInputField_default
|
|
1408
|
+
ChipInput: ControlledChipInputField_default,
|
|
1409
|
+
Combobox: ControlledComboboxField_default
|
|
1138
1410
|
});
|
|
1139
1411
|
export {
|
|
1140
1412
|
ChipInputField_default as ChipInputField,
|
|
1413
|
+
Combobox_default as Combobox,
|
|
1414
|
+
ComboboxField_default as ComboboxField,
|
|
1141
1415
|
ConfigurationForm_default as ConfigurationForm,
|
|
1142
1416
|
Form2 as Form,
|
|
1143
1417
|
Select_default as Select,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scm-manager/ui-forms",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.44.
|
|
4
|
+
"version": "2.44.3-20230527-064447",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
7
7
|
"module": "build/index.mjs",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@scm-manager/eslint-config": "^2.16.0",
|
|
17
17
|
"@scm-manager/prettier-config": "^2.10.1",
|
|
18
18
|
"@scm-manager/tsconfig": "^2.13.0",
|
|
19
|
-
"@scm-manager/ui-styles": "2.44.
|
|
19
|
+
"@scm-manager/ui-styles": "2.44.3-20230527-064447",
|
|
20
20
|
"@storybook/addon-actions": "^6.5.10",
|
|
21
21
|
"@storybook/addon-essentials": "^6.5.10",
|
|
22
22
|
"@storybook/addon-interactions": "^6.5.10",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"tsup": "^6.2.3"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@scm-manager/ui-components": "2.44.
|
|
35
|
+
"@scm-manager/ui-components": "2.44.3-20230527-064447",
|
|
36
36
|
"classnames": "^2.3.1",
|
|
37
37
|
"react": "17",
|
|
38
38
|
"react-hook-form": "7",
|
|
@@ -41,9 +41,10 @@
|
|
|
41
41
|
"styled-components": "5"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@scm-manager/ui-buttons": "2.44.
|
|
45
|
-
"@scm-manager/ui-overlays": "2.44.
|
|
46
|
-
"@scm-manager/ui-api": "2.44.
|
|
44
|
+
"@scm-manager/ui-buttons": "2.44.3-20230527-064447",
|
|
45
|
+
"@scm-manager/ui-overlays": "2.44.3-20230527-064447",
|
|
46
|
+
"@scm-manager/ui-api": "2.44.3-20230527-064447",
|
|
47
|
+
"@headlessui/react": "^1.7.15",
|
|
47
48
|
"@radix-ui/react-slot": "^1.0.1",
|
|
48
49
|
"@radix-ui/react-visually-hidden": "^1.0.3"
|
|
49
50
|
},
|