@koine/react 1.0.3 → 1.0.8

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.
Files changed (159) hide show
  1. package/Alert/Alert.js +18 -0
  2. package/Alert/index.js +1 -0
  3. package/Animations/Reveal.js +17 -0
  4. package/Animations/Underline.js +15 -0
  5. package/Animations/index.js +3 -0
  6. package/Animations/useReveal.js +70 -0
  7. package/Autocomplete/AutocompleteDownshift.js +158 -0
  8. package/Autocomplete/AutocompleteDownshiftMultiselect.js +353 -0
  9. package/Autocomplete/AutocompleteMui.js +172 -0
  10. package/Autocomplete/AutocompleteReach.js +112 -0
  11. package/Autocomplete/components.js +89 -0
  12. package/Autocomplete/helpers.js +28 -0
  13. package/Autocomplete/index.js +3 -0
  14. package/Bg/BgColor.js +33 -0
  15. package/Bg/BgPhoto.js +59 -0
  16. package/Bg/BgSvg.js +15 -0
  17. package/Bg/index.js +3 -0
  18. package/Breadcrumbs/Breadcrumbs.js +70 -0
  19. package/Breadcrumbs/index.js +1 -0
  20. package/Buttons/Button.js +79 -0
  21. package/Buttons/ButtonComposite.d.ts +1 -1
  22. package/Buttons/ButtonComposite.js +53 -0
  23. package/Buttons/ButtonFab.js +8 -0
  24. package/Buttons/ButtonLink.js +16 -0
  25. package/Buttons/IconButton.js +19 -0
  26. package/Buttons/index.js +5 -0
  27. package/Calendar/CalendarDaygridCell.js +52 -0
  28. package/Calendar/CalendarDaygridNav.js +23 -0
  29. package/Calendar/CalendarDaygridTable.js +49 -0
  30. package/Calendar/CalendarLegend.js +12 -0
  31. package/Calendar/calendar-api-google.js +97 -0
  32. package/Calendar/index.js +6 -0
  33. package/Calendar/types.js +1 -0
  34. package/Calendar/useCalendar.js +166 -0
  35. package/Calendar/utils.js +197 -0
  36. package/Carousel/Carousel.js +378 -0
  37. package/Carousel/CarouselCss.js +39 -0
  38. package/Carousel/index.js +1 -0
  39. package/Collapsable/Collapsable.js +132 -0
  40. package/Collapsable/index.js +1 -0
  41. package/Debug/Debug.js +21 -0
  42. package/Debug/index.js +1 -0
  43. package/Dialog/Dialog.js +93 -0
  44. package/Dialog/index.js +1 -0
  45. package/Editor/Editor--tiptap.js +21 -0
  46. package/Editor/components.d.ts +1 -2
  47. package/Editor/components.js +28 -0
  48. package/Editor/index.js +1 -0
  49. package/Favicon/FaviconTags.js +14 -0
  50. package/Favicon/index.js +1 -0
  51. package/Forms/Checkbox/Checkbox.js +24 -0
  52. package/Forms/Checkbox/index.js +1 -0
  53. package/Forms/Feedback/Feedback.js +10 -0
  54. package/Forms/Feedback/index.js +1 -0
  55. package/Forms/Field/Field.js +61 -0
  56. package/Forms/Field/FieldControl.js +45 -0
  57. package/Forms/Field/FieldHint.js +6 -0
  58. package/Forms/Field/index.js +2 -0
  59. package/Forms/Form/Form.js +64 -0
  60. package/Forms/Form/index.js +1 -0
  61. package/Forms/Input/Input.js +25 -0
  62. package/Forms/Input/index.js +1 -0
  63. package/Forms/InputGroup/InputGroup.js +42 -0
  64. package/Forms/InputGroup/index.js +1 -0
  65. package/Forms/Label/Label.js +24 -0
  66. package/Forms/Label/index.js +1 -0
  67. package/Forms/Password/Password.js +32 -0
  68. package/Forms/Password/index.js +1 -0
  69. package/Forms/Radio/Radio.js +31 -0
  70. package/Forms/Radio/index.js +1 -0
  71. package/Forms/Switch/Switch.js +50 -0
  72. package/Forms/Switch/index.js +1 -0
  73. package/Forms/Textarea/Textarea.js +15 -0
  74. package/Forms/Textarea/TextareaRich.js +44 -0
  75. package/Forms/Textarea/index.js +2 -0
  76. package/Forms/Toggle/Toggle.js +79 -0
  77. package/Forms/Toggle/index.js +1 -0
  78. package/Forms/Toggle/useToggle.js +143 -0
  79. package/Forms/antispam.js +56 -0
  80. package/Forms/helpers.js +44 -0
  81. package/Forms/index.js +17 -0
  82. package/Forms/styles.js +60 -0
  83. package/Gauge/Gauge.js +102 -0
  84. package/Grid/Grid.js +79 -0
  85. package/Grid/index.js +1 -0
  86. package/Hamburger/Hamburger.js +55 -0
  87. package/Hamburger/index.js +1 -0
  88. package/Header/index.js +1 -0
  89. package/Header/useHeader.js +30 -0
  90. package/Hidden/Hidden.js +14 -0
  91. package/Hidden/index.js +1 -0
  92. package/Img/Img.js +34 -0
  93. package/Img/index.js +1 -0
  94. package/Link/Link.js +2 -0
  95. package/Link/LinkBlank.d.ts +1 -1
  96. package/Link/LinkBlank.js +28 -0
  97. package/Link/index.js +2 -0
  98. package/Menu/Menu.js +11 -0
  99. package/Menu/index.js +1 -0
  100. package/MenuItem/MenuItem.js +20 -0
  101. package/MenuItem/index.js +1 -0
  102. package/Meta/Meta.js +4 -0
  103. package/Meta/index.js +1 -0
  104. package/NoJs/NoJs.js +6 -0
  105. package/NoJs/index.js +1 -0
  106. package/Pagination/PaginationNav.js +87 -0
  107. package/Pagination/PaginationResults.js +10 -0
  108. package/Pagination/index.js +2 -0
  109. package/Pill/Pill.js +37 -0
  110. package/Pill/index.js +1 -0
  111. package/Progress/ProgressCircular.js +38 -0
  112. package/Progress/ProgressLinear.js +34 -0
  113. package/Progress/ProgressOverlay.js +40 -0
  114. package/Progress/index.js +3 -0
  115. package/Rating/Rating.js +93 -0
  116. package/Rating/index.js +45 -0
  117. package/Select/SelectDownshift.js +38 -0
  118. package/Select/components.js +20 -0
  119. package/Select/index.js +3 -0
  120. package/Sidebar/Sidebar.js +48 -0
  121. package/Sidebar/index.js +1 -0
  122. package/Spacing/Spacing.js +47 -0
  123. package/Spacing/index.js +1 -0
  124. package/Sticky/Sticky.js +220 -0
  125. package/Sticky/StickyCss.js +6 -0
  126. package/Sticky/index.js +1 -0
  127. package/Tabs/Tabs.js +67 -0
  128. package/Tabs/index.js +1 -0
  129. package/Typography/CopyPasteVisible.js +6 -0
  130. package/Typography/Native.js +47 -0
  131. package/Typography/ReadMore.js +71 -0
  132. package/Typography/TextLoop.js +45 -0
  133. package/Typography/TypeStairs.js +46 -0
  134. package/Typography/index.js +5 -0
  135. package/helpers/index.js +19 -0
  136. package/hooks/index.js +5 -0
  137. package/hooks/useDateLocale.js +30 -0
  138. package/hooks/useFocus.js +11 -0
  139. package/hooks/usePrevious.js +8 -0
  140. package/hooks/useTraceUpdate.js +20 -0
  141. package/hooks/useWindowSize.js +13 -0
  142. package/index.js +36 -0
  143. package/index.umd.js +234 -257
  144. package/package.json +15 -9
  145. package/styles/Body.js +17 -0
  146. package/styles/Global.js +50 -0
  147. package/styles/classed.js +11 -0
  148. package/styles/index.js +7 -0
  149. package/styles/media.js +150 -0
  150. package/styles/spacing.d.ts +6 -6
  151. package/styles/spacing.js +46 -0
  152. package/styles/styled.d.ts +2 -2
  153. package/styles/styled.js +27 -0
  154. package/styles/theme--vanilla.js +53 -0
  155. package/styles/theme.d.ts +0 -7
  156. package/styles/theme.js +38 -0
  157. package/types.js +1 -0
  158. package/typings.d.ts +21 -0
  159. package/index.esm.js +0 -9472
