@koobiq/react-components 0.22.0 → 0.23.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/Autocomplete/Autocomplete.js +2 -2
- package/dist/components/Button/Button.js +1 -0
- package/dist/components/Calendar/Calendar.js +9 -10
- package/dist/components/Calendar/components/CalendarCell/CalendarCell.js +11 -1
- package/dist/components/Calendar/components/CalendarGrid/CalendarGrid.d.ts +2 -6
- package/dist/components/Calendar/components/CalendarGrid/CalendarGrid.js +13 -3
- package/dist/components/Calendar/components/CalendarGrid/index.d.ts +1 -0
- package/dist/components/Calendar/components/CalendarGrid/types.d.ts +10 -0
- package/dist/components/Calendar/components/CalendarHeader/CalendarHeader.d.ts +1 -7
- package/dist/components/Calendar/components/CalendarHeader/CalendarHeader.js +13 -6
- package/dist/components/Calendar/components/CalendarHeader/index.d.ts +1 -0
- package/dist/components/Calendar/components/CalendarHeader/types.d.ts +16 -0
- package/dist/components/Calendar/components/CalendarMonthDropdown/CalendarMonthDropdown.d.ts +11 -3
- package/dist/components/Calendar/components/CalendarMonthDropdown/CalendarMonthDropdown.js +26 -15
- package/dist/components/Calendar/components/CalendarYearDropdown/CalendarYearDropdown.d.ts +11 -3
- package/dist/components/Calendar/components/CalendarYearDropdown/CalendarYearDropdown.js +26 -15
- package/dist/components/Calendar/types.d.ts +8 -1
- package/dist/components/CheckboxGroup/CheckboxGroup.js +2 -2
- package/dist/components/ContenPanel/ContentPanel.d.ts +32 -0
- package/dist/components/ContenPanel/ContentPanel.js +157 -0
- package/dist/components/ContenPanel/ContentPanel.module.css.js +17 -0
- package/dist/components/ContenPanel/ContentPanelContext.d.ts +3 -0
- package/dist/components/ContenPanel/ContentPanelContext.js +6 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/ContentPanelContainer.d.ts +2 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/ContentPanelContainer.js +108 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/ContentPanelContainer.module.css.js +14 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/ContentPanelContainerContext.d.ts +7 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/ContentPanelContainerContext.js +8 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/index.d.ts +3 -0
- package/dist/components/ContenPanel/components/ContentPanelContainer/types.d.ts +23 -0
- package/dist/components/ContenPanel/components/index.d.ts +1 -0
- package/dist/components/ContenPanel/constants.d.ts +1 -0
- package/dist/components/ContenPanel/constants.js +4 -0
- package/dist/components/ContenPanel/hooks/index.d.ts +2 -0
- package/dist/components/ContenPanel/hooks/useContentPanelContainer/index.d.ts +1 -0
- package/dist/components/ContenPanel/hooks/useContentPanelContainer/useContentPanelContainer.d.ts +14 -0
- package/dist/components/ContenPanel/hooks/useContentPanelContainer/useContentPanelContainer.js +19 -0
- package/dist/components/ContenPanel/hooks/useContentPanelResize/index.d.ts +1 -0
- package/dist/components/ContenPanel/hooks/useContentPanelResize/intl.json.js +7 -0
- package/dist/components/ContenPanel/hooks/useContentPanelResize/useContentPanelResize.d.ts +32 -0
- package/dist/components/ContenPanel/hooks/useContentPanelResize/useContentPanelResize.js +80 -0
- package/dist/components/ContenPanel/index.d.ts +3 -0
- package/dist/components/ContenPanel/types.d.ts +53 -0
- package/dist/components/ContenPanel/utils/index.d.ts +3 -0
- package/dist/components/ContenPanel/utils/index.js +31 -0
- package/dist/components/DateInput/DateInput.js +2 -2
- package/dist/components/DatePicker/DatePicker.js +21 -21
- package/dist/components/DatePicker/types.d.ts +1 -0
- package/dist/components/Dialog/types.d.ts +1 -1
- package/dist/components/FormField/FormFieldInputDate/FormFieldInputDate.d.ts +3 -2
- package/dist/components/IconButton/IconButton.js +1 -0
- package/dist/components/Input/Input.js +2 -2
- package/dist/components/InputNumber/InputNumber.js +2 -2
- package/dist/components/Link/Link.js +0 -2
- package/dist/components/Menu/components/MenuItem/MenuItem.js +8 -1
- package/dist/components/RadioGroup/RadioGroup.js +2 -2
- package/dist/components/SearchInput/SearchInput.js +2 -2
- package/dist/components/Select/Select.js +2 -2
- package/dist/components/Select/intl.js +2 -2
- package/dist/components/Table/components/TableColumnHeader/TableColumnHeader.js +2 -2
- package/dist/components/Textarea/components/TextareaContextConsumer/TextareaContextConsumer.js +2 -2
- package/dist/components/TimePicker/TimePicker.js +2 -2
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/style.css +90 -0
- package/package.json +5 -5
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef, useState, useRef, useMemo } from "react";
|
|
4
|
+
import { useMultiRef, useResizeObserverRefs, mergeProps, clsx } from "@koobiq/react-core";
|
|
5
|
+
import { useOverlayTriggerState, Provider, ButtonContext, DEFAULT_SLOT } from "@koobiq/react-primitives";
|
|
6
|
+
import { TRANSITION_TIMEOUT } from "../../constants.js";
|
|
7
|
+
import { ContentPanelContext } from "../../ContentPanelContext.js";
|
|
8
|
+
import { getInlineSize } from "../../utils/index.js";
|
|
9
|
+
import s from "./ContentPanelContainer.module.css.js";
|
|
10
|
+
import { ContentPanelContainerContext } from "./ContentPanelContainerContext.js";
|
|
11
|
+
import { useContentPanelContainer } from "../../hooks/useContentPanelContainer/useContentPanelContainer.js";
|
|
12
|
+
const ContentPanelContainer = forwardRef((props, ref) => {
|
|
13
|
+
const {
|
|
14
|
+
children,
|
|
15
|
+
isOpen,
|
|
16
|
+
onOpenChange,
|
|
17
|
+
disableExitOnEscapeKeyDown,
|
|
18
|
+
defaultOpen,
|
|
19
|
+
className,
|
|
20
|
+
slotProps,
|
|
21
|
+
...other
|
|
22
|
+
} = props;
|
|
23
|
+
const state = useOverlayTriggerState({
|
|
24
|
+
isOpen,
|
|
25
|
+
onOpenChange,
|
|
26
|
+
defaultOpen
|
|
27
|
+
});
|
|
28
|
+
const [portalContainer, setPortalContainer] = useState(
|
|
29
|
+
null
|
|
30
|
+
);
|
|
31
|
+
const { triggerProps, containerProps } = useContentPanelContainer(
|
|
32
|
+
{ isKeyboardDismissDisabled: !!disableExitOnEscapeKeyDown },
|
|
33
|
+
state
|
|
34
|
+
);
|
|
35
|
+
const containerRef = useRef(null);
|
|
36
|
+
const panelRef = useRef(null);
|
|
37
|
+
const domRef = useMultiRef([
|
|
38
|
+
ref,
|
|
39
|
+
containerRef,
|
|
40
|
+
setPortalContainer
|
|
41
|
+
]);
|
|
42
|
+
const observedRefs = useMemo(
|
|
43
|
+
() => [containerRef, panelRef],
|
|
44
|
+
[panelRef.current, containerRef.current, state.isOpen]
|
|
45
|
+
);
|
|
46
|
+
const [containerWidth, panelWidth] = useResizeObserverRefs(
|
|
47
|
+
observedRefs,
|
|
48
|
+
(el) => {
|
|
49
|
+
if (el) return getInlineSize(el);
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
const rootProps = mergeProps(
|
|
54
|
+
{
|
|
55
|
+
className: clsx(s.base, className),
|
|
56
|
+
ref: domRef,
|
|
57
|
+
...other
|
|
58
|
+
},
|
|
59
|
+
containerProps
|
|
60
|
+
);
|
|
61
|
+
const bodyProps = {
|
|
62
|
+
...slotProps?.body,
|
|
63
|
+
className: clsx(s.body, slotProps?.body?.className),
|
|
64
|
+
children: typeof children === "function" ? children(state) : children,
|
|
65
|
+
style: {
|
|
66
|
+
...slotProps?.body?.style,
|
|
67
|
+
"--content-panel-inline-size": `${panelWidth}px`,
|
|
68
|
+
"--content-body-transition-duration": `${TRANSITION_TIMEOUT}ms`
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
return /* @__PURE__ */ jsx(
|
|
72
|
+
Provider,
|
|
73
|
+
{
|
|
74
|
+
values: [
|
|
75
|
+
[
|
|
76
|
+
ContentPanelContainerContext,
|
|
77
|
+
{
|
|
78
|
+
state,
|
|
79
|
+
containerWidth: containerWidth || void 0,
|
|
80
|
+
portalContainer
|
|
81
|
+
}
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
ContentPanelContext,
|
|
85
|
+
{
|
|
86
|
+
ref: panelRef,
|
|
87
|
+
className: s.panel,
|
|
88
|
+
disableExitOnEscapeKeyDown
|
|
89
|
+
}
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
ButtonContext,
|
|
93
|
+
{
|
|
94
|
+
slots: {
|
|
95
|
+
[DEFAULT_SLOT]: {},
|
|
96
|
+
trigger: triggerProps
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
]
|
|
100
|
+
],
|
|
101
|
+
children: /* @__PURE__ */ jsx("div", { ...rootProps, children: /* @__PURE__ */ jsx("div", { ...bodyProps }) })
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
});
|
|
105
|
+
ContentPanelContainer.displayName = "ContentPanelContainer";
|
|
106
|
+
export {
|
|
107
|
+
ContentPanelContainer
|
|
108
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const base = "kbq-contentpanelcontainer-476965";
|
|
2
|
+
const body = "kbq-contentpanelcontainer-body-b7b172";
|
|
3
|
+
const panel = "kbq-contentpanelcontainer-panel-03cf65";
|
|
4
|
+
const s = {
|
|
5
|
+
base,
|
|
6
|
+
body,
|
|
7
|
+
panel
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
base,
|
|
11
|
+
body,
|
|
12
|
+
s as default,
|
|
13
|
+
panel
|
|
14
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { OverlayTriggerState } from '@react-stately/overlays';
|
|
2
|
+
export type ContentPanelStateContextProps = {
|
|
3
|
+
portalContainer?: HTMLElement | null;
|
|
4
|
+
containerWidth?: number;
|
|
5
|
+
state: OverlayTriggerState;
|
|
6
|
+
};
|
|
7
|
+
export declare const ContentPanelContainerContext: import("react").Context<ContentPanelStateContextProps>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ComponentRef, ReactElement, ReactNode } from 'react';
|
|
2
|
+
import type { DataAttributeProps, ExtendableComponentPropsWithRef } from '@koobiq/react-core';
|
|
3
|
+
import type { OverlayTriggerState } from '@react-stately/overlays';
|
|
4
|
+
export type ContentPanelContainerPropContent = ReactNode | ((props: OverlayTriggerState) => ReactElement);
|
|
5
|
+
export type ContentPanelContainerProps = ExtendableComponentPropsWithRef<{
|
|
6
|
+
/** The content of the container. Can be a render function with panel state. */
|
|
7
|
+
children?: ContentPanelContainerPropContent;
|
|
8
|
+
/** If `true`, the panel is open (controlled). */
|
|
9
|
+
isOpen?: boolean;
|
|
10
|
+
/** The default open state (uncontrolled). */
|
|
11
|
+
defaultOpen?: boolean;
|
|
12
|
+
/** Handler that is called when the panel's open state changes. */
|
|
13
|
+
onOpenChange?: (open: boolean) => void;
|
|
14
|
+
/** The props used for each slot inside. */
|
|
15
|
+
slotProps?: {
|
|
16
|
+
body?: ComponentPropsWithRef<'div'> & DataAttributeProps;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* If `true`, the content panel won't close when the ESC key is pressed.
|
|
20
|
+
*/
|
|
21
|
+
disableExitOnEscapeKeyDown?: boolean;
|
|
22
|
+
}, 'div'>;
|
|
23
|
+
export type ContentPanelContainerRef = ComponentRef<'div'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ContentPanelContainer';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const TRANSITION_TIMEOUT = 300;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useContentPanelContainer';
|
package/dist/components/ContenPanel/hooks/useContentPanelContainer/useContentPanelContainer.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
import type { ButtonBaseProps } from '@koobiq/react-primitives';
|
|
3
|
+
import type { OverlayTriggerState } from '@react-stately/overlays';
|
|
4
|
+
export type UseContentPanelReturnValue = {
|
|
5
|
+
triggerProps: ButtonBaseProps;
|
|
6
|
+
closeButtonProps: ButtonBaseProps;
|
|
7
|
+
containerProps?: HTMLAttributes<HTMLElement>;
|
|
8
|
+
panelProps?: HTMLAttributes<HTMLElement>;
|
|
9
|
+
bodyProps?: HTMLAttributes<HTMLElement>;
|
|
10
|
+
};
|
|
11
|
+
export type UseContentPanelContainerProps = {
|
|
12
|
+
isKeyboardDismissDisabled: boolean;
|
|
13
|
+
};
|
|
14
|
+
export declare function useContentPanelContainer(props: UseContentPanelContainerProps, state: OverlayTriggerState): UseContentPanelReturnValue;
|
package/dist/components/ContenPanel/hooks/useContentPanelContainer/useContentPanelContainer.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
function useContentPanelContainer(props, state) {
|
|
3
|
+
const { isKeyboardDismissDisabled } = props;
|
|
4
|
+
return {
|
|
5
|
+
containerProps: {
|
|
6
|
+
tabIndex: -1,
|
|
7
|
+
onKeyDown: (event) => {
|
|
8
|
+
if (isKeyboardDismissDisabled) return;
|
|
9
|
+
if (!state.isOpen) return;
|
|
10
|
+
if (event.key === "Escape") state.close();
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
triggerProps: { onPress: state.open },
|
|
14
|
+
closeButtonProps: { onPress: state.close }
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
useContentPanelContainer
|
|
19
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './useContentPanelResize';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'react';
|
|
2
|
+
export type UseContentPanelResizeProps = {
|
|
3
|
+
/** The controlled width of the panel (in pixels). */
|
|
4
|
+
width?: number | null;
|
|
5
|
+
/** If `true`, the panel can be resized by dragging the resizer. */
|
|
6
|
+
isResizable?: boolean;
|
|
7
|
+
/** The initial width of the panel when uncontrolled (in pixels). */
|
|
8
|
+
defaultWidth?: number | null;
|
|
9
|
+
/** The minimum allowed width of the panel (in pixels). */
|
|
10
|
+
minWidth?: number | null;
|
|
11
|
+
/** The maximum allowed width of the panel (in pixels). */
|
|
12
|
+
maxWidth?: number | null;
|
|
13
|
+
/** Handler that is called whenever the panel width changes. */
|
|
14
|
+
onResize?: (width: number) => void;
|
|
15
|
+
/** Handler that is called when the user starts resizing the panel. */
|
|
16
|
+
onResizeStart?: (width: number) => void;
|
|
17
|
+
/** Handler that is called when the user finishes resizing the panel. */
|
|
18
|
+
onResizeEnd?: (width: number) => void;
|
|
19
|
+
/**
|
|
20
|
+
* Handler that is called when the panel width is reset (double click on the resizer).
|
|
21
|
+
* Receives the initial width and can return the width to apply.
|
|
22
|
+
* If nothing is returned, the panel resets to the initial width.
|
|
23
|
+
*/
|
|
24
|
+
onResetResize?: (initialWidth: number) => number | null | undefined;
|
|
25
|
+
};
|
|
26
|
+
export type UseContentPanelResizeReturnValue = {
|
|
27
|
+
/** Current panel width in pixels (only when `isResizable` is `true`). */
|
|
28
|
+
width?: number;
|
|
29
|
+
/** Props to spread on the resizer element (drag + double click reset + aria). */
|
|
30
|
+
resizerProps: HTMLAttributes<HTMLElement>;
|
|
31
|
+
};
|
|
32
|
+
export declare function useContentPanelResize(props: UseContentPanelResizeProps): UseContentPanelResizeReturnValue;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useRef, useCallback, useMemo } from "react";
|
|
3
|
+
import { useLocalizedStringFormatter, isNumber, useControlledState, useMove, mergeProps } from "@koobiq/react-core";
|
|
4
|
+
import intlMessages from "./intl.json.js";
|
|
5
|
+
const clamp = (v, min, max) => Math.max(min, Math.min(max, v));
|
|
6
|
+
function useContentPanelResize(props) {
|
|
7
|
+
const {
|
|
8
|
+
isResizable = false,
|
|
9
|
+
width: widthProp,
|
|
10
|
+
defaultWidth,
|
|
11
|
+
minWidth,
|
|
12
|
+
maxWidth,
|
|
13
|
+
onResize,
|
|
14
|
+
onResetResize,
|
|
15
|
+
onResizeStart,
|
|
16
|
+
onResizeEnd
|
|
17
|
+
} = props;
|
|
18
|
+
const t = useLocalizedStringFormatter(intlMessages);
|
|
19
|
+
const min = isNumber(minWidth) ? minWidth : 0;
|
|
20
|
+
const max = isNumber(maxWidth) ? maxWidth : Number.POSITIVE_INFINITY;
|
|
21
|
+
const controlledWidth = isNumber(widthProp) ? clamp(widthProp, min, max) : void 0;
|
|
22
|
+
const defaultUncontrolled = isNumber(defaultWidth) ? clamp(defaultWidth, min, max) : 0;
|
|
23
|
+
const [width, setWidth] = useControlledState(
|
|
24
|
+
controlledWidth,
|
|
25
|
+
defaultUncontrolled,
|
|
26
|
+
onResize
|
|
27
|
+
);
|
|
28
|
+
const widthRef = useRef(width);
|
|
29
|
+
widthRef.current = width;
|
|
30
|
+
const initialResetRef = useRef(null);
|
|
31
|
+
if (initialResetRef.current == null) {
|
|
32
|
+
initialResetRef.current = isNumber(widthProp) ? clamp(widthProp, min, max) : defaultUncontrolled;
|
|
33
|
+
}
|
|
34
|
+
const onReset = useCallback(() => {
|
|
35
|
+
if (!isResizable) return;
|
|
36
|
+
const initial = initialResetRef.current ?? 0;
|
|
37
|
+
const nextRaw = onResetResize?.(initial);
|
|
38
|
+
const next = clamp(isNumber(nextRaw) ? nextRaw : initial, min, max);
|
|
39
|
+
setWidth(next);
|
|
40
|
+
}, [isResizable, onResetResize, min, max, setWidth]);
|
|
41
|
+
const { moveProps } = useMove({
|
|
42
|
+
onMoveStart() {
|
|
43
|
+
if (!isResizable) return;
|
|
44
|
+
document.body.dataset.resizing = "true";
|
|
45
|
+
onResizeStart?.(Math.round(widthRef.current));
|
|
46
|
+
},
|
|
47
|
+
onMoveEnd() {
|
|
48
|
+
if (!isResizable) return;
|
|
49
|
+
delete document.body.dataset.resizing;
|
|
50
|
+
onResizeEnd?.(Math.round(widthRef.current));
|
|
51
|
+
},
|
|
52
|
+
onMove(e) {
|
|
53
|
+
if (!isResizable) return;
|
|
54
|
+
setWidth((w) => {
|
|
55
|
+
const next = clamp(w - e.deltaX, min, max);
|
|
56
|
+
widthRef.current = next;
|
|
57
|
+
return next;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
const resizerProps = useMemo(() => {
|
|
62
|
+
if (!isResizable) {
|
|
63
|
+
return {
|
|
64
|
+
tabIndex: -1,
|
|
65
|
+
"aria-hidden": "true"
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const aria = {
|
|
69
|
+
"aria-label": t.format("resize panel"),
|
|
70
|
+
"aria-valuenow": Math.round(width)
|
|
71
|
+
};
|
|
72
|
+
if (isNumber(minWidth)) aria["aria-valuemin"] = min;
|
|
73
|
+
if (isNumber(maxWidth)) aria["aria-valuemax"] = max;
|
|
74
|
+
return mergeProps(aria, { onDoubleClick: onReset }, moveProps);
|
|
75
|
+
}, [isResizable, width, minWidth, maxWidth, min, max, moveProps, onReset]);
|
|
76
|
+
return { width: isResizable ? width : void 0, resizerProps };
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
useContentPanelResize
|
|
80
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ComponentRef, CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import type { DataAttributeProps } from '@koobiq/react-core';
|
|
3
|
+
import type { TransitionProps } from 'react-transition-group/Transition';
|
|
4
|
+
import type { DialogProps } from '../Dialog';
|
|
5
|
+
export type ContentPanelSize = number | `${number}` | `${number}%`;
|
|
6
|
+
export type ContentPanelProps = {
|
|
7
|
+
/** The content of the panel. */
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
/** The width of the panel. */
|
|
10
|
+
width?: ContentPanelSize | null;
|
|
11
|
+
/** The minimum width of the panel. */
|
|
12
|
+
minWidth?: ContentPanelSize | null;
|
|
13
|
+
/** The maximum width of the panel. */
|
|
14
|
+
maxWidth?: ContentPanelSize | null;
|
|
15
|
+
/** The default width of the panel. */
|
|
16
|
+
defaultWidth?: ContentPanelSize | null;
|
|
17
|
+
/**
|
|
18
|
+
* If `true`, the panel can be resized by the user.
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
isResizable?: boolean;
|
|
22
|
+
/** Handler that is called whenever the panel width changes. */
|
|
23
|
+
onResize?: (width: number) => void;
|
|
24
|
+
/** Handler that is called when the user starts resizing the panel. */
|
|
25
|
+
onResizeStart?: (width: number) => void;
|
|
26
|
+
/** Handler that is called when the user finishes resizing the panel. */
|
|
27
|
+
onResizeEnd?: (width: number) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Handler that is called when the panel width is reset (double-click on the resizer).
|
|
30
|
+
* Receives the initial width and can return a new width.
|
|
31
|
+
* If nothing is returned, the panel resets to the initial width.
|
|
32
|
+
*/
|
|
33
|
+
onResetResize?: (initialWidth: number) => number | null | undefined;
|
|
34
|
+
/** If `true`, the panel is shown. */
|
|
35
|
+
isOpen?: boolean;
|
|
36
|
+
/** The default open state. Use when the component is not controlled. */
|
|
37
|
+
defaultOpen?: boolean;
|
|
38
|
+
/** Handler that is called when the panel's open state changes. */
|
|
39
|
+
onOpenChange?: (open: boolean) => void;
|
|
40
|
+
/** Additional CSS-classes. */
|
|
41
|
+
className?: string;
|
|
42
|
+
/** Inline styles. */
|
|
43
|
+
style?: CSSProperties;
|
|
44
|
+
/** The props used for each slot inside. */
|
|
45
|
+
slotProps?: {
|
|
46
|
+
dialog?: DialogProps;
|
|
47
|
+
transition?: Partial<TransitionProps<HTMLElement>>;
|
|
48
|
+
resizer?: ComponentPropsWithRef<'div'> & DataAttributeProps;
|
|
49
|
+
};
|
|
50
|
+
/** If `true`, the content panel won't close when the ESC key is pressed. */
|
|
51
|
+
disableExitOnEscapeKeyDown?: boolean;
|
|
52
|
+
} & Pick<DialogProps, 'hideCloseButton'>;
|
|
53
|
+
export type ContentPanelRef = ComponentRef<'div'>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isNumber } from "@koobiq/react-core";
|
|
2
|
+
function getInlineSize(el) {
|
|
3
|
+
if (!el) return 0;
|
|
4
|
+
const cs = getComputedStyle(el);
|
|
5
|
+
const mis = parseFloat(cs.marginInlineStart) || 0;
|
|
6
|
+
const mie = parseFloat(cs.marginInlineEnd) || 0;
|
|
7
|
+
return mis + mie + el.getBoundingClientRect().width;
|
|
8
|
+
}
|
|
9
|
+
function parseContentPanelSize(containerWidth, value) {
|
|
10
|
+
if (value == null) return null;
|
|
11
|
+
if (isNumber(value)) {
|
|
12
|
+
return Number.isFinite(value) ? value : null;
|
|
13
|
+
}
|
|
14
|
+
const v = value.trim();
|
|
15
|
+
if (v.endsWith("%")) {
|
|
16
|
+
if (containerWidth == null || !Number.isFinite(containerWidth)) return null;
|
|
17
|
+
const n2 = Number(v.slice(0, -1).trim());
|
|
18
|
+
if (!Number.isFinite(n2)) return null;
|
|
19
|
+
return containerWidth * (n2 / 100);
|
|
20
|
+
}
|
|
21
|
+
if (v.toLowerCase().endsWith("px")) {
|
|
22
|
+
const n2 = Number(v.slice(0, -2).trim());
|
|
23
|
+
return Number.isFinite(n2) ? n2 : null;
|
|
24
|
+
}
|
|
25
|
+
const n = Number(v);
|
|
26
|
+
return Number.isFinite(n) ? n : null;
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
getInlineSize,
|
|
30
|
+
parseContentPanelSize
|
|
31
|
+
};
|
|
@@ -114,8 +114,8 @@ function DateInputRender(props, ref) {
|
|
|
114
114
|
state.segments.map((segment, i) => /* @__PURE__ */ jsx(DateSegment, { segment, state }, i)),
|
|
115
115
|
/* @__PURE__ */ jsx("input", { ...inputProps })
|
|
116
116
|
] }) }),
|
|
117
|
-
/* @__PURE__ */ jsx(FormField.
|
|
118
|
-
/* @__PURE__ */ jsx(
|
|
117
|
+
/* @__PURE__ */ jsx(FieldErrorContext.Provider, { value: validation, children: /* @__PURE__ */ jsx(FormField.Error, { ...errorProps }) }),
|
|
118
|
+
/* @__PURE__ */ jsx(FormField.Caption, { ...captionProps })
|
|
119
119
|
] })
|
|
120
120
|
] });
|
|
121
121
|
}
|
|
@@ -42,7 +42,6 @@ function DatePickerRender(props, ref) {
|
|
|
42
42
|
const {
|
|
43
43
|
isInvalid,
|
|
44
44
|
groupProps,
|
|
45
|
-
labelProps,
|
|
46
45
|
fieldProps,
|
|
47
46
|
buttonProps,
|
|
48
47
|
dialogProps,
|
|
@@ -57,6 +56,25 @@ function DatePickerRender(props, ref) {
|
|
|
57
56
|
state,
|
|
58
57
|
anchorRef
|
|
59
58
|
);
|
|
59
|
+
const { slotProps: rootSlotProps, ...otherRoot } = slotProps?.root || {};
|
|
60
|
+
const mergedRootSlotProps = {
|
|
61
|
+
...rootSlotProps,
|
|
62
|
+
group: mergeProps(rootSlotProps?.group, groupProps, {
|
|
63
|
+
ref: anchorRef,
|
|
64
|
+
endAddon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
65
|
+
endAddon,
|
|
66
|
+
/* @__PURE__ */ jsx(
|
|
67
|
+
IconButton,
|
|
68
|
+
{
|
|
69
|
+
variant: isInvalid ? "error" : "fade-contrast",
|
|
70
|
+
className: s.calendar,
|
|
71
|
+
...buttonProps,
|
|
72
|
+
children: /* @__PURE__ */ jsx(IconCalendarO16, {})
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
] })
|
|
76
|
+
})
|
|
77
|
+
};
|
|
60
78
|
const rootProps = mergeProps(
|
|
61
79
|
{
|
|
62
80
|
ref,
|
|
@@ -70,27 +88,9 @@ function DatePickerRender(props, ref) {
|
|
|
70
88
|
labelAlign,
|
|
71
89
|
errorMessage,
|
|
72
90
|
"data-testid": testId,
|
|
73
|
-
slotProps:
|
|
74
|
-
label: mergeProps(labelProps, slotProps?.label),
|
|
75
|
-
group: {
|
|
76
|
-
endAddon: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
77
|
-
endAddon,
|
|
78
|
-
/* @__PURE__ */ jsx(
|
|
79
|
-
IconButton,
|
|
80
|
-
{
|
|
81
|
-
variant: isInvalid ? "error" : "fade-contrast",
|
|
82
|
-
className: s.calendar,
|
|
83
|
-
...buttonProps,
|
|
84
|
-
children: /* @__PURE__ */ jsx(IconCalendarO16, {})
|
|
85
|
-
}
|
|
86
|
-
)
|
|
87
|
-
] }),
|
|
88
|
-
...groupProps,
|
|
89
|
-
ref: anchorRef
|
|
90
|
-
}
|
|
91
|
-
}
|
|
91
|
+
slotProps: mergedRootSlotProps
|
|
92
92
|
},
|
|
93
|
-
|
|
93
|
+
otherRoot,
|
|
94
94
|
fieldProps
|
|
95
95
|
);
|
|
96
96
|
const popoverProps = mergeProps(
|
|
@@ -21,5 +21,5 @@ export type DialogBaseProps = {
|
|
|
21
21
|
'close-button'?: DialogCloseButtonProps;
|
|
22
22
|
};
|
|
23
23
|
} & AriaDialogProps;
|
|
24
|
-
export type DialogProps = ExtendableComponentPropsWithRef<DialogBaseProps, 'section'>;
|
|
24
|
+
export type DialogProps = ExtendableComponentPropsWithRef<DialogBaseProps & DataAttributeProps, 'section'>;
|
|
25
25
|
export type DialogRef = ComponentRef<'section'>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type ReactNode, type Ref } from 'react';
|
|
2
|
-
|
|
2
|
+
import { type ExtendableComponentPropsWithRef } from '@koobiq/react-core';
|
|
3
|
+
export type FormFieldInputDateProps = ExtendableComponentPropsWithRef<{
|
|
3
4
|
className?: string;
|
|
4
5
|
children?: ReactNode;
|
|
5
6
|
'data-testid'?: string;
|
|
6
7
|
ref?: Ref<HTMLDivElement>;
|
|
7
|
-
}
|
|
8
|
+
}, 'div'>;
|
|
8
9
|
export declare const FormFieldInputDate: import("react").ForwardRefExoticComponent<Omit<FormFieldInputDateProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -132,8 +132,8 @@ const Input = forwardRef((props, ref) => {
|
|
|
132
132
|
/* @__PURE__ */ jsx(FormField.Label, { ...labelProps }),
|
|
133
133
|
/* @__PURE__ */ jsxs("div", { className: s.body, children: [
|
|
134
134
|
/* @__PURE__ */ jsx(FormField.ControlGroup, { ...groupProps, children: /* @__PURE__ */ jsx(FormField.Input, { ...inputProps }) }),
|
|
135
|
-
/* @__PURE__ */ jsx(FormField.
|
|
136
|
-
/* @__PURE__ */ jsx(FormField.
|
|
135
|
+
/* @__PURE__ */ jsx(FormField.Error, { ...errorProps }),
|
|
136
|
+
/* @__PURE__ */ jsx(FormField.Caption, { ...captionProps })
|
|
137
137
|
] })
|
|
138
138
|
] });
|
|
139
139
|
} });
|
|
@@ -117,8 +117,8 @@ const InputNumber = forwardRef(
|
|
|
117
117
|
/* @__PURE__ */ jsx(FormField.Label, { ...labelProps }),
|
|
118
118
|
/* @__PURE__ */ jsxs("div", { className: s.body, children: [
|
|
119
119
|
/* @__PURE__ */ jsx(FormField.ControlGroup, { ...groupProps, children: /* @__PURE__ */ jsx(FormField.Input, { ...inputProps }) }),
|
|
120
|
-
/* @__PURE__ */ jsx(FormField.
|
|
121
|
-
/* @__PURE__ */ jsx(FormField.
|
|
120
|
+
/* @__PURE__ */ jsx(FormField.Error, { ...errorProps }),
|
|
121
|
+
/* @__PURE__ */ jsx(FormField.Caption, { ...captionProps })
|
|
122
122
|
] })
|
|
123
123
|
] });
|
|
124
124
|
} });
|
|
@@ -39,13 +39,11 @@ const Link = polymorphicForwardRef((props, ref) => {
|
|
|
39
39
|
'Link: the "disabled" prop is deprecated. Use "isDisabled" prop to replace it.'
|
|
40
40
|
);
|
|
41
41
|
}
|
|
42
|
-
const elementType = as !== "a" && as !== "button" ? `${as}` : void 0;
|
|
43
42
|
return /* @__PURE__ */ jsxs(
|
|
44
43
|
Link$1,
|
|
45
44
|
{
|
|
46
45
|
as,
|
|
47
46
|
isDisabled,
|
|
48
|
-
elementType,
|
|
49
47
|
...isDisabled && { tabIndex: -1 },
|
|
50
48
|
className: ({ isHovered, isPressed, isFocusVisible }) => clsx(
|
|
51
49
|
s.base,
|
|
@@ -17,6 +17,11 @@ function MenuItem({ item, state }) {
|
|
|
17
17
|
const { hoverProps, isHovered: hovered } = useHover({ isDisabled: disabled });
|
|
18
18
|
const { isPressed: pressed, pressProps } = usePress({ isDisabled: disabled });
|
|
19
19
|
const Tag = item.props.href ? "a" : "li";
|
|
20
|
+
const {
|
|
21
|
+
style,
|
|
22
|
+
className,
|
|
23
|
+
"data-testid": dataTestId
|
|
24
|
+
} = item.props;
|
|
20
25
|
return /* @__PURE__ */ jsx(
|
|
21
26
|
Tag,
|
|
22
27
|
{
|
|
@@ -25,7 +30,9 @@ function MenuItem({ item, state }) {
|
|
|
25
30
|
"data-pressed": pressed,
|
|
26
31
|
"data-selected": selected,
|
|
27
32
|
"data-focus-visible": focusVisible,
|
|
28
|
-
|
|
33
|
+
style,
|
|
34
|
+
"data-testid": dataTestId,
|
|
35
|
+
className: clsx(listItem, textVariant["text-normal"], className),
|
|
29
36
|
ref,
|
|
30
37
|
children: item.rendered
|
|
31
38
|
}
|
|
@@ -114,8 +114,8 @@ const RadioGroup = forwardRef(
|
|
|
114
114
|
/* @__PURE__ */ jsx(FormField.Label, { ...labelProps }),
|
|
115
115
|
/* @__PURE__ */ jsxs("div", { className: s.body, children: [
|
|
116
116
|
/* @__PURE__ */ jsx("div", { ...radioGroupProps, children }),
|
|
117
|
-
/* @__PURE__ */ jsx(FormField.
|
|
118
|
-
/* @__PURE__ */ jsx(FormField.
|
|
117
|
+
/* @__PURE__ */ jsx(FormField.Error, { ...errorProps }),
|
|
118
|
+
/* @__PURE__ */ jsx(FormField.Caption, { ...captionProps })
|
|
119
119
|
] })
|
|
120
120
|
] });
|
|
121
121
|
} }) });
|