@koobiq/react-components 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ActionsPanel/ActionPanel.module.css.js +17 -0
- package/dist/components/ActionsPanel/ActionsPanel.d.ts +11 -0
- package/dist/components/ActionsPanel/ActionsPanel.js +170 -0
- package/dist/components/ActionsPanel/ActionsPanelContext.d.ts +3 -0
- package/dist/components/ActionsPanel/ActionsPanelContext.js +6 -0
- package/dist/components/ActionsPanel/components/ActionsPanelAction/ActionsPanelAction.d.ts +2 -0
- package/dist/components/ActionsPanel/components/ActionsPanelAction/ActionsPanelAction.js +22 -0
- package/dist/components/ActionsPanel/components/ActionsPanelAction/ActionsPanelAction.module.css.js +8 -0
- package/dist/components/ActionsPanel/components/ActionsPanelAction/index.d.ts +2 -0
- package/dist/components/ActionsPanel/components/ActionsPanelAction/types.d.ts +5 -0
- package/dist/components/ActionsPanel/components/ActionsPanelClearButton/ActionsPanelClearButton.d.ts +5 -0
- package/dist/components/ActionsPanel/components/ActionsPanelClearButton/ActionsPanelClearButton.js +30 -0
- package/dist/components/ActionsPanel/components/ActionsPanelClearButton/ActionsPanelClearButton.module.css.js +8 -0
- package/dist/components/ActionsPanel/components/ActionsPanelClearButton/index.d.ts +1 -0
- package/dist/components/ActionsPanel/components/ActionsPanelContainer/ActionPanelContainer.module.css.js +11 -0
- package/dist/components/ActionsPanel/components/ActionsPanelContainer/ActionsPanelContainer.d.ts +2 -0
- package/dist/components/ActionsPanel/components/ActionsPanelContainer/ActionsPanelContainer.js +32 -0
- package/dist/components/ActionsPanel/components/ActionsPanelContainer/index.d.ts +2 -0
- package/dist/components/ActionsPanel/components/ActionsPanelContainer/types.d.ts +5 -0
- package/dist/components/ActionsPanel/components/ActionsPanelCounter/ActionsPanelCounter.d.ts +6 -0
- package/dist/components/ActionsPanel/components/ActionsPanelCounter/ActionsPanelCounter.js +44 -0
- package/dist/components/ActionsPanel/components/ActionsPanelCounter/ActionsPanelCounter.module.css.js +17 -0
- package/dist/components/ActionsPanel/components/ActionsPanelCounter/index.d.ts +1 -0
- package/dist/components/ActionsPanel/components/ActionsPanelDivider/ActionsPanelDivider.d.ts +3 -0
- package/dist/components/ActionsPanel/components/ActionsPanelDivider/ActionsPanelDivider.js +18 -0
- package/dist/components/ActionsPanel/components/ActionsPanelDivider/ActionsPanelDivider.module.css.js +8 -0
- package/dist/components/ActionsPanel/components/ActionsPanelDivider/index.d.ts +1 -0
- package/dist/components/ActionsPanel/components/ActionsPanelMoreAction/ActionsPanelMoreAction.d.ts +2 -0
- package/dist/components/ActionsPanel/components/ActionsPanelMoreAction/ActionsPanelMoreAction.js +72 -0
- package/dist/components/ActionsPanel/components/ActionsPanelMoreAction/ActionsPanelMoreAction.module.css.js +14 -0
- package/dist/components/ActionsPanel/components/ActionsPanelMoreAction/index.d.ts +2 -0
- package/dist/components/ActionsPanel/components/ActionsPanelMoreAction/types.d.ts +9 -0
- package/dist/components/ActionsPanel/components/index.d.ts +4 -0
- package/dist/components/ActionsPanel/hooks/index.d.ts +1 -0
- package/dist/components/ActionsPanel/hooks/useInlinePaddingSize.d.ts +6 -0
- package/dist/components/ActionsPanel/hooks/useInlinePaddingSize.js +17 -0
- package/dist/components/ActionsPanel/index.d.ts +5 -0
- package/dist/components/ActionsPanel/intl.json.js +7 -0
- package/dist/components/ActionsPanel/types.d.ts +47 -0
- package/dist/components/Breadcrumbs/components/BreadcrumbsCollapse/BreadcrumbsCollapse.js +9 -5
- package/dist/components/Breadcrumbs/intl.json.js +7 -0
- package/dist/components/Breadcrumbs/types.d.ts +2 -0
- package/dist/components/ContenPanel/ContentPanel.d.ts +3 -2
- package/dist/components/ContenPanel/ContentPanel.js +9 -9
- package/dist/components/Divider/Divider.d.ts +14 -4
- package/dist/components/Divider/Divider.js +23 -8
- package/dist/components/Divider/types.d.ts +4 -3
- package/dist/components/Navbar/components/NavbarItem.d.ts +4 -0
- package/dist/components/Navbar/components/NavbarItem.js +11 -1
- package/dist/components/SearchInput/SearchInput.d.ts +1 -1
- package/dist/components/Select/Select.d.ts +4 -0
- package/dist/components/SelectNext/Select.d.ts +13 -0
- package/dist/components/SelectNext/Select.js +258 -0
- package/dist/components/SelectNext/Select.module.css.js +23 -0
- package/dist/components/SelectNext/SelectContext.d.ts +2 -0
- package/dist/components/SelectNext/SelectContext.js +5 -0
- package/dist/components/SelectNext/components/SelectList/SelectList.d.ts +37 -0
- package/dist/components/SelectNext/components/SelectList/SelectList.js +131 -0
- package/dist/components/SelectNext/components/SelectList/SelectList.module.css.js +11 -0
- package/dist/components/SelectNext/components/SelectList/index.d.ts +1 -0
- package/dist/components/SelectNext/components/SelectOption/SelectOption.d.ts +37 -0
- package/dist/components/SelectNext/components/SelectOption/SelectOption.js +48 -0
- package/dist/components/SelectNext/components/SelectOption/index.d.ts +1 -0
- package/dist/components/SelectNext/components/SelectSection/SelectSection.d.ts +9 -0
- package/dist/components/SelectNext/components/SelectSection/SelectSection.js +51 -0
- package/dist/components/SelectNext/components/SelectSection/index.d.ts +1 -0
- package/dist/components/SelectNext/components/Tag/Tag.d.ts +18 -0
- package/dist/components/SelectNext/components/Tag/Tag.js +67 -0
- package/dist/components/SelectNext/components/Tag/index.d.ts +1 -0
- package/dist/components/SelectNext/components/Tag/intl.json.js +7 -0
- package/dist/components/SelectNext/components/Tag/utils.d.ts +3 -0
- package/dist/components/SelectNext/components/Tag/utils.js +9 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroup.d.ts +13 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroup.js +25 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroup.module.css.js +20 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroupMultiline.d.ts +3 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroupMultiline.js +44 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroupResponsive.d.ts +3 -0
- package/dist/components/SelectNext/components/TagGroup/TagGroupResponsive.js +65 -0
- package/dist/components/SelectNext/components/TagGroup/index.d.ts +1 -0
- package/dist/components/SelectNext/components/TagGroup/utils.d.ts +1 -0
- package/dist/components/SelectNext/components/TagGroup/utils.js +4 -0
- package/dist/components/SelectNext/components/index.d.ts +5 -0
- package/dist/components/SelectNext/index.d.ts +2 -0
- package/dist/components/SelectNext/intl.d.ts +2 -0
- package/dist/components/SelectNext/intl.js +21 -0
- package/dist/components/SelectNext/types.d.ts +99 -0
- package/dist/components/SelectNext/types.js +12 -0
- package/dist/components/SelectNext/utils.d.ts +9 -0
- package/dist/components/SelectNext/utils.js +26 -0
- package/dist/components/index.d.ts +3 -1
- package/dist/index.js +14 -1
- package/dist/style.css +324 -47
- package/package.json +5 -5
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { DataAttributeProps, ExtendableComponentPropsWithRef } from '@koobiq/react-core';
|
|
3
|
+
import type { TransitionProps } from 'react-transition-group/Transition';
|
|
4
|
+
import type { Key } from '../../index';
|
|
5
|
+
import type { ActionsPanelActionProps, ActionsPanelCounterProps } from './components';
|
|
6
|
+
import type { ActionsPanelMoreActionProps } from './components/ActionsPanelMoreAction';
|
|
7
|
+
export type ActionsPanelActionRenderItem = {
|
|
8
|
+
/** React element. */
|
|
9
|
+
element: ReactElement<ActionsPanelActionProps>;
|
|
10
|
+
/** Index in the `children` list. */
|
|
11
|
+
index: number;
|
|
12
|
+
/** Key. */
|
|
13
|
+
key: Key | null;
|
|
14
|
+
/** Convenient access to the element's children. */
|
|
15
|
+
children: ReactNode;
|
|
16
|
+
/** Optional link target extracted from props. */
|
|
17
|
+
href?: string;
|
|
18
|
+
/** Element props shortcut. */
|
|
19
|
+
props: ActionsPanelActionProps;
|
|
20
|
+
};
|
|
21
|
+
export type ActionsPanelProps = ExtendableComponentPropsWithRef<{
|
|
22
|
+
/** If `true`, the content panel won't close when the ESC key is pressed. */
|
|
23
|
+
disableExitOnEscapeKeyDown?: boolean;
|
|
24
|
+
/** The number of selected items that the ActionsPanel is currently linked to. */
|
|
25
|
+
selectedItemCount?: number | 'all';
|
|
26
|
+
/** Optional secondary counter displayed next to `selectedItemCount`. */
|
|
27
|
+
selectedExtraCount?: number;
|
|
28
|
+
/** The contents of the collection. */
|
|
29
|
+
children?: ReactElement<ActionsPanelActionProps> | Array<ReactElement<ActionsPanelActionProps>>;
|
|
30
|
+
/** Handler that is called when the ActionsPanel clear button is pressed. */
|
|
31
|
+
onClearSelection?: () => void;
|
|
32
|
+
/** Handler called when any breadcrumb item is pressed. It returns the item key. */
|
|
33
|
+
onAction?: (key: Key) => void;
|
|
34
|
+
/**
|
|
35
|
+
* The container element in which the component portal will be placed.
|
|
36
|
+
* @default document.body
|
|
37
|
+
*/
|
|
38
|
+
portalContainer?: HTMLElement | null;
|
|
39
|
+
/** The props used for each slot inside. */
|
|
40
|
+
slotProps?: {
|
|
41
|
+
transition?: Partial<TransitionProps<HTMLElement>>;
|
|
42
|
+
container?: ComponentPropsWithRef<'div'> & DataAttributeProps;
|
|
43
|
+
actions?: ComponentPropsWithRef<'div'> & DataAttributeProps;
|
|
44
|
+
counter?: ActionsPanelCounterProps;
|
|
45
|
+
more?: Partial<ActionsPanelMoreActionProps>;
|
|
46
|
+
};
|
|
47
|
+
}, 'div'>;
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Children, isValidElement, cloneElement } from "react";
|
|
4
|
-
import { useHideOverflowItems, mergeProps, isString, isNotNil } from "@koobiq/react-core";
|
|
4
|
+
import { useLocalizedStringFormatter, useHideOverflowItems, mergeProps, isString, isNotNil } from "@koobiq/react-core";
|
|
5
5
|
import { IconEllipsisHorizontal16 } from "@koobiq/react-icons";
|
|
6
6
|
import { Button } from "@koobiq/react-primitives";
|
|
7
7
|
import s from "../../Breadcrumbs.module.css.js";
|
|
8
|
+
import intlMessages from "../../intl.json.js";
|
|
8
9
|
import { clampEllipsisIndex, getSlotIndex } from "./utils.js";
|
|
9
10
|
import { BreadcrumbItem } from "../BreadcrumbItem/BreadcrumbItem.js";
|
|
10
11
|
import { Menu } from "../../../Menu/Menu.js";
|
|
11
12
|
const renderEllipsisDefault = ({
|
|
12
13
|
ellipsisIcon,
|
|
13
14
|
onAction,
|
|
14
|
-
items
|
|
15
|
+
items,
|
|
16
|
+
"aria-label": label
|
|
15
17
|
}) => {
|
|
16
18
|
if (items.length === 0) return null;
|
|
17
19
|
return /* @__PURE__ */ jsx(
|
|
18
20
|
Menu,
|
|
19
21
|
{
|
|
20
22
|
onAction,
|
|
21
|
-
control: (props) => /* @__PURE__ */ jsx(BreadcrumbItem, { ...props, as: Button, children: ellipsisIcon }),
|
|
23
|
+
control: (props) => /* @__PURE__ */ jsx(BreadcrumbItem, { "aria-label": label, ...props, as: Button, children: ellipsisIcon }),
|
|
22
24
|
children: items.map((item, index) => /* @__PURE__ */ jsx(
|
|
23
25
|
Menu.Item,
|
|
24
26
|
{
|
|
@@ -40,6 +42,7 @@ const BreadcrumbsCollapse = (props) => {
|
|
|
40
42
|
slotProps,
|
|
41
43
|
children
|
|
42
44
|
} = props;
|
|
45
|
+
const t = useLocalizedStringFormatter(intlMessages);
|
|
43
46
|
const ellipsisIcon = /* @__PURE__ */ jsx(IconEllipsisHorizontal16, {});
|
|
44
47
|
const elements = Children.toArray(children);
|
|
45
48
|
const { length } = elements;
|
|
@@ -77,10 +80,11 @@ const BreadcrumbsCollapse = (props) => {
|
|
|
77
80
|
if (isEllipsis) {
|
|
78
81
|
const defaultEllipsis = /* @__PURE__ */ jsx(BreadcrumbItem, { as: "span", children: ellipsisIcon });
|
|
79
82
|
const customEllipsis = renderEllipsis?.({
|
|
83
|
+
onAction,
|
|
80
84
|
ellipsisIcon,
|
|
81
|
-
ellipsisIndex: slotIndex,
|
|
82
85
|
items: collapsedItems,
|
|
83
|
-
|
|
86
|
+
ellipsisIndex: slotIndex,
|
|
87
|
+
"aria-label": t.format("show more")
|
|
84
88
|
});
|
|
85
89
|
return /* @__PURE__ */ jsxs(
|
|
86
90
|
"li",
|
|
@@ -29,6 +29,8 @@ export type RenderEllipsisParams = {
|
|
|
29
29
|
ellipsisIndex: number;
|
|
30
30
|
/** Handler called when any breadcrumb item is pressed. It returns the item key. */
|
|
31
31
|
onAction?: (key: Key) => void;
|
|
32
|
+
/** Defines a string value that labels the current element. */
|
|
33
|
+
'aria-label'?: string;
|
|
32
34
|
};
|
|
33
35
|
export type BreadcrumbsPropRenderEllipsis = (params: RenderEllipsisParams) => ReactNode;
|
|
34
36
|
export type BreadcrumbsProps = ExtendableComponentPropsWithRef<AriaBreadcrumbsProps & {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DialogBody, DialogFooter, DialogHeader
|
|
1
|
+
import type { CSSProperties, ComponentPropsWithRef } from 'react';
|
|
2
|
+
import { DialogBody, DialogFooter, DialogHeader } from '../Dialog';
|
|
3
|
+
import type { DialogProps } from '../Dialog';
|
|
3
4
|
declare const ContentPanelComponent: import("react").ForwardRefExoticComponent<{
|
|
4
5
|
children?: import("react").ReactNode;
|
|
5
6
|
width?: import("./types").ContentPanelSize | null;
|
|
@@ -26,23 +26,23 @@ const ContentPanelComponent = forwardRef(
|
|
|
26
26
|
);
|
|
27
27
|
const {
|
|
28
28
|
defaultWidth: defaultWidthProp,
|
|
29
|
+
disableExitOnEscapeKeyDown,
|
|
29
30
|
minWidth: minWidthProp,
|
|
30
31
|
maxWidth: maxWidthProp,
|
|
31
|
-
disableExitOnEscapeKeyDown,
|
|
32
|
-
onResetResize,
|
|
33
32
|
isResizable = false,
|
|
34
|
-
|
|
35
|
-
onResize,
|
|
36
|
-
onResizeEnd,
|
|
33
|
+
hideCloseButton,
|
|
37
34
|
onResizeStart,
|
|
38
|
-
|
|
35
|
+
onResetResize,
|
|
39
36
|
onOpenChange,
|
|
40
37
|
defaultOpen,
|
|
38
|
+
onResizeEnd,
|
|
39
|
+
slotProps,
|
|
41
40
|
className,
|
|
42
|
-
style,
|
|
43
41
|
children,
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
onResize,
|
|
43
|
+
isOpen,
|
|
44
|
+
width,
|
|
45
|
+
style,
|
|
46
46
|
...other
|
|
47
47
|
} = panelProps;
|
|
48
48
|
const {
|
|
@@ -1,4 +1,14 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
export
|
|
1
|
+
import type { ElementType } from 'react';
|
|
2
|
+
import type { BaseCollection } from '@koobiq/react-primitives';
|
|
3
|
+
import { CollectionNode } from '@koobiq/react-primitives';
|
|
4
|
+
export declare class DividerNode extends CollectionNode<any> {
|
|
5
|
+
static readonly type = "separator";
|
|
6
|
+
filter(collection: BaseCollection<any>, newCollection: BaseCollection<any>): CollectionNode<any> | null;
|
|
7
|
+
}
|
|
8
|
+
export declare const Divider: (props: {
|
|
9
|
+
className?: string;
|
|
10
|
+
display?: import("./types").DividerPropDisplay;
|
|
11
|
+
flexItem?: boolean;
|
|
12
|
+
disablePaddings?: boolean;
|
|
13
|
+
as?: ElementType;
|
|
14
|
+
} & Omit<import("@react-aria/separator").SeparatorProps, "elementType"> & import("react").HTMLAttributes<HTMLElement> & import("react").RefAttributes<HTMLElement>) => import("react").ReactElement | null;
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import { useSeparator } from "@koobiq/react-primitives";
|
|
3
|
+
import { clsx } from "@koobiq/react-core";
|
|
4
|
+
import { createLeafComponent, CollectionNode, useSeparator } from "@koobiq/react-primitives";
|
|
5
5
|
import s from "./Divider.module.css.js";
|
|
6
|
-
const
|
|
7
|
-
(
|
|
6
|
+
const _DividerNode = class _DividerNode extends CollectionNode {
|
|
7
|
+
filter(collection, newCollection) {
|
|
8
|
+
const prevItem = newCollection.getItem(this.prevKey);
|
|
9
|
+
if (prevItem && prevItem.type !== "separator") {
|
|
10
|
+
const clone = this.clone();
|
|
11
|
+
newCollection.addDescendants(clone, collection);
|
|
12
|
+
return clone;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
_DividerNode.type = "separator";
|
|
18
|
+
let DividerNode = _DividerNode;
|
|
19
|
+
const Divider = createLeafComponent(
|
|
20
|
+
DividerNode,
|
|
21
|
+
function Separator(props, ref) {
|
|
8
22
|
const {
|
|
9
|
-
as: Tag = "div",
|
|
10
23
|
orientation = "horizontal",
|
|
24
|
+
as = "div",
|
|
11
25
|
disablePaddings,
|
|
12
26
|
flexItem,
|
|
13
27
|
display,
|
|
@@ -17,9 +31,10 @@ const Divider = polymorphicForwardRef(
|
|
|
17
31
|
const { separatorProps } = useSeparator({
|
|
18
32
|
...other,
|
|
19
33
|
orientation,
|
|
20
|
-
elementType:
|
|
34
|
+
elementType: `${as}`
|
|
21
35
|
});
|
|
22
36
|
const hasPaddings = !disablePaddings;
|
|
37
|
+
const Tag = as;
|
|
23
38
|
return /* @__PURE__ */ jsx(
|
|
24
39
|
Tag,
|
|
25
40
|
{
|
|
@@ -42,7 +57,7 @@ const Divider = polymorphicForwardRef(
|
|
|
42
57
|
);
|
|
43
58
|
}
|
|
44
59
|
);
|
|
45
|
-
Divider.displayName = "Divider";
|
|
46
60
|
export {
|
|
47
|
-
Divider
|
|
61
|
+
Divider,
|
|
62
|
+
DividerNode
|
|
48
63
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ElementType, HTMLAttributes } from 'react';
|
|
2
2
|
import type { SeparatorProps } from '@koobiq/react-primitives';
|
|
3
3
|
export declare const dividerPropDisplay: readonly ["block", "inline", "inlineBlock"];
|
|
4
4
|
export type DividerPropDisplay = (typeof dividerPropDisplay)[number];
|
|
5
|
-
export type
|
|
5
|
+
export type DividerProps = {
|
|
6
6
|
/** Additional CSS-classes. */
|
|
7
7
|
className?: string;
|
|
8
8
|
/** Set the display for the component. */
|
|
@@ -17,4 +17,5 @@ export type DividerBaseProps = ExtendableProps<{
|
|
|
17
17
|
* If `true`, it disables the default paddings.
|
|
18
18
|
*/
|
|
19
19
|
disablePaddings?: boolean;
|
|
20
|
-
|
|
20
|
+
as?: ElementType;
|
|
21
|
+
} & Omit<SeparatorProps, 'elementType'> & HTMLAttributes<HTMLElement>;
|
|
@@ -9,7 +9,16 @@ import { useNavbarState } from "../NavbarContext.js";
|
|
|
9
9
|
import { Tooltip } from "../../Tooltip/Tooltip.js";
|
|
10
10
|
const { listItem, typography } = utilClasses;
|
|
11
11
|
const NavbarItem = polymorphicForwardRef(
|
|
12
|
-
({
|
|
12
|
+
({
|
|
13
|
+
as,
|
|
14
|
+
className,
|
|
15
|
+
isActive,
|
|
16
|
+
isMenu = false,
|
|
17
|
+
icon,
|
|
18
|
+
badge,
|
|
19
|
+
children,
|
|
20
|
+
...other
|
|
21
|
+
}, inRef) => {
|
|
13
22
|
const { isCollapsed } = useNavbarState();
|
|
14
23
|
return /* @__PURE__ */ jsx(
|
|
15
24
|
Tooltip,
|
|
@@ -28,6 +37,7 @@ const NavbarItem = polymorphicForwardRef(
|
|
|
28
37
|
s.item,
|
|
29
38
|
className
|
|
30
39
|
),
|
|
40
|
+
"data-selected": isActive || void 0,
|
|
31
41
|
...mergeProps(props, other),
|
|
32
42
|
ref: mergeRefs(props.ref, inRef),
|
|
33
43
|
children: [
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FormFieldProps, FormFieldLabelProps, FormFieldInputProps, FormFieldErrorProps, FormFieldCaptionProps, FormFieldControlGroupProps } from '../FormField';
|
|
2
|
-
export declare const SearchInput: import("react").ForwardRefExoticComponent<Omit<Omit<import("@react-
|
|
2
|
+
export declare const SearchInput: import("react").ForwardRefExoticComponent<Omit<Omit<import("@koobiq/react-primitives").AriaSearchFieldProps, "description" | "validationState">, "caption" | "style" | "className" | `data-${string}` | "startAddon" | "endAddon" | "variant" | "slotProps" | "labelPlacement" | "labelAlign" | "fullWidth" | "isLabelHidden"> & {
|
|
3
3
|
className?: string;
|
|
4
4
|
style?: import("react").CSSProperties;
|
|
5
5
|
isLabelHidden?: boolean;
|
|
@@ -8,5 +8,9 @@ type CompoundedComponent = typeof SelectComponent & {
|
|
|
8
8
|
Divider: typeof Divider;
|
|
9
9
|
ItemText: typeof ListItemText;
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated
|
|
13
|
+
* This component has been deprecated, please use SelectNext instead.
|
|
14
|
+
*/
|
|
11
15
|
export declare const Select: CompoundedComponent;
|
|
12
16
|
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Divider } from '../Divider';
|
|
2
|
+
import type { ListItemText } from '../List';
|
|
3
|
+
import { SelectOption, SelectSection } from './components';
|
|
4
|
+
import { type SelectNextComponent } from './index';
|
|
5
|
+
declare const SelectComponent: SelectNextComponent;
|
|
6
|
+
type CompoundedComponent = typeof SelectComponent & {
|
|
7
|
+
Item: typeof SelectOption;
|
|
8
|
+
Section: typeof SelectSection;
|
|
9
|
+
Divider: typeof Divider;
|
|
10
|
+
ItemText: typeof ListItemText;
|
|
11
|
+
};
|
|
12
|
+
export declare const SelectNext: CompoundedComponent;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef, useCallback } from "react";
|
|
4
|
+
import { useDOMRef, useElementSize, mergeProps } from "@koobiq/react-core";
|
|
5
|
+
import { IconChevronDownS16 } from "@koobiq/react-icons";
|
|
6
|
+
import { CollectionBuilder, Collection, useSelectState, removeDataAttributes, useSlottedContext, FormContext, useSelect, FieldErrorContext } from "@koobiq/react-primitives";
|
|
7
|
+
import { PopoverInner } from "../Popover/PopoverInner.js";
|
|
8
|
+
import s from "./Select.module.css.js";
|
|
9
|
+
import { SelectList } from "./components/SelectList/SelectList.js";
|
|
10
|
+
import { TagGroup } from "./components/TagGroup/TagGroup.js";
|
|
11
|
+
import { SelectOption } from "./components/SelectOption/SelectOption.js";
|
|
12
|
+
import { SelectSection } from "./components/SelectSection/SelectSection.js";
|
|
13
|
+
import { useForm } from "../Form/FormContext.js";
|
|
14
|
+
import { FormFieldClearButton } from "../FormField/FormFieldClearButton/FormFieldClearButton.js";
|
|
15
|
+
import { FormField } from "../FormField/FormField.js";
|
|
16
|
+
import { Divider } from "../Divider/Divider.js";
|
|
17
|
+
import { List } from "../List/List.js";
|
|
18
|
+
function SelectInner({
|
|
19
|
+
state: inState,
|
|
20
|
+
props,
|
|
21
|
+
listBoxRef
|
|
22
|
+
}) {
|
|
23
|
+
const {
|
|
24
|
+
selectedTagsOverflow = "responsive",
|
|
25
|
+
renderValue: renderValueProp,
|
|
26
|
+
"data-testid": testId,
|
|
27
|
+
defaultInputValue,
|
|
28
|
+
labelPlacement,
|
|
29
|
+
onInputChange,
|
|
30
|
+
selectionMode,
|
|
31
|
+
defaultFilter,
|
|
32
|
+
isLabelHidden,
|
|
33
|
+
isSearchable,
|
|
34
|
+
errorMessage,
|
|
35
|
+
placeholder,
|
|
36
|
+
loadingText,
|
|
37
|
+
isClearable,
|
|
38
|
+
noItemsText,
|
|
39
|
+
inputValue,
|
|
40
|
+
labelAlign,
|
|
41
|
+
startAddon,
|
|
42
|
+
isRequired,
|
|
43
|
+
onLoadMore,
|
|
44
|
+
isDisabled,
|
|
45
|
+
fullWidth,
|
|
46
|
+
className,
|
|
47
|
+
isLoading,
|
|
48
|
+
slotProps,
|
|
49
|
+
endAddon,
|
|
50
|
+
caption,
|
|
51
|
+
onClear,
|
|
52
|
+
style,
|
|
53
|
+
label
|
|
54
|
+
} = props;
|
|
55
|
+
const { validationBehavior: formValidationBehavior } = useSlottedContext(FormContext) || {};
|
|
56
|
+
const validationBehavior = props.validationBehavior ?? formValidationBehavior ?? "aria";
|
|
57
|
+
const clearButtonIsHidden = isDisabled || !inState.selectedItems.length;
|
|
58
|
+
const handleClear = useCallback(() => {
|
|
59
|
+
inState.selectionManager.setSelectedKeys(/* @__PURE__ */ new Set());
|
|
60
|
+
onClear?.();
|
|
61
|
+
}, [onClear, inState]);
|
|
62
|
+
const {
|
|
63
|
+
menuProps,
|
|
64
|
+
valueProps,
|
|
65
|
+
triggerProps,
|
|
66
|
+
descriptionProps,
|
|
67
|
+
errorMessageProps,
|
|
68
|
+
labelProps: labelPropsAria,
|
|
69
|
+
...validation
|
|
70
|
+
} = useSelect(
|
|
71
|
+
removeDataAttributes({
|
|
72
|
+
...props,
|
|
73
|
+
isDisabled,
|
|
74
|
+
selectionMode,
|
|
75
|
+
validationBehavior,
|
|
76
|
+
allowsEmptyCollection: true
|
|
77
|
+
}),
|
|
78
|
+
inState,
|
|
79
|
+
listBoxRef
|
|
80
|
+
);
|
|
81
|
+
const { isInvalid } = validation;
|
|
82
|
+
const { ref: containerRef, width } = useElementSize();
|
|
83
|
+
const rootProps = mergeProps({
|
|
84
|
+
"data-testid": testId,
|
|
85
|
+
"data-invalid": isInvalid || void 0,
|
|
86
|
+
"data-disabled": isDisabled || void 0,
|
|
87
|
+
"data-required": isRequired || void 0,
|
|
88
|
+
className,
|
|
89
|
+
fullWidth,
|
|
90
|
+
labelPlacement,
|
|
91
|
+
labelAlign,
|
|
92
|
+
style
|
|
93
|
+
});
|
|
94
|
+
const listProps = mergeProps(
|
|
95
|
+
{
|
|
96
|
+
isLoading,
|
|
97
|
+
inputValue,
|
|
98
|
+
onLoadMore,
|
|
99
|
+
noItemsText,
|
|
100
|
+
loadingText,
|
|
101
|
+
isSearchable,
|
|
102
|
+
defaultFilter,
|
|
103
|
+
state: inState,
|
|
104
|
+
onInputChange,
|
|
105
|
+
className: s.list,
|
|
106
|
+
defaultInputValue
|
|
107
|
+
},
|
|
108
|
+
slotProps?.list,
|
|
109
|
+
menuProps
|
|
110
|
+
);
|
|
111
|
+
const labelProps = mergeProps(
|
|
112
|
+
{ isHidden: isLabelHidden, children: label, isRequired },
|
|
113
|
+
labelPropsAria,
|
|
114
|
+
slotProps?.label
|
|
115
|
+
);
|
|
116
|
+
const clearButtonProps = mergeProps(
|
|
117
|
+
{
|
|
118
|
+
isClearable,
|
|
119
|
+
onPress: handleClear,
|
|
120
|
+
className: s.clearButton,
|
|
121
|
+
isHidden: clearButtonIsHidden
|
|
122
|
+
},
|
|
123
|
+
slotProps?.clearButton
|
|
124
|
+
);
|
|
125
|
+
const { slotProps: groupSlotProps, ...otherGroup } = slotProps?.group || {};
|
|
126
|
+
const groupProps = mergeProps(
|
|
127
|
+
{
|
|
128
|
+
slotProps: mergeProps(
|
|
129
|
+
{
|
|
130
|
+
endAddon: { className: s.addon },
|
|
131
|
+
startAddon: { className: s.addon }
|
|
132
|
+
},
|
|
133
|
+
groupSlotProps
|
|
134
|
+
),
|
|
135
|
+
startAddon,
|
|
136
|
+
onMouseDown: (e) => {
|
|
137
|
+
if (e.currentTarget !== e.target || isDisabled) return;
|
|
138
|
+
e.preventDefault();
|
|
139
|
+
listBoxRef?.current?.focus();
|
|
140
|
+
inState.open();
|
|
141
|
+
},
|
|
142
|
+
endAddon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
143
|
+
endAddon,
|
|
144
|
+
/* @__PURE__ */ jsx(FormFieldClearButton, { ...clearButtonProps }),
|
|
145
|
+
/* @__PURE__ */ jsx("span", { className: s.chevron, children: /* @__PURE__ */ jsx(IconChevronDownS16, {}) })
|
|
146
|
+
] }),
|
|
147
|
+
isInvalid,
|
|
148
|
+
isDisabled,
|
|
149
|
+
ref: containerRef
|
|
150
|
+
},
|
|
151
|
+
otherGroup
|
|
152
|
+
);
|
|
153
|
+
const controlProps = mergeProps(
|
|
154
|
+
{
|
|
155
|
+
ref: listBoxRef,
|
|
156
|
+
placeholder
|
|
157
|
+
},
|
|
158
|
+
valueProps,
|
|
159
|
+
triggerProps,
|
|
160
|
+
slotProps?.control
|
|
161
|
+
);
|
|
162
|
+
const popoverProps = mergeProps(
|
|
163
|
+
{
|
|
164
|
+
offset: 4,
|
|
165
|
+
state: inState,
|
|
166
|
+
hideArrow: true,
|
|
167
|
+
type: "listbox",
|
|
168
|
+
maxBlockSize: 256,
|
|
169
|
+
className: s.popover,
|
|
170
|
+
anchorRef: containerRef,
|
|
171
|
+
placement: "bottom start",
|
|
172
|
+
size: Math.max(width, 200)
|
|
173
|
+
},
|
|
174
|
+
slotProps?.popover
|
|
175
|
+
);
|
|
176
|
+
const captionProps = mergeProps(
|
|
177
|
+
{ children: caption },
|
|
178
|
+
descriptionProps,
|
|
179
|
+
slotProps?.caption
|
|
180
|
+
);
|
|
181
|
+
const errorProps = mergeProps(
|
|
182
|
+
{ children: errorMessage },
|
|
183
|
+
errorMessageProps,
|
|
184
|
+
slotProps?.errorMessage
|
|
185
|
+
);
|
|
186
|
+
const renderDefaultValue = (state, states) => {
|
|
187
|
+
if (!state.selectedItems?.length) return null;
|
|
188
|
+
if (selectionMode === "multiple")
|
|
189
|
+
return /* @__PURE__ */ jsx(
|
|
190
|
+
TagGroup,
|
|
191
|
+
{
|
|
192
|
+
state,
|
|
193
|
+
states,
|
|
194
|
+
selectedTagsOverflow
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
return state.selectedItems[0].textValue;
|
|
198
|
+
};
|
|
199
|
+
const renderValue = renderValueProp || renderDefaultValue;
|
|
200
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
201
|
+
/* @__PURE__ */ jsxs(FormField, { ...rootProps, children: [
|
|
202
|
+
/* @__PURE__ */ jsx(FormField.Label, { ...labelProps }),
|
|
203
|
+
/* @__PURE__ */ jsxs("div", { className: s.body, children: [
|
|
204
|
+
/* @__PURE__ */ jsx(FormField.ControlGroup, { ...groupProps, children: /* @__PURE__ */ jsx(FormField.Select, { ...controlProps, children: renderValue(inState, {
|
|
205
|
+
isInvalid,
|
|
206
|
+
isDisabled: props.isDisabled,
|
|
207
|
+
isRequired: props.isRequired
|
|
208
|
+
}) }) }),
|
|
209
|
+
/* @__PURE__ */ jsx(FieldErrorContext.Provider, { value: validation, children: /* @__PURE__ */ jsx(FormField.Error, { ...errorProps }) }),
|
|
210
|
+
/* @__PURE__ */ jsx(FormField.Caption, { ...captionProps })
|
|
211
|
+
] })
|
|
212
|
+
] }),
|
|
213
|
+
/* @__PURE__ */ jsx(PopoverInner, { ...popoverProps, children: /* @__PURE__ */ jsx(SelectList, { ...listProps }) })
|
|
214
|
+
] });
|
|
215
|
+
}
|
|
216
|
+
function StandaloneSelect({
|
|
217
|
+
props: inProps,
|
|
218
|
+
listBoxRef,
|
|
219
|
+
collection
|
|
220
|
+
}) {
|
|
221
|
+
const props = { ...inProps, collection, children: null, items: null };
|
|
222
|
+
const { isDisabled: formIsDisabled } = useForm();
|
|
223
|
+
const isDisabled = inProps?.isDisabled ?? formIsDisabled;
|
|
224
|
+
const state = useSelectState(
|
|
225
|
+
removeDataAttributes({
|
|
226
|
+
...props,
|
|
227
|
+
isDisabled
|
|
228
|
+
})
|
|
229
|
+
);
|
|
230
|
+
return /* @__PURE__ */ jsx(
|
|
231
|
+
SelectInner,
|
|
232
|
+
{
|
|
233
|
+
state,
|
|
234
|
+
listBoxRef,
|
|
235
|
+
props: { ...props, isDisabled }
|
|
236
|
+
}
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
function SelectRender(props, ref) {
|
|
240
|
+
const listBoxRef = useDOMRef(ref);
|
|
241
|
+
return /* @__PURE__ */ jsx(CollectionBuilder, { content: /* @__PURE__ */ jsx(Collection, { ...props }), children: (collection) => /* @__PURE__ */ jsx(
|
|
242
|
+
StandaloneSelect,
|
|
243
|
+
{
|
|
244
|
+
props,
|
|
245
|
+
collection,
|
|
246
|
+
listBoxRef
|
|
247
|
+
}
|
|
248
|
+
) });
|
|
249
|
+
}
|
|
250
|
+
const SelectComponent = forwardRef(SelectRender);
|
|
251
|
+
const SelectNext = SelectComponent;
|
|
252
|
+
SelectNext.Item = SelectOption;
|
|
253
|
+
SelectNext.Section = SelectSection;
|
|
254
|
+
SelectNext.Divider = Divider;
|
|
255
|
+
SelectNext.ItemText = List.ItemText;
|
|
256
|
+
export {
|
|
257
|
+
SelectNext
|
|
258
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const addon = "kbq-select-addon-1077d8";
|
|
2
|
+
const chevron = "kbq-select-chevron-5918a1";
|
|
3
|
+
const body = "kbq-select-body-698617";
|
|
4
|
+
const list = "kbq-select-list-51ca7a";
|
|
5
|
+
const popover = "kbq-select-popover-756d4e";
|
|
6
|
+
const clearButton = "kbq-select-clearButton-8498d2";
|
|
7
|
+
const s = {
|
|
8
|
+
addon,
|
|
9
|
+
chevron,
|
|
10
|
+
body,
|
|
11
|
+
list,
|
|
12
|
+
popover,
|
|
13
|
+
clearButton
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
addon,
|
|
17
|
+
body,
|
|
18
|
+
chevron,
|
|
19
|
+
clearButton,
|
|
20
|
+
s as default,
|
|
21
|
+
list,
|
|
22
|
+
popover
|
|
23
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import type { SelectState, AriaListBoxProps } from '@koobiq/react-primitives';
|
|
3
|
+
import type { SelectionMode } from '@react-types/select';
|
|
4
|
+
import { type DividerProps } from '../../../Divider';
|
|
5
|
+
import { type SearchInputProps } from '../../../SearchInput';
|
|
6
|
+
export type SelectListProps<T extends object, M extends SelectionMode = 'single'> = {
|
|
7
|
+
state: SelectState<T, M>;
|
|
8
|
+
/** The filter function used to determine if a option should be included in the Select list. */
|
|
9
|
+
defaultFilter?: (textValue: string, inputValue: string) => boolean;
|
|
10
|
+
/** The value of the Select search input (controlled). */
|
|
11
|
+
inputValue?: string;
|
|
12
|
+
/** The default value of the Select search input (uncontrolled). */
|
|
13
|
+
defaultInputValue?: string;
|
|
14
|
+
/** Handler that is called when the Select search input value changes. */
|
|
15
|
+
onInputChange?: (value: string) => void;
|
|
16
|
+
/** Additional CSS-classes. */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Inline styles. */
|
|
19
|
+
style?: CSSProperties;
|
|
20
|
+
/** The load more spinner to render when loading additional items. */
|
|
21
|
+
isLoading?: boolean;
|
|
22
|
+
/** Handler that is called when more items should be loaded, e.g. while scrolling near the bottom. */
|
|
23
|
+
onLoadMore?: () => void;
|
|
24
|
+
/** Content to display when no items are available. */
|
|
25
|
+
noItemsText?: ReactNode;
|
|
26
|
+
/** Content to display when items are loading. */
|
|
27
|
+
loadingText?: ReactNode;
|
|
28
|
+
/** Enables search input for filtering items in the list. */
|
|
29
|
+
isSearchable?: boolean;
|
|
30
|
+
/** The props used for each slot inside. */
|
|
31
|
+
slotProps?: {
|
|
32
|
+
divider?: DividerProps;
|
|
33
|
+
root?: ComponentPropsWithRef<'div'>;
|
|
34
|
+
'search-input'?: SearchInputProps;
|
|
35
|
+
};
|
|
36
|
+
} & Omit<AriaListBoxProps<T>, 'children'>;
|
|
37
|
+
export declare function SelectList<T extends object, M extends SelectionMode = 'single'>(props: SelectListProps<T, M>): import("react/jsx-runtime").JSX.Element;
|