package/Alert/Alert.js ADDED
@@ -0,0 +1,18 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import styled from "styled-components";
4
+ const AlertRoot = styled.div `
5
+ font-size: 12px;
6
+ ${(p) => (p.$danger ? `color: var(--danger)` : "")}
7
+ `;
8
+ const AlertInner = styled.div `
9
+ padding: 1em;
10
+ background-color: rgba(0, 0, 0, 0.05);
11
+ /* border: 1px solid var(--grey700); */
12
+ /* background: pink; */
13
+ /* color: red; */
14
+ `;
15
+ export const Alert = (_a) => {
16
+ var { $danger, children } = _a, props = __rest(_a, ["$danger", "children"]);
17
+ return (_jsx(AlertRoot, Object.assign({ "$danger": $danger }, props, { children: _jsx(AlertInner, { children: children }) })));
18
+ };
package/Alert/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from "./Alert";
@@ -0,0 +1,17 @@
1
+ import { __rest } from "tslib";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { motion, useViewportScroll, useTransform, useSpring, useReducedMotion, } from "framer-motion";
4
+ import { useReveal } from "./useReveal";
5
+ export const Reveal = (_a) => {
6
+ var { children, direction, offsetStartY, offsetEndY, offsetStartX } = _a, props = __rest(_a, ["children", "direction", "offsetStartY", "offsetEndY", "offsetStartX"]);
7
+ const effectOptions = { direction, offsetStartY, offsetEndY, offsetStartX };
8
+ const prefersReducedMotion = useReducedMotion();
9
+ const { ref, startY, endY, startX } = useReveal(effectOptions);
10
+ const { scrollYProgress } = useViewportScroll();
11
+ const xRange = useTransform(scrollYProgress, [startY, endY], [startX, 0]);
12
+ const opacityRange = useTransform(scrollYProgress, [startY, endY], [0, 1]);
13
+ const x = useSpring(xRange, { stiffness: 400, damping: 90 });
14
+ const opacity = useSpring(opacityRange);
15
+ // console.log("start, end", startY, endY)
16
+ return (_jsx(motion.div, Object.assign({}, props, { ref: ref, style: prefersReducedMotion ? {} : { x, opacity } }, { children: children })));
17
+ };
@@ -0,0 +1,15 @@
1
+ import styled from "styled-components";
2
+ import { m } from "framer-motion";
3
+ export const UnderlineSkewed = styled(m.i) `
4
+ display: block;
5
+ position: absolute;
6
+ top: 50%;
7
+ left: 15%;
8
+ right: 15%;
9
+ height: 20px;
10
+ margin-top: -10px;
11
+ z-index: 0;
12
+ pointer-events: none;
13
+ background: var(--accent400);
14
+ transform: skewY(-5deg);
15
+ `;
@@ -0,0 +1,3 @@
1
+ export * from "./Reveal";
2
+ export * from "./Underline";
3
+ export * from "./useReveal";
@@ -0,0 +1,70 @@
1
+ import { useRef, useState, useEffect } from "react";
2
+ export function useReveal({ direction = "left", offsetStartY = -2, offsetEndY = 0, offsetStartX = "all", }) {
3
+ const ref = useRef(null);
4
+ const [startY, setStartY] = useState(0);
5
+ const [endY, setEndY] = useState(0);
6
+ const [startX, setStartX] = useState(0);
7
+ useEffect(() => {
8
+ if (!ref.current) {
9
+ return;
10
+ }
11
+ const rect = ref.current.getBoundingClientRect();
12
+ // scroll position from top of the window
13
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
14
+ const elementHeight = rect.height;
15
+ // rect.top is the distance from the currently visible viewport to the top
16
+ // of the given element
17
+ // so distanceTop is the distance between the top edge of the window and the
18
+ // top edge of the given element
19
+ const elementTop = rect.top;
20
+ const distanceTop = elementTop + scrollTop;
21
+ const offsetTop = offsetStartY ? elementHeight * offsetStartY : 0;
22
+ const offsetBottom = offsetEndY ? elementHeight * offsetEndY : offsetTop;
23
+ // the distance of the element from the top divided by the full height
24
+ // of the window gives back the start position of the given element in
25
+ // a scale from 0 to 1
26
+ const startY = (distanceTop + offsetTop) / document.body.clientHeight;
27
+ // same for the end, we just add the given element height to the first value
28
+ const endY = (distanceTop + elementHeight + offsetBottom) / document.body.clientHeight;
29
+ let startX;
30
+ if (offsetStartX === "all") {
31
+ startX = direction === "left" ? -rect.right : rect.left;
32
+ }
33
+ else {
34
+ startX = rect.width * offsetStartX;
35
+ startX = direction === "left" ? -startX : startX;
36
+ }
37
+ // addMarker(startY + "px");
38
+ // addMarker(endY + "px");
39
+ // console.log("start", startY, "end", endY, "startX", startX)
40
+ setStartY(startY);
41
+ setEndY(endY);
42
+ setStartX(startX);
43
+ // addMarker(startY * 100 + "%", "blue", "fixed");
44
+ // addMarker(endY * 100 + "%", "blue", "fixed");
45
+ }, [
46
+ setStartY,
47
+ setEndY,
48
+ setStartX,
49
+ offsetStartY,
50
+ offsetEndY,
51
+ offsetStartX,
52
+ direction,
53
+ ]);
54
+ return { ref, startY, endY, startX };
55
+ }
56
+ // function addMarker(top: string, color = "red", position = "absolute") {
57
+ // const div = document.createElement("div");
58
+ // div.setAttribute(
59
+ // "style",
60
+ // `
61
+ // position: ${position};
62
+ // top: ${top};
63
+ // left: 0;
64
+ // right: 0;
65
+ // height: 1px;
66
+ // background: ${color};
67
+ // `
68
+ // );
69
+ // document.body.appendChild(div);
70
+ // }
@@ -0,0 +1,158 @@
1
+ // TODO: remove, just use mui version...
2
+ export const Autocomplete = null;
3
+ // import {
4
+ // forwardRef,
5
+ // useCallback,
6
+ // useState,
7
+ // ForwardedRef,
8
+ // ReactNode,
9
+ // ComponentPropsWithRef,
10
+ // CSSProperties,
11
+ // } from "react";
12
+ // import { useCombobox } from "downshift";
13
+ // import { SetRequired } from "@koine/utils";
14
+ // // import debounce from "lodash.debounce";
15
+ // import {
16
+ // AutocompleteRoot,
17
+ // AutocompleteLabel,
18
+ // AutocompleteInputWrap,
19
+ // AutocompleteInput,
20
+ // AutocompleteInputArrow,
21
+ // AutocompleteMenu,
22
+ // AutocompleteMenuItem,
23
+ // } from "./components";
24
+ // import { defaultOptionsFilterFn, triggerOnChange } from "../Forms/helpers";
25
+ // import { InputProgress } from "../Forms/styles";
26
+ // export type AutocompleteOption = Option;
27
+ // export type AutocompleteValue = null | AutocompleteOption;
28
+ // export type AutocompleteProps = SetRequired<
29
+ // Omit<ComponentPropsWithRef<"input">, "onSelect">,
30
+ // "onChange" | "name"
31
+ // > & {
32
+ // freeSolo?: boolean;
33
+ // onSelect?: (option?: AutocompleteValue) => any;
34
+ // options?: AutocompleteOption[];
35
+ // loadOptions: (query?: string) => Promise<AutocompleteOption[]>;
36
+ // label?: string | ReactNode;
37
+ // className?: string;
38
+ // style?: CSSProperties;
39
+ // $ref: ForwardedRef<HTMLInputElement>;
40
+ // };
41
+ // export const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(
42
+ // function Autocomplete(
43
+ // {
44
+ // freeSolo,
45
+ // onSelect,
46
+ // options = [],
47
+ // label,
48
+ // name,
49
+ // value,
50
+ // onChange,
51
+ // loadOptions,
52
+ // className,
53
+ // style,
54
+ // $ref,
55
+ // ...props
56
+ // },
57
+ // ref
58
+ // ) {
59
+ // const [items, setItems] = useState(options);
60
+ // const [loading, setLoading] = useState(false);
61
+ // const triggerChange = useCallback(
62
+ // (selectedItem?: AutocompleteValue, inputValue?: string) => {
63
+ // const value = freeSolo ? inputValue : selectedItem?.value;
64
+ // triggerOnChange(onChange, name, value || "");
65
+ // if (onSelect) onSelect(selectedItem);
66
+ // },
67
+ // [onChange, onSelect, name, freeSolo]
68
+ // );
69
+ // const handleInputValueChange = useCallback(
70
+ // async ({ inputValue }) => {
71
+ // if (inputValue) {
72
+ // if (loadOptions) {
73
+ // setLoading(true);
74
+ // try {
75
+ // const newOptions = await loadOptions(inputValue);
76
+ // setItems(newOptions);
77
+ // } catch (e) {}
78
+ // setLoading(false);
79
+ // } else {
80
+ // setItems(defaultOptionsFilterFn(options, inputValue));
81
+ // }
82
+ // } else {
83
+ // setItems(options);
84
+ // // clear like behaviour
85
+ // triggerChange({ value: "", label: "" });
86
+ // }
87
+ // },
88
+ // [loadOptions, triggerChange]
89
+ // );
90
+ // const {
91
+ // isOpen,
92
+ // // selectedItem,
93
+ // getToggleButtonProps,
94
+ // getLabelProps,
95
+ // getMenuProps,
96
+ // getInputProps,
97
+ // getComboboxProps,
98
+ // highlightedIndex,
99
+ // getItemProps,
100
+ // openMenu,
101
+ // } = useCombobox<null | AutocompleteOption>({
102
+ // id: `Autocomplete-${name}`,
103
+ // items,
104
+ // // initialInputValue: value,
105
+ // onSelectedItemChange: ({ selectedItem, inputValue }) => {
106
+ // triggerChange(selectedItem, inputValue);
107
+ // },
108
+ // // itemToString: (item) => (item ? item.label || item.value : ""),
109
+ // onInputValueChange: handleInputValueChange,
110
+ // });
111
+ // // const debouncedInputValueChangeHandler = useCallback(
112
+ // // debounce(handleInputValueChange, 200),
113
+ // // [handleInputValueChange]
114
+ // // );
115
+ // return (
116
+ // <AutocompleteRoot className={className} style={style}>
117
+ // {label && (
118
+ // <AutocompleteLabel {...getLabelProps()}>{label}</AutocompleteLabel>
119
+ // )}
120
+ // <AutocompleteInputWrap {...getComboboxProps()}>
121
+ // <AutocompleteInput
122
+ // {...getInputProps({
123
+ // onFocus: openMenu,
124
+ // onClick: openMenu,
125
+ // ref: $ref || ref,
126
+ // // itemRef: ref,
127
+ // })}
128
+ // {...props}
129
+ // />
130
+ // {!!items.length && (
131
+ // <AutocompleteInputArrow
132
+ // {...getToggleButtonProps()}
133
+ // aria-label={"toggle menu"}
134
+ // />
135
+ // )}
136
+ // {loading && <InputProgress />}
137
+ // </AutocompleteInputWrap>
138
+ // <AutocompleteMenu {...getMenuProps()}>
139
+ // {isOpen &&
140
+ // items
141
+ // // .filter(item => !inputValue || item.includes(inputValue))
142
+ // .map(
143
+ // (item, index) =>
144
+ // item && (
145
+ // <AutocompleteMenuItem
146
+ // $active={highlightedIndex === index}
147
+ // key={`${item.value}${index}`}
148
+ // {...getItemProps({ item, index })}
149
+ // >
150
+ // {item.label}
151
+ // </AutocompleteMenuItem>
152
+ // )
153
+ // )}
154
+ // </AutocompleteMenu>
155
+ // </AutocompleteRoot>
156
+ // );
157
+ // }
158
+ // );
@@ -0,0 +1,353 @@
1
+ // TODO: remove, just use mui version...
2
+ export const Autocomplete = null;
3
+ // import {
4
+ // forwardRef,
5
+ // useCallback,
6
+ // useEffect,
7
+ // useRef,
8
+ // useState,
9
+ // ForwardedRef,
10
+ // ReactNode,
11
+ // ComponentPropsWithRef,
12
+ // CSSProperties,
13
+ // } from "react";
14
+ // import { SetRequired } from "@koine/utils";
15
+ // import {
16
+ // useCombobox,
17
+ // useMultipleSelection,
18
+ // UseMultipleSelectionProps,
19
+ // UseMultipleSelectionStateChange,
20
+ // UseMultipleSelectionReturnValue,
21
+ // } from "downshift";
22
+ // import { usePopper } from "react-popper"; // imports from downshift demo
23
+ // // import { useDeepCompareEffect } from "react-use"; // imports from downshift demo
24
+ // import type { Option } from "../types";
25
+ // import {
26
+ // normaliseOptions,
27
+ // defaultOptionsFilterFn,
28
+ // triggerOnChange,
29
+ // } from "../Forms/helpers";
30
+ // import {
31
+ // AutocompleteRoot,
32
+ // AutocompleteLabel,
33
+ // AutocompleteWrap,
34
+ // AutocompleteInner,
35
+ // AutocompleteItem,
36
+ // AutocompleteItemLabel,
37
+ // AutocompleteItemRemove,
38
+ // AutocompleteInputWrap,
39
+ // AutocompleteInput,
40
+ // AutocompleteInputArrow,
41
+ // AutocompleteMenu,
42
+ // AutocompleteMenuItem,
43
+ // } from "./components";
44
+ // const USE_POPPER = false;
45
+ // export type AutocompleteItem = Option;
46
+ // export type AutocompleteValue = AutocompleteItem[];
47
+ // export type AutocompleteProps = SetRequired<
48
+ // Omit<ComponentPropsWithRef<"input">, "defaultValue" | "onSelect">,
49
+ // "onChange" | "name"
50
+ // > & {
51
+ // selectedItems: UseMultipleSelectionReturnValue<AutocompleteItem>["selectedItems"];
52
+ // onSelectedItemsChange: UseMultipleSelectionProps<AutocompleteItem>["onSelectedItemsChange"];
53
+ // onCreateItem: (item?: AutocompleteItem) => any;
54
+ // creatable?: boolean;
55
+ // onSelect?: (value?: AutocompleteValue) => any;
56
+ // options?: AutocompleteItem[];
57
+ // loadOptions?: (query?: string) => Promise<AutocompleteItem[]>;
58
+ // label?: string | ReactNode;
59
+ // defaultValue?: AutocompleteValue | string[];
60
+ // className?: string;
61
+ // style?: CSSProperties;
62
+ // $ref?: ForwardedRef<HTMLInputElement>;
63
+ // };
64
+ // /**
65
+ // * @see https://www.downshift-js.com/use-multiple-selection
66
+ // * @see https://codesandbox.io/s/y34o5l3p61?file=/src/hooks/useMultipleSelection/combobox.js
67
+ // * @see https://codesandbox.io/s/y34o5l3p61?file=/src/downshift/ordered-examples/05-multi-create.js
68
+ // */
69
+ // export const _Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(
70
+ // function _Autocomplete(
71
+ // {
72
+ // selectedItems,
73
+ // onSelectedItemsChange,
74
+ // onCreateItem,
75
+ // creatable,
76
+ // onSelect,
77
+ // options = [],
78
+ // label,
79
+ // loadOptions,
80
+ // $ref,
81
+ // className,
82
+ // style,
83
+ // ...props
84
+ // },
85
+ // ref
86
+ // ) {
87
+ // options = normaliseOptions(options);
88
+ // const [isCreating, setIsCreating] = useState(false);
89
+ // const [filteredOptions, setFilteredOptions] = useState(options);
90
+ // const disclosureRef = useRef(null);
91
+ // const popoverRef = useRef(null);
92
+ // const { styles, attributes } = USE_POPPER
93
+ // ? usePopper(disclosureRef.current, popoverRef.current, {
94
+ // placement: "bottom-start",
95
+ // })
96
+ // : { styles: {}, attributes: {} };
97
+ // const {
98
+ // getSelectedItemProps,
99
+ // getDropdownProps,
100
+ // addSelectedItem,
101
+ // removeSelectedItem,
102
+ // // selectedItems,
103
+ // activeIndex,
104
+ // } = useMultipleSelection<AutocompleteItem>({
105
+ // selectedItems,
106
+ // onSelectedItemsChange,
107
+ // // onSelectedItemsChange: ({ selectedItems = [] }) => {
108
+ // // triggerChange(selectedItems);
109
+ // // },
110
+ // // initialSelectedItems: normaliseOptions(defaultValue),
111
+ // stateReducer: (_, actionAndChanges) => {
112
+ // const { type, changes } = actionAndChanges;
113
+ // switch (type) {
114
+ // case useMultipleSelection.stateChangeTypes.FunctionRemoveSelectedItem:
115
+ // return {
116
+ // ...changes,
117
+ // activeIndex: undefined,
118
+ // };
119
+ // default:
120
+ // return changes;
121
+ // }
122
+ // },
123
+ // });
124
+ // const selectedItemsValues = selectedItems.map((item) => item.value);
125
+ // const {
126
+ // isOpen,
127
+ // getToggleButtonProps,
128
+ // getLabelProps,
129
+ // getMenuProps,
130
+ // getInputProps,
131
+ // getComboboxProps,
132
+ // highlightedIndex,
133
+ // getItemProps,
134
+ // openMenu,
135
+ // selectItem,
136
+ // setHighlightedIndex,
137
+ // inputValue,
138
+ // } = useCombobox<null | AutocompleteItem>({
139
+ // selectedItem: null,
140
+ // items: filteredOptions,
141
+ // onInputValueChange: ({ inputValue }) => {
142
+ // // perhaps allows the optionsFilterFn as prop
143
+ // const filteredItems = defaultOptionsFilterFn(options, inputValue);
144
+ // if (creatable && isCreating && filteredItems.length > 0) {
145
+ // setIsCreating(false);
146
+ // }
147
+ // setFilteredOptions(filteredItems);
148
+ // },
149
+ // stateReducer: (state, actionAndChanges) => {
150
+ // const { changes, type } = actionAndChanges;
151
+ // switch (type) {
152
+ // case useCombobox.stateChangeTypes.InputBlur:
153
+ // return {
154
+ // ...changes,
155
+ // highlightedIndex: state.highlightedIndex,
156
+ // // clear input on blur to avoid have "pending" uncompleted behaviours
157
+ // inputValue: "",
158
+ // };
159
+ // case useCombobox.stateChangeTypes.InputKeyDownEnter:
160
+ // case useCombobox.stateChangeTypes.ItemClick:
161
+ // return {
162
+ // ...changes,
163
+ // highlightedIndex: state.highlightedIndex,
164
+ // isOpen: true,
165
+ // inputValue: "",
166
+ // };
167
+ // default:
168
+ // return changes;
169
+ // }
170
+ // },
171
+ // onStateChange: ({ type, selectedItem }) => {
172
+ // switch (type) {
173
+ // case useCombobox.stateChangeTypes.InputKeyDownEnter:
174
+ // case useCombobox.stateChangeTypes.ItemClick:
175
+ // if (selectedItem) {
176
+ // if (selectedItemsValues.includes(selectedItem.value)) {
177
+ // removeSelectedItem(selectedItem);
178
+ // } else {
179
+ // if (creatable && onCreateItem) {
180
+ // onCreateItem(selectedItem);
181
+ // }
182
+ // addSelectedItem(selectedItem);
183
+ // if (isCreating) {
184
+ // setIsCreating(false);
185
+ // setFilteredOptions(options);
186
+ // }
187
+ // }
188
+ // selectItem(null);
189
+ // }
190
+ // break;
191
+ // default:
192
+ // break;
193
+ // }
194
+ // },
195
+ // });
196
+ // useEffect(() => {
197
+ // if (
198
+ // creatable &&
199
+ // filteredOptions.length === 0 &&
200
+ // activeIndex === -1 &&
201
+ // inputValue.length > 0
202
+ // ) {
203
+ // setIsCreating(true);
204
+ // setFilteredOptions(normaliseOptions([inputValue]));
205
+ // setHighlightedIndex(0);
206
+ // }
207
+ // }, [
208
+ // creatable,
209
+ // filteredOptions,
210
+ // setIsCreating,
211
+ // setHighlightedIndex,
212
+ // inputValue,
213
+ // activeIndex,
214
+ // ]);
215
+ // // useEffect(() => {
216
+ // // setSelectedItems(normaliseOptions(defaultValue));
217
+ // // }, [defaultValue]);
218
+ // // useDeepCompareEffect(() => {
219
+ // // setFilteredOptions(options);
220
+ // // }, [options]);
221
+ // // useDeepCompareEffect(() => {
222
+ // // triggerChange(values);
223
+ // // }, [values]);
224
+ // return (
225
+ // <AutocompleteRoot>
226
+ // {label && (
227
+ // <AutocompleteLabel {...getLabelProps()}>{label}</AutocompleteLabel>
228
+ // )}
229
+ // <AutocompleteWrap
230
+ // {...getComboboxProps({
231
+ // ref: disclosureRef,
232
+ // })}
233
+ // >
234
+ // <AutocompleteInner>
235
+ // {selectedItems.map((selectedItem, index) => (
236
+ // <AutocompleteItem
237
+ // key={`selected-item-${index}`}
238
+ // {...getSelectedItemProps({ selectedItem, index })}
239
+ // >
240
+ // <AutocompleteItemLabel>
241
+ // {selectedItem?.label || selectedItem}
242
+ // </AutocompleteItemLabel>
243
+ // <AutocompleteItemRemove
244
+ // onClick={(e) => {
245
+ // e.stopPropagation();
246
+ // removeSelectedItem(selectedItem);
247
+ // }}
248
+ // >
249
+ // &#10005;
250
+ // </AutocompleteItemRemove>
251
+ // </AutocompleteItem>
252
+ // ))}
253
+ // <AutocompleteInputWrap>
254
+ // <AutocompleteInput
255
+ // {...getInputProps({
256
+ // ...getDropdownProps({
257
+ // // this option used in the official example prevents the
258
+ // // backspace key to behave correctly
259
+ // // preventKeyAction: isOpen,
260
+ // onClick: isOpen ? () => {} : openMenu,
261
+ // onFocus: isOpen ? () => {} : openMenu,
262
+ // ref: $ref || ref,
263
+ // // ref: disclosureRef,
264
+ // }),
265
+ // // ref: $ref || ref,
266
+ // })}
267
+ // {...props}
268
+ // />
269
+ // </AutocompleteInputWrap>
270
+ // </AutocompleteInner>
271
+ // {!!filteredOptions.length && (
272
+ // <AutocompleteInputArrow
273
+ // {...getToggleButtonProps()}
274
+ // aria-label={"toggle menu"}
275
+ // isOpen={isOpen}
276
+ // />
277
+ // )}
278
+ // </AutocompleteWrap>
279
+ // <AutocompleteMenu
280
+ // style={styles.popper}
281
+ // {...attributes.popper}
282
+ // {...getMenuProps({ ref: popoverRef })}
283
+ // >
284
+ // {isOpen &&
285
+ // filteredOptions.map((item, index) => (
286
+ // <AutocompleteMenuItem
287
+ // $active={highlightedIndex === index}
288
+ // key={`${item.value}${index}`}
289
+ // {...getItemProps({ item, index })}
290
+ // >
291
+ // {isCreating ? (
292
+ // <>
293
+ // <span>+</span> <strong>{item.label}</strong>
294
+ // </>
295
+ // ) : (
296
+ // <>
297
+ // {/* {selectedItemsValues.includes(item.value) && (
298
+ // <CheckboxToggle />
299
+ // )} */}
300
+ // {item.label}
301
+ // </>
302
+ // )}
303
+ // </AutocompleteMenuItem>
304
+ // ))}
305
+ // </AutocompleteMenu>
306
+ // </AutocompleteRoot>
307
+ // );
308
+ // }
309
+ // );
310
+ // /**
311
+ // * @see https://www.downshift-js.com/use-multiple-selection
312
+ // * @see https://codesandbox.io/s/y34o5l3p61?file=/src/hooks/useMultipleSelection/combobox.js
313
+ // * @see https://codesandbox.io/s/y34o5l3p61?file=/src/downshift/ordered-examples/05-multi-create.js
314
+ // */
315
+ // export const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(
316
+ // function Autocomplete(
317
+ // { defaultValue = [], onChange, onSelect, name, ...props },
318
+ // ref
319
+ // ) {
320
+ // const [selectedItems, setSelectedItems] = useState(
321
+ // normaliseOptions(defaultValue)
322
+ // );
323
+ // const triggerChange = useCallback(
324
+ // (values: AutocompleteValue) => {
325
+ // triggerOnChange(
326
+ // onChange,
327
+ // name,
328
+ // values.map((item) => item.value || item)
329
+ // );
330
+ // if (onSelect) onSelect(values);
331
+ // },
332
+ // [onChange, onSelect, name]
333
+ // );
334
+ // const handleCreateItem = (item?: AutocompleteItem) => {
335
+ // // setSelectedItems((curr) => [...curr, item]);
336
+ // };
337
+ // const handleSelectedItemsChange = ({
338
+ // selectedItems = [],
339
+ // }: UseMultipleSelectionStateChange<AutocompleteItem>) => {
340
+ // setSelectedItems(selectedItems);
341
+ // triggerChange(selectedItems);
342
+ // };
343
+ // return (
344
+ // <_Autocomplete
345
+ // {...props}
346
+ // selectedItems={selectedItems}
347
+ // onSelectedItemsChange={handleSelectedItemsChange}
348
+ // onCreateItem={handleCreateItem}
349
+ // $ref={ref}
350
+ // />
351
+ // );
352
+ // }
353
+ // );