@paroicms/react-ui 0.4.4 → 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/dist/Accordion.d.ts +10 -0
- package/dist/{PuAccordion.jsx → Accordion.js} +5 -8
- package/dist/Alert.d.ts +10 -0
- package/dist/Alert.js +7 -0
- package/dist/Badge.d.ts +8 -0
- package/dist/Badge.js +6 -0
- package/dist/Breadcrumb.d.ts +14 -0
- package/dist/Breadcrumb.js +10 -0
- package/dist/Button.d.ts +36 -0
- package/dist/Button.js +74 -0
- package/dist/Card.d.ts +10 -0
- package/dist/Card.js +7 -0
- package/dist/Checkbox.d.ts +9 -0
- package/dist/Checkbox.js +12 -0
- package/dist/Chip.d.ts +8 -0
- package/dist/Chip.js +7 -0
- package/dist/Column.d.ts +14 -0
- package/dist/Column.js +7 -0
- package/dist/DataTable.d.ts +30 -0
- package/dist/DataTable.js +26 -0
- package/dist/DateInput.d.ts +9 -0
- package/dist/DateInput.js +7 -0
- package/dist/Dialog.d.ts +13 -0
- package/dist/Dialog.js +55 -0
- package/dist/Inplace.d.ts +12 -0
- package/dist/Inplace.js +16 -0
- package/dist/InputNumber.d.ts +10 -0
- package/dist/InputNumber.js +19 -0
- package/dist/InputText.d.ts +14 -0
- package/dist/InputText.js +11 -0
- package/dist/MenuItem.d.ts +8 -0
- package/dist/MenuItem.js +18 -0
- package/dist/MultiSelect.d.ts +17 -0
- package/dist/MultiSelect.js +50 -0
- package/dist/Panel.d.ts +11 -0
- package/dist/Panel.js +9 -0
- package/dist/PasswordInput.d.ts +8 -0
- package/dist/PasswordInput.js +10 -0
- package/dist/PopupMenu.d.ts +20 -0
- package/dist/{PuPopupMenu.jsx → PopupMenu.js} +45 -36
- package/dist/RadioButton.d.ts +9 -0
- package/dist/RadioButton.js +12 -0
- package/dist/Select.d.ts +18 -0
- package/dist/Select.js +11 -0
- package/dist/SideMenu.d.ts +5 -0
- package/dist/SideMenu.js +13 -0
- package/dist/SortableList.d.ts +19 -0
- package/dist/SortableList.js +27 -0
- package/dist/Spinner.d.ts +2 -0
- package/dist/Spinner.js +5 -0
- package/dist/SplitButton.d.ts +24 -0
- package/dist/SplitButton.js +42 -0
- package/dist/Switch.d.ts +9 -0
- package/dist/Switch.js +12 -0
- package/dist/Tabs.d.ts +22 -0
- package/dist/Tabs.js +21 -0
- package/dist/Textarea.d.ts +8 -0
- package/dist/Textarea.js +7 -0
- package/dist/ToggleButton.d.ts +11 -0
- package/dist/ToggleButton.js +6 -0
- package/dist/ToggleGroup.d.ts +15 -0
- package/dist/ToggleGroup.js +6 -0
- package/dist/Tooltip.d.ts +10 -0
- package/dist/Tooltip.js +50 -0
- package/dist/Tree.d.ts +22 -0
- package/dist/Tree.js +43 -0
- package/dist/alert-stack.d.ts +18 -0
- package/dist/alert-stack.js +72 -0
- package/dist/index.d.ts +36 -10
- package/dist/index.js +45 -10
- package/dist/paroi-ui-lib-types.d.ts +4 -4
- package/dist/react-ui-provider.d.ts +15 -0
- package/dist/react-ui-provider.js +22 -0
- package/package.json +16 -2
- package/styles/Accordion.css +46 -0
- package/styles/Alert.css +76 -0
- package/styles/Badge.css +59 -0
- package/styles/Breadcrumb.css +57 -0
- package/styles/Button.css +167 -0
- package/styles/Card.css +28 -0
- package/styles/Checkbox.css +61 -0
- package/styles/Chip.css +35 -0
- package/styles/DataTable.css +176 -0
- package/styles/DateInput.css +59 -0
- package/styles/Dialog.css +77 -0
- package/styles/Inplace.css +44 -0
- package/styles/InputNumber.css +60 -0
- package/styles/InputText.css +99 -0
- package/styles/MenuItem.css +169 -0
- package/styles/MultiSelect.css +158 -0
- package/styles/Panel.css +40 -0
- package/styles/PasswordInput.css +80 -0
- package/styles/PopupMenu.css +37 -0
- package/styles/RadioButton.css +60 -0
- package/styles/Select.css +72 -0
- package/styles/SideMenu.css +7 -0
- package/styles/SortableList.css +32 -0
- package/styles/Spinner.css +30 -0
- package/styles/SplitButton.css +143 -0
- package/styles/Switch.css +60 -0
- package/styles/Tabs.css +94 -0
- package/styles/Textarea.css +66 -0
- package/styles/ToggleButton.css +36 -0
- package/styles/ToggleGroup.css +55 -0
- package/styles/Tooltip.css +34 -0
- package/styles/Tree.css +161 -0
- package/styles/theme/base.css +40 -0
- package/styles/theme/common.css +410 -0
- package/styles/theme/index.css +15 -0
- package/styles/theme/margins.css +119 -0
- package/styles/theme/reset.css +119 -0
- package/styles/theme/tokens.css +226 -0
- package/dist/PuAccordion.d.ts +0 -9
- package/dist/PuButton.d.ts +0 -14
- package/dist/PuButton.jsx +0 -15
- package/dist/PuCheckbox.d.ts +0 -8
- package/dist/PuCheckbox.jsx +0 -13
- package/dist/PuInput.d.ts +0 -10
- package/dist/PuInput.jsx +0 -13
- package/dist/PuMenuItem.d.ts +0 -7
- package/dist/PuMenuItem.jsx +0 -33
- package/dist/PuPopupMenu.d.ts +0 -14
- package/dist/PuSelect.d.ts +0 -17
- package/dist/PuSelect.jsx +0 -24
- package/dist/PuSideMenu.d.ts +0 -4
- package/dist/PuSideMenu.jsx +0 -15
- package/dist/PuSpinner.d.ts +0 -1
- package/dist/PuSpinner.jsx +0 -3
- package/dist/svg-icons.d.ts +0 -5
- package/dist/svg-icons.jsx +0 -30
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "../styles/Accordion.css";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
import type { MenuOption } from "./paroi-ui-lib-types.js";
|
|
4
|
+
export interface AccordionProps {
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
header: MenuOption;
|
|
7
|
+
/** Initial value */
|
|
8
|
+
expanded?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function Accordion({ children, header, expanded }: AccordionProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Accordion.css";
|
|
1
3
|
import { useAsyncEffect } from "@paroi/use-async-effect";
|
|
2
4
|
import { useRef, useState } from "react";
|
|
3
|
-
import {
|
|
4
|
-
export function
|
|
5
|
+
import { MenuItem } from "./MenuItem.js";
|
|
6
|
+
export function Accordion({ children, header, expanded }) {
|
|
5
7
|
const [isExpanded, setIsExpanded] = useState(expanded ?? false);
|
|
6
8
|
const contentRef = useRef(null);
|
|
7
9
|
useAsyncEffect(async () => {
|
|
@@ -19,12 +21,7 @@ export function PuAccordion({ children, header, expanded }) {
|
|
|
19
21
|
await startTransition(content, isExpanded);
|
|
20
22
|
}
|
|
21
23
|
}, [isExpanded]);
|
|
22
|
-
return (
|
|
23
|
-
<PuMenuItem item={header} expanded={isExpanded} onToggle={setIsExpanded}/>
|
|
24
|
-
<div className="PuAccordion-content initializing" ref={contentRef}>
|
|
25
|
-
{children}
|
|
26
|
-
</div>
|
|
27
|
-
</div>);
|
|
24
|
+
return (_jsxs("div", { className: "PaAccordion", children: [_jsx(MenuItem, { item: header, expanded: isExpanded, onToggle: setIsExpanded }), _jsx("div", { className: "PaAccordion-content initializing", ref: contentRef, children: children })] }));
|
|
28
25
|
}
|
|
29
26
|
function startTransition(content, isOpen) {
|
|
30
27
|
if (isOpen) {
|
package/dist/Alert.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "../styles/Alert.css";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export interface AlertProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
severity?: "info" | "success" | "warning" | "error" | "primary";
|
|
6
|
+
title?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
onClose?: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function Alert({ children, severity, title, className, onClose }: AlertProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Alert.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Alert.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { X } from "lucide-react";
|
|
5
|
+
export function Alert({ children, severity = "info", title, className, onClose }) {
|
|
6
|
+
return (_jsxs("div", { className: clsx("PaAlert", severity, onClose && "dismissible", className), children: [onClose && (_jsx("button", { type: "button", className: "PaAlert-closeBtn", onClick: onClose, "aria-label": "Close", children: _jsx(X, { size: 16 }) })), title && _jsx("div", { className: "PaAlert-title", children: title }), _jsx("div", { className: "PaAlert-content", children: children })] }));
|
|
7
|
+
}
|
package/dist/Badge.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "../styles/Badge.css";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export interface BadgeProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
severity?: "default" | "primary" | "accent" | "success" | "warning" | "danger" | "info" | "secondary" | "contrast";
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function Badge({ children, severity, className }: BadgeProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Badge.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Badge.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
export function Badge({ children, severity = "default", className }) {
|
|
5
|
+
return _jsx("span", { className: clsx("PaBadge", severity, className), children: children });
|
|
6
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import "../styles/Breadcrumb.css";
|
|
3
|
+
export interface BreadcrumbItem {
|
|
4
|
+
label: string;
|
|
5
|
+
icon?: ReactNode;
|
|
6
|
+
url?: string;
|
|
7
|
+
onClick?: () => void;
|
|
8
|
+
}
|
|
9
|
+
export interface BreadcrumbProps {
|
|
10
|
+
items: BreadcrumbItem[];
|
|
11
|
+
separator?: ReactNode;
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function Breadcrumb({ items, separator, className, }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { ChevronRight } from "lucide-react";
|
|
4
|
+
import "../styles/Breadcrumb.css";
|
|
5
|
+
export function Breadcrumb({ items, separator = _jsx(ChevronRight, { size: 12 }), className, }) {
|
|
6
|
+
return (_jsx("nav", { className: clsx("PaBreadcrumb", className), "aria-label": "Breadcrumb", children: items.map((item, index) => {
|
|
7
|
+
const isLast = index === items.length - 1;
|
|
8
|
+
return (_jsxs("div", { className: "PaBreadcrumb-item", children: [isLast ? (_jsxs("span", { className: "PaBreadcrumb-current", children: [item.icon, item.label] })) : item.url ? (_jsxs("a", { href: item.url, className: "PaBreadcrumb-link", children: [item.icon, item.label] })) : item.onClick ? (_jsxs("button", { type: "button", className: "PaBreadcrumb-link", onClick: item.onClick, children: [item.icon, item.label] })) : (_jsxs("span", { className: "PaBreadcrumb-link", children: [item.icon, item.label] })), !isLast && _jsx("span", { className: "PaBreadcrumb-separator", children: separator })] }, `${item.label}:${index}`));
|
|
9
|
+
}) }));
|
|
10
|
+
}
|
package/dist/Button.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import "../styles/Button.css";
|
|
2
|
+
import { type AnchorHTMLAttributes, type ButtonHTMLAttributes, type MouseEvent, type ReactNode, type Ref } from "react";
|
|
3
|
+
export type ButtonProps = ButtonElProps | AsyncButtonElProps | AnchorElProps;
|
|
4
|
+
interface ButtonBaseProps {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
outlined?: boolean;
|
|
9
|
+
icon?: ReactNode;
|
|
10
|
+
severity?: "primary" | "secondary" | "success" | "info" | "warning" | "danger" | "ghost";
|
|
11
|
+
}
|
|
12
|
+
export interface ButtonElProps extends ButtonBaseProps, Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "onClick"> {
|
|
13
|
+
as?: "button";
|
|
14
|
+
type?: "button" | "submit" | "reset";
|
|
15
|
+
onClick?(e: MouseEvent<HTMLButtonElement>): unknown;
|
|
16
|
+
insideFeedback?: InsideFeedback;
|
|
17
|
+
ref?: Ref<HTMLButtonElement>;
|
|
18
|
+
}
|
|
19
|
+
export interface InsideFeedback {
|
|
20
|
+
label: string;
|
|
21
|
+
autoDismiss?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface AsyncButtonElProps extends ButtonBaseProps, Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children" | "onClick"> {
|
|
24
|
+
as: "async";
|
|
25
|
+
type?: "button";
|
|
26
|
+
onClick: (e: MouseEvent<HTMLButtonElement>) => Promise<unknown>;
|
|
27
|
+
insideFeedback?: InsideFeedback;
|
|
28
|
+
onError?: (error: unknown) => void;
|
|
29
|
+
ref?: Ref<HTMLButtonElement>;
|
|
30
|
+
}
|
|
31
|
+
export interface AnchorElProps extends ButtonBaseProps, Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "children"> {
|
|
32
|
+
as: "a";
|
|
33
|
+
ref?: Ref<HTMLAnchorElement>;
|
|
34
|
+
}
|
|
35
|
+
export declare function Button(props: ButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
export {};
|
package/dist/Button.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Button.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { Check, Loader2 } from "lucide-react";
|
|
5
|
+
import { useCallback, useState, } from "react";
|
|
6
|
+
import { useReactUIConfig } from "./react-ui-provider.js";
|
|
7
|
+
export function Button(props) {
|
|
8
|
+
const { children, className, disabled, outlined, icon, severity = "primary", ref, ...rest } = props;
|
|
9
|
+
const { autoDismissInsideFeedbackDurationMs } = useReactUIConfig();
|
|
10
|
+
const [loading, setLoading] = useState(false);
|
|
11
|
+
const [showFeedback, setShowFeedback] = useState(false);
|
|
12
|
+
const classNames = clsx("PaBtn", severity, outlined && "outlined", disabled && "disabled", showFeedback && "feedback", className);
|
|
13
|
+
const handleAsyncClick = useCallback(async (e) => {
|
|
14
|
+
if (props.as !== "async")
|
|
15
|
+
return;
|
|
16
|
+
setLoading(true);
|
|
17
|
+
setShowFeedback(false);
|
|
18
|
+
try {
|
|
19
|
+
await props.onClick(e);
|
|
20
|
+
if (props.insideFeedback) {
|
|
21
|
+
setShowFeedback(true);
|
|
22
|
+
if (props.insideFeedback.autoDismiss) {
|
|
23
|
+
setTimeout(() => setShowFeedback(false), autoDismissInsideFeedbackDurationMs);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
props.onError?.(error);
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
setLoading(false);
|
|
32
|
+
}
|
|
33
|
+
}, [
|
|
34
|
+
props.as,
|
|
35
|
+
...(props.as === "async"
|
|
36
|
+
? [
|
|
37
|
+
props.onClick,
|
|
38
|
+
!!props.insideFeedback,
|
|
39
|
+
props.insideFeedback?.autoDismiss,
|
|
40
|
+
props.onError,
|
|
41
|
+
autoDismissInsideFeedbackDurationMs,
|
|
42
|
+
]
|
|
43
|
+
: []),
|
|
44
|
+
]);
|
|
45
|
+
const handleSyncClick = useCallback((e) => {
|
|
46
|
+
if (props.as && props.as !== "button")
|
|
47
|
+
return;
|
|
48
|
+
if (props.onClick) {
|
|
49
|
+
props.onClick(e);
|
|
50
|
+
}
|
|
51
|
+
if (props.insideFeedback) {
|
|
52
|
+
setShowFeedback(true);
|
|
53
|
+
if (props.insideFeedback.autoDismiss) {
|
|
54
|
+
setTimeout(() => setShowFeedback(false), autoDismissInsideFeedbackDurationMs);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}, [
|
|
58
|
+
props.as,
|
|
59
|
+
props.onClick,
|
|
60
|
+
...(!props.as || props.as === "button"
|
|
61
|
+
? [
|
|
62
|
+
!!props.insideFeedback,
|
|
63
|
+
props.insideFeedback?.autoDismiss,
|
|
64
|
+
autoDismissInsideFeedbackDurationMs,
|
|
65
|
+
]
|
|
66
|
+
: []),
|
|
67
|
+
]);
|
|
68
|
+
if (props.as === "a") {
|
|
69
|
+
const { as, ...anchorProps } = rest;
|
|
70
|
+
return (_jsxs("a", { ref: ref, className: classNames, ...anchorProps, children: [icon && _jsx("span", { className: "PaBtn-icon", children: icon }), children] }));
|
|
71
|
+
}
|
|
72
|
+
const { as, onClick, type = "button", insideFeedback, ...buttonProps } = rest;
|
|
73
|
+
return (_jsx("button", { ref: ref, className: classNames, disabled: disabled || loading, onClick: as === "async" ? handleAsyncClick : handleSyncClick, type: type, ...buttonProps, children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 16, className: "PaBtn-spinner" }), children] })) : showFeedback && insideFeedback ? (_jsxs(_Fragment, { children: [_jsx(Check, { size: 16, className: "PaBtn-feedbackIcon" }), insideFeedback.label] })) : (_jsxs(_Fragment, { children: [icon && _jsx("span", { className: "PaBtn-icon", children: icon }), children] })) }));
|
|
74
|
+
}
|
package/dist/Card.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import "../styles/Card.css";
|
|
2
|
+
import type { ReactNode } from "react";
|
|
3
|
+
export interface CardProps {
|
|
4
|
+
children: ReactNode;
|
|
5
|
+
header?: ReactNode;
|
|
6
|
+
title?: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function Card({ children, header, title, subtitle, className }: CardProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Card.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Card.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
export function Card({ children, header, title, subtitle, className }) {
|
|
5
|
+
const hasHeader = header || title || subtitle;
|
|
6
|
+
return (_jsxs("div", { className: clsx("PaCard", className), children: [hasHeader && (_jsx("div", { className: "PaCard-header", children: header || (_jsxs(_Fragment, { children: [title && _jsx("h3", { className: "PaCard-title", children: title }), subtitle && _jsx("p", { className: "PaCard-subtitle", children: subtitle })] })) })), children] }));
|
|
7
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "../styles/Checkbox.css";
|
|
2
|
+
import type { InputHTMLAttributes } from "react";
|
|
3
|
+
export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "onChange" | "type"> {
|
|
4
|
+
checked: boolean;
|
|
5
|
+
onChange: (checked: boolean) => void;
|
|
6
|
+
label?: string;
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function Checkbox({ checked, onChange, label, className, ...rest }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Checkbox.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Checkbox.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
export function Checkbox({ checked, onChange, label, className, ...rest }) {
|
|
5
|
+
const handleChange = (e) => {
|
|
6
|
+
onChange(e.target.checked);
|
|
7
|
+
};
|
|
8
|
+
if (label) {
|
|
9
|
+
return (_jsxs("label", { className: clsx("PaCheckbox", className), children: [_jsx("input", { className: "PaCheckbox-input", type: "checkbox", checked: checked, onChange: handleChange, ...rest }), _jsx("span", { className: "PaCheckbox-label", children: label })] }));
|
|
10
|
+
}
|
|
11
|
+
return (_jsx("input", { className: clsx("PaCheckbox-input", className), type: "checkbox", checked: checked, onChange: handleChange, ...rest }));
|
|
12
|
+
}
|
package/dist/Chip.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "../styles/Chip.css";
|
|
2
|
+
export interface ChipProps {
|
|
3
|
+
label: string;
|
|
4
|
+
onRemove?: () => void;
|
|
5
|
+
className?: string;
|
|
6
|
+
removable?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function Chip({ label, onRemove, className, removable }: ChipProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Chip.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { X } from "lucide-react";
|
|
4
|
+
import "../styles/Chip.css";
|
|
5
|
+
export function Chip({ label, onRemove, className, removable = true }) {
|
|
6
|
+
return (_jsxs("span", { className: clsx("PaChip", className), children: [_jsx("span", { className: "PaChip-label", children: label }), removable && onRemove && (_jsx("button", { type: "button", className: "PaChip-remove", onClick: onRemove, "aria-label": `Remove ${label}`, children: _jsx(X, { size: 12 }) }))] }));
|
|
7
|
+
}
|
package/dist/Column.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from "react";
|
|
2
|
+
export interface ColumnProps<T = unknown> {
|
|
3
|
+
field?: keyof T & string;
|
|
4
|
+
header?: string;
|
|
5
|
+
body?: (rowData: T) => ReactNode;
|
|
6
|
+
style?: CSSProperties;
|
|
7
|
+
sortable?: boolean;
|
|
8
|
+
bodyClassName?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render-less component for column definition.
|
|
12
|
+
* Used for configuration only - does not render anything.
|
|
13
|
+
*/
|
|
14
|
+
export declare function Column<T>(_props: ColumnProps<T>): null;
|
package/dist/Column.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import "../styles/DataTable.css";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
export interface DataTableProps<T> {
|
|
4
|
+
value: T[];
|
|
5
|
+
dataKey: keyof T & string;
|
|
6
|
+
size?: "small" | "normal";
|
|
7
|
+
loading?: boolean;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
emptyMessage?: string;
|
|
11
|
+
paginator?: boolean;
|
|
12
|
+
rows?: number;
|
|
13
|
+
totalRecords?: number;
|
|
14
|
+
first?: number;
|
|
15
|
+
onPage?: (event: {
|
|
16
|
+
first: number;
|
|
17
|
+
rows: number;
|
|
18
|
+
}) => void;
|
|
19
|
+
rowsPerPageOptions?: number[];
|
|
20
|
+
sortField?: string;
|
|
21
|
+
sortOrder?: 1 | -1;
|
|
22
|
+
onSort?: (event: {
|
|
23
|
+
field: string;
|
|
24
|
+
order: 1 | -1;
|
|
25
|
+
}) => void;
|
|
26
|
+
onRowClick?: (row: T, event: React.MouseEvent) => void;
|
|
27
|
+
rowClassName?: (row: T) => string | undefined;
|
|
28
|
+
totalLabel?: string;
|
|
29
|
+
}
|
|
30
|
+
export declare function DataTable<T extends object>({ value, dataKey, size, loading, children, className, emptyMessage, paginator, rows, totalRecords, first, onPage, rowsPerPageOptions, sortField, sortOrder, onSort, onRowClick, rowClassName, totalLabel, }: DataTableProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/DataTable.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { ArrowDown, ArrowUp, ChevronLeft, ChevronRight, ChevronsUpDown } from "lucide-react";
|
|
5
|
+
import { Children, isValidElement } from "react";
|
|
6
|
+
import { Select } from "./Select.js";
|
|
7
|
+
import { Spinner } from "./Spinner.js";
|
|
8
|
+
export function DataTable({ value, dataKey, size, loading, children, className, emptyMessage = "No data available", paginator, rows = 10, totalRecords, first = 0, onPage, rowsPerPageOptions, sortField, sortOrder, onSort, onRowClick, rowClassName, totalLabel, }) {
|
|
9
|
+
// Extract column definitions from children
|
|
10
|
+
const columns = [];
|
|
11
|
+
Children.forEach(children, (child) => {
|
|
12
|
+
if (isValidElement(child) && child.props) {
|
|
13
|
+
columns.push(child.props);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
const total = totalRecords ?? value.length;
|
|
17
|
+
const pageCount = Math.ceil(total / rows);
|
|
18
|
+
const currentPage = Math.floor(first / rows) + 1;
|
|
19
|
+
const handleSort = (field) => {
|
|
20
|
+
if (!field || !onSort)
|
|
21
|
+
return;
|
|
22
|
+
const newOrder = sortField === field && sortOrder === 1 ? -1 : 1;
|
|
23
|
+
onSort({ field, order: newOrder });
|
|
24
|
+
};
|
|
25
|
+
return (_jsxs("div", { className: clsx("PaDataTable-wrapper", loading && "loading"), children: [loading && (_jsx("div", { className: "PaDataTable-overlay", children: _jsx(Spinner, {}) })), _jsx("div", { className: "PaDataTable-scrollable", children: _jsxs("table", { className: clsx("PaDataTable", size, className), children: [_jsx("thead", { className: "PaDataTable-header", children: _jsx("tr", { children: columns.map((col, i) => (_jsx("th", { className: clsx("PaDataTable-headerCell", col.sortable && "sortable"), style: col.style, onClick: col.sortable ? () => handleSort(col.field) : undefined, tabIndex: 0, children: _jsxs("span", { className: "PaDataTable-headerContent", children: [col.header, col.sortable && (_jsx("span", { className: "PaDataTable-sortIcon", children: col.field === sortField ? (sortOrder === 1 ? (_jsx(ArrowDown, { size: 14 })) : (_jsx(ArrowUp, { size: 14 }))) : (_jsx(ChevronsUpDown, { size: 14 })) }))] }) }, col.field ?? i))) }) }), _jsx("tbody", { children: value.length === 0 ? (_jsx("tr", { className: "PaDataTable-emptyRow", children: _jsx("td", { colSpan: columns.length, className: "PaDataTable-emptyCell", children: emptyMessage }) })) : (value.map((row) => (_jsx("tr", { className: clsx("PaDataTable-row", onRowClick && "clickable", rowClassName?.(row)), onClick: onRowClick ? (e) => onRowClick(row, e) : undefined, children: columns.map((col, i) => (_jsx("td", { className: clsx("PaDataTable-cell", col.bodyClassName), style: col.style, children: col.body ? col.body(row) : col.field ? String(row[col.field] ?? "") : null }, col.field ?? i))) }, String(row[dataKey]))))) })] }) }), paginator && onPage && pageCount > 0 && (_jsxs("div", { className: "PaDataTable-footer", children: [_jsxs("span", { className: "PaDataTable-totalCount", children: [total, " ", totalLabel ?? "items"] }), _jsxs("div", { className: "PaDataTable-pagination", children: [_jsx("button", { type: "button", className: "PaDataTable-paginationBtn", disabled: currentPage <= 1, onClick: () => onPage({ first: first - rows, rows }), children: _jsx(ChevronLeft, { size: 16 }) }), _jsxs("span", { className: "PaDataTable-paginationText", children: ["Page ", currentPage, " of ", pageCount] }), _jsx("button", { type: "button", className: "PaDataTable-paginationBtn", disabled: currentPage >= pageCount, onClick: () => onPage({ first: first + rows, rows }), children: _jsx(ChevronRight, { size: 16 }) }), rowsPerPageOptions && rowsPerPageOptions.length > 0 && (_jsx(Select, { className: "PaDataTable-rowsPerPage", value: String(rows), options: rowsPerPageOptions.map((n) => ({ label: String(n), value: String(n) })), onChange: (val) => onPage({ first: 0, rows: Number(val) }) }))] })] }))] }));
|
|
26
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "../styles/DateInput.css";
|
|
2
|
+
import type { InputHTMLAttributes, Ref } from "react";
|
|
3
|
+
export interface DateInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
|
|
4
|
+
type: "date" | "datetime-local" | "time";
|
|
5
|
+
label?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
ref?: Ref<HTMLInputElement>;
|
|
8
|
+
}
|
|
9
|
+
export declare function DateInput({ className, label, error, type, ref, ...props }: DateInputProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/DateInput.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
export function DateInput({ className, label, error, type, ref, ...props }) {
|
|
5
|
+
const inputElement = (_jsx("input", { ref: ref, type: type, className: clsx("PaDateInput-field", error && "error"), ...props }));
|
|
6
|
+
return (_jsxs("span", { className: clsx("PaDateInput", className), children: [label ? (_jsxs("label", { className: "PaDateInput-wrapper", children: [_jsx("span", { className: "PaDateInput-label", children: label }), inputElement] })) : (inputElement), error && _jsx("span", { className: "PaDateInput-error", children: error })] }));
|
|
7
|
+
}
|
package/dist/Dialog.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "../styles/Dialog.css";
|
|
2
|
+
import { type ReactNode } from "react";
|
|
3
|
+
export interface DialogProps {
|
|
4
|
+
visible: boolean;
|
|
5
|
+
onHide: () => void;
|
|
6
|
+
header?: ReactNode;
|
|
7
|
+
footer?: ReactNode;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
closable?: boolean;
|
|
11
|
+
modal?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function Dialog({ visible, onHide, header, footer, children, className, closable, modal, }: DialogProps): import("react").ReactPortal | null;
|
package/dist/Dialog.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/Dialog.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { X } from "lucide-react";
|
|
5
|
+
import { useEffect, useRef } from "react";
|
|
6
|
+
import { createPortal } from "react-dom";
|
|
7
|
+
/** Track dialog stack for ESC key handling - only topmost dialog should respond */
|
|
8
|
+
let dialogStackCounter = 0;
|
|
9
|
+
export function Dialog({ visible, onHide, header, footer, children, className, closable = true, modal = true, }) {
|
|
10
|
+
// Track this dialog's position in the stack for ESC key handling
|
|
11
|
+
const dialogIdRef = useRef(undefined);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
if (visible) {
|
|
14
|
+
dialogIdRef.current = ++dialogStackCounter;
|
|
15
|
+
}
|
|
16
|
+
return () => {
|
|
17
|
+
if (dialogIdRef.current !== undefined) {
|
|
18
|
+
// Decrement only if this was the topmost dialog
|
|
19
|
+
if (dialogIdRef.current === dialogStackCounter) {
|
|
20
|
+
dialogStackCounter--;
|
|
21
|
+
}
|
|
22
|
+
dialogIdRef.current = undefined;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
}, [visible]);
|
|
26
|
+
// Handle escape key - only the topmost dialog should respond
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!visible || !closable)
|
|
29
|
+
return;
|
|
30
|
+
const handleKeyDown = (e) => {
|
|
31
|
+
// Only handle ESC if this is the topmost dialog
|
|
32
|
+
if (e.key === "Escape" && dialogIdRef.current === dialogStackCounter) {
|
|
33
|
+
onHide();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
37
|
+
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
38
|
+
}, [visible, closable, onHide]);
|
|
39
|
+
// Prevent body scroll when open
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (visible) {
|
|
42
|
+
document.body.style.overflow = "hidden";
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
document.body.style.overflow = "";
|
|
46
|
+
}
|
|
47
|
+
return () => {
|
|
48
|
+
document.body.style.overflow = "";
|
|
49
|
+
};
|
|
50
|
+
}, [visible]);
|
|
51
|
+
if (!visible)
|
|
52
|
+
return null;
|
|
53
|
+
const dialog = (_jsxs("div", { className: "PaDialog-overlay", children: [modal && _jsx("div", { className: "PaDialog-backdrop", onClick: closable ? onHide : undefined }), _jsxs("div", { className: clsx("PaDialog", className), role: "dialog", "aria-modal": modal, children: [(header || closable) && (_jsxs("div", { className: "PaDialog-header", children: [header && _jsx("div", { className: "PaDialog-title", children: header }), closable && (_jsx("button", { type: "button", className: "PaDialog-close", onClick: onHide, "aria-label": "Close", children: _jsx(X, { size: 18 }) }))] })), _jsx("div", { className: "PaDialog-content", children: children }), footer && _jsx("div", { className: "PaDialog-footer", children: footer })] })] }));
|
|
54
|
+
return createPortal(dialog, document.body);
|
|
55
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import "../styles/Inplace.css";
|
|
3
|
+
export interface InplaceProps {
|
|
4
|
+
display: ReactNode;
|
|
5
|
+
children: ReactNode;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
onOpen?: () => void;
|
|
8
|
+
onClose?: () => void;
|
|
9
|
+
className?: string;
|
|
10
|
+
closable?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function Inplace({ display, children, active, onOpen, onClose, className, closable, }: InplaceProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Inplace.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import "../styles/Inplace.css";
|
|
4
|
+
export function Inplace({ display, children, active = false, onOpen, onClose, className, closable = true, }) {
|
|
5
|
+
if (!active) {
|
|
6
|
+
return (
|
|
7
|
+
// biome-ignore lint/a11y/useSemanticElements: custom behavior
|
|
8
|
+
_jsx("div", { className: clsx("PaInplace", "display", className), onClick: onOpen, onKeyDown: (e) => {
|
|
9
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
onOpen?.();
|
|
12
|
+
}
|
|
13
|
+
}, tabIndex: 0, role: "button", children: display }));
|
|
14
|
+
}
|
|
15
|
+
return (_jsxs("div", { className: clsx("PaInplace", "active", className), children: [_jsx("div", { className: "PaInplace-content", children: children }), closable && onClose && (_jsx("button", { type: "button", className: "PaInplace-close", onClick: onClose, children: "Done" }))] }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { InputHTMLAttributes, Ref } from "react";
|
|
2
|
+
import "../styles/InputNumber.css";
|
|
3
|
+
export interface InputNumberProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "onChange"> {
|
|
4
|
+
value: number | undefined;
|
|
5
|
+
onChange: (value: number | undefined) => void;
|
|
6
|
+
label?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
ref?: Ref<HTMLInputElement>;
|
|
9
|
+
}
|
|
10
|
+
export declare function InputNumber({ className, label, error, value, onChange, min, max, step, ref, ...props }: InputNumberProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import "../styles/InputNumber.css";
|
|
4
|
+
export function InputNumber({ className, label, error, value, onChange, min, max, step, ref, ...props }) {
|
|
5
|
+
const handleChange = (e) => {
|
|
6
|
+
const val = e.target.value;
|
|
7
|
+
if (val === "") {
|
|
8
|
+
onChange(undefined);
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
const num = Number(val);
|
|
12
|
+
if (!Number.isNaN(num)) {
|
|
13
|
+
onChange(num);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const inputElement = (_jsx("input", { ref: ref, type: "number", className: clsx("PaInputNumber-field", error && "error"), value: value ?? "", onChange: handleChange, min: min, max: max, step: step, ...props }));
|
|
18
|
+
return (_jsxs("span", { className: clsx("PaInputNumber", className), children: [label ? (_jsxs("label", { className: "PaInputNumber-wrapper", children: [_jsx("span", { className: "PaInputNumber-label", children: label }), inputElement] })) : (inputElement), error && _jsx("span", { className: "PaInputNumber-error", children: error })] }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { InputHTMLAttributes, ReactNode } from "react";
|
|
2
|
+
import "../styles/InputText.css";
|
|
3
|
+
export interface InputTextProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "onChange"> {
|
|
4
|
+
value: string;
|
|
5
|
+
onChange: (value: string) => void;
|
|
6
|
+
label?: string;
|
|
7
|
+
error?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
fullWidth?: boolean;
|
|
10
|
+
endElement?: ReactNode;
|
|
11
|
+
icon?: ReactNode;
|
|
12
|
+
iconPosition?: "left" | "right";
|
|
13
|
+
}
|
|
14
|
+
export declare function InputText({ value, onChange, label, error, className, fullWidth, endElement, icon, iconPosition, ...rest }: InputTextProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import "../styles/InputText.css";
|
|
4
|
+
export function InputText({ value, onChange, label, error, className, fullWidth = false, endElement, icon, iconPosition = "left", ...rest }) {
|
|
5
|
+
const handleChange = (e) => {
|
|
6
|
+
onChange(e.target.value);
|
|
7
|
+
};
|
|
8
|
+
const inputElement = (_jsx("input", { className: "PaInputText-field", value: value, onChange: handleChange, ...rest }));
|
|
9
|
+
const fieldContent = endElement ? (_jsxs("span", { className: "PaInputText-row", children: [inputElement, endElement] })) : icon ? (_jsxs("span", { className: clsx("PaInputText-iconWrapper", iconPosition === "right" && "iconRight"), children: [_jsx("span", { className: "PaInputText-icon", children: icon }), inputElement] })) : (inputElement);
|
|
10
|
+
return (_jsxs("span", { className: clsx("PaInputText", error && "error", fullWidth && "fullWidth", className), children: [label ? (_jsxs("label", { className: "PaInputText-wrapper", children: [_jsx("span", { className: "PaInputText-label", children: label }), fieldContent] })) : (fieldContent), error && _jsx("span", { className: "PaInputText-error", children: error })] }));
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import "../styles/MenuItem.css";
|
|
2
|
+
import type { MenuOption } from "./paroi-ui-lib-types.js";
|
|
3
|
+
export interface MenuItemProps {
|
|
4
|
+
item: MenuOption;
|
|
5
|
+
expanded?: boolean;
|
|
6
|
+
onToggle?: (expanded: boolean) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function MenuItem({ item, expanded, onToggle }: MenuItemProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/MenuItem.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../styles/MenuItem.css";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
5
|
+
import { PopupMenu } from "./PopupMenu.js";
|
|
6
|
+
export function MenuItem({ item, expanded, onToggle }) {
|
|
7
|
+
let { key: id, label, icon, url, command, popupMenu, className, style, active, disabled } = item;
|
|
8
|
+
if (disabled) {
|
|
9
|
+
url = undefined;
|
|
10
|
+
command = undefined;
|
|
11
|
+
}
|
|
12
|
+
return (_jsxs("div", { className: clsx("PaMenuItem", active && "active", disabled && "disabled", className), style: style, children: [expanded !== undefined && onToggle ? (_jsx("button", { className: "PaMenuItem-left toggle", onClick: () => onToggle(!expanded), type: "button", children: expanded ? _jsx(ChevronDown, { size: 14 }) : _jsx(ChevronRight, { size: 14 }) })) : icon ? (_jsx("div", { className: "PaMenuItem-left icon", children: icon })) : undefined, url ? (_jsx("a", { className: "PaMenuItem-label", href: url, onClick: url && command
|
|
13
|
+
? (ev) => {
|
|
14
|
+
ev.preventDefault();
|
|
15
|
+
command?.();
|
|
16
|
+
}
|
|
17
|
+
: undefined, children: label })) : command ? (_jsx("button", { className: "PaMenuItem-label", onClick: command, type: "button", children: label })) : (_jsx("span", { className: "PaMenuItem-label", children: label })), popupMenu && _jsx(PopupMenu, { className: "PaMenuItem-popup", items: popupMenu })] }, id));
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import "../styles/MultiSelect.css";
|
|
2
|
+
export interface MultiSelectOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface MultiSelectProps {
|
|
8
|
+
value: string[];
|
|
9
|
+
onChange: (value: string[]) => void;
|
|
10
|
+
options: MultiSelectOption[];
|
|
11
|
+
label?: string;
|
|
12
|
+
error?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
placeholder?: string;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function MultiSelect({ value, onChange, options, label, error, className, placeholder, disabled, }: MultiSelectProps): import("react/jsx-runtime").JSX.Element;
|