@koobiq/react-components 0.0.1-beta.17 → 0.0.1-beta.19
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/ButtonToggleGroup/ButtonToggleGroup.d.ts +2 -0
- package/dist/components/ButtonToggleGroup/ButtonToggleGroup.js +130 -0
- package/dist/components/ButtonToggleGroup/ButtonToggleGroup.module.css.js +17 -0
- package/dist/components/ButtonToggleGroup/ButtonToggleGroupContext.d.ts +7 -0
- package/dist/components/ButtonToggleGroup/ButtonToggleGroupContext.js +12 -0
- package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.d.ts +2 -0
- package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.js +90 -0
- package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.module.css.js +32 -0
- package/dist/components/ButtonToggleGroup/components/ButtonToggle/index.d.ts +2 -0
- package/dist/components/ButtonToggleGroup/components/ButtonToggle/types.d.ts +27 -0
- package/dist/components/ButtonToggleGroup/components/index.d.ts +1 -0
- package/dist/components/ButtonToggleGroup/index.d.ts +3 -0
- package/dist/components/ButtonToggleGroup/reducer.d.ts +23 -0
- package/dist/components/ButtonToggleGroup/reducer.js +25 -0
- package/dist/components/ButtonToggleGroup/types.d.ts +38 -0
- package/dist/components/ButtonToggleGroup/utils.d.ts +3 -0
- package/dist/components/ButtonToggleGroup/utils.js +19 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/style.css +144 -4
- package/package.json +5 -5
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef, useRef, useReducer, useEffect } from "react";
|
|
4
|
+
import { once } from "@koobiq/logger";
|
|
5
|
+
import { useDOMRef, mergeProps, clsx } from "@koobiq/react-core";
|
|
6
|
+
import { useToggleGroupState, useToggleButtonGroup } from "@koobiq/react-primitives";
|
|
7
|
+
import { Transition } from "react-transition-group";
|
|
8
|
+
import s from "./ButtonToggleGroup.module.css.js";
|
|
9
|
+
import { ButtonToggleGroupContext } from "./ButtonToggleGroupContext.js";
|
|
10
|
+
import { animationReducer, initialAnimationState } from "./reducer.js";
|
|
11
|
+
import { getSelectedToggleButton, getToggleButtonStyle } from "./utils.js";
|
|
12
|
+
const MAX_ITEMS = 5;
|
|
13
|
+
const ButtonToggleGroup = forwardRef((props, ref) => {
|
|
14
|
+
const {
|
|
15
|
+
isBlock = false,
|
|
16
|
+
isDisabled = false,
|
|
17
|
+
hasEqualItemSize = false,
|
|
18
|
+
style,
|
|
19
|
+
className,
|
|
20
|
+
slotProps,
|
|
21
|
+
defaultSelectedKey,
|
|
22
|
+
children,
|
|
23
|
+
selectedKey: selectedKeyProp,
|
|
24
|
+
onSelectionChange: onSelectionChangeProp,
|
|
25
|
+
...other
|
|
26
|
+
} = props;
|
|
27
|
+
if (process.env.NODE_ENV !== "production" && children?.length && children?.length > MAX_ITEMS) {
|
|
28
|
+
once.warn(
|
|
29
|
+
`Use a ButtonToggleGroup to allow selection of up to ${MAX_ITEMS} options.`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const domRef = useDOMRef(ref);
|
|
33
|
+
const thumbRef = useRef(null);
|
|
34
|
+
const state = useToggleGroupState({
|
|
35
|
+
...other,
|
|
36
|
+
isDisabled,
|
|
37
|
+
disallowEmptySelection: true,
|
|
38
|
+
onSelectionChange: (keys) => {
|
|
39
|
+
onSelectionChangeProp?.(Array.from(keys)[0]);
|
|
40
|
+
},
|
|
41
|
+
defaultSelectedKeys: defaultSelectedKey ? [defaultSelectedKey] : [],
|
|
42
|
+
...!defaultSelectedKey && {
|
|
43
|
+
selectedKeys: selectedKeyProp ? [selectedKeyProp] : []
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const { groupProps: groupPropsAria } = useToggleButtonGroup(
|
|
47
|
+
{},
|
|
48
|
+
state,
|
|
49
|
+
domRef
|
|
50
|
+
);
|
|
51
|
+
const previous = useRef(null);
|
|
52
|
+
const selectedKey = Array.from(state.selectedKeys)[0];
|
|
53
|
+
const [animatedState, dispatch] = useReducer(
|
|
54
|
+
animationReducer,
|
|
55
|
+
initialAnimationState
|
|
56
|
+
);
|
|
57
|
+
const { isAnimated, start, end, savedKey } = animatedState;
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const active = getSelectedToggleButton(domRef.current);
|
|
60
|
+
if (active && previous.current) {
|
|
61
|
+
dispatch({
|
|
62
|
+
type: "SET_ANIMATED",
|
|
63
|
+
payload: {
|
|
64
|
+
start: [previous.current.offsetLeft, previous.current.offsetWidth],
|
|
65
|
+
end: [active.offsetLeft, active.offsetWidth]
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
} else {
|
|
69
|
+
dispatch({ type: "SET_SAVED", payload: { savedKey: selectedKey } });
|
|
70
|
+
}
|
|
71
|
+
previous.current = active;
|
|
72
|
+
}, [selectedKey]);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (!selectedKey) dispatch({ type: "RESET" });
|
|
75
|
+
}, [selectedKey]);
|
|
76
|
+
const groupProps = mergeProps(
|
|
77
|
+
{
|
|
78
|
+
className: clsx(
|
|
79
|
+
s.base,
|
|
80
|
+
isBlock && s.block,
|
|
81
|
+
hasEqualItemSize && s.hasEqualItemSize,
|
|
82
|
+
className
|
|
83
|
+
),
|
|
84
|
+
"data-block": isBlock,
|
|
85
|
+
"data-animated": isAnimated,
|
|
86
|
+
"data-equal-item-size": hasEqualItemSize,
|
|
87
|
+
ref: domRef,
|
|
88
|
+
style
|
|
89
|
+
},
|
|
90
|
+
other,
|
|
91
|
+
groupPropsAria
|
|
92
|
+
);
|
|
93
|
+
const thumbProps = mergeProps(
|
|
94
|
+
{
|
|
95
|
+
ref: thumbRef,
|
|
96
|
+
className: clsx(s.thumb),
|
|
97
|
+
style: getToggleButtonStyle(start, end)
|
|
98
|
+
},
|
|
99
|
+
slotProps?.thumb
|
|
100
|
+
);
|
|
101
|
+
const containerProps = mergeProps(
|
|
102
|
+
{
|
|
103
|
+
className: clsx(s.container)
|
|
104
|
+
},
|
|
105
|
+
slotProps?.container
|
|
106
|
+
);
|
|
107
|
+
return /* @__PURE__ */ jsx(ButtonToggleGroupContext.Provider, { value: { state, savedKey }, children: /* @__PURE__ */ jsxs("div", { ...groupProps, children: [
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
Transition,
|
|
110
|
+
{
|
|
111
|
+
in: isAnimated,
|
|
112
|
+
timeout: 200,
|
|
113
|
+
nodeRef: thumbRef,
|
|
114
|
+
exit: false,
|
|
115
|
+
onEntered: () => {
|
|
116
|
+
dispatch({ type: "SET_SAVED", payload: { savedKey: selectedKey } });
|
|
117
|
+
},
|
|
118
|
+
mountOnEnter: true,
|
|
119
|
+
unmountOnExit: true,
|
|
120
|
+
enter: true,
|
|
121
|
+
children: (transitionState) => /* @__PURE__ */ jsx("div", { ...thumbProps, "data-transition": transitionState })
|
|
122
|
+
}
|
|
123
|
+
),
|
|
124
|
+
/* @__PURE__ */ jsx("div", { ...containerProps, children })
|
|
125
|
+
] }) });
|
|
126
|
+
});
|
|
127
|
+
ButtonToggleGroup.displayName = "ButtonToggleGroup";
|
|
128
|
+
export {
|
|
129
|
+
ButtonToggleGroup
|
|
130
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const base = "kbq-buttontogglegroup-79a88d";
|
|
2
|
+
const block = "kbq-buttontogglegroup-block-f9494f";
|
|
3
|
+
const thumb = "kbq-buttontogglegroup-thumb-7ff4ae";
|
|
4
|
+
const container = "kbq-buttontogglegroup-container-e48aaf";
|
|
5
|
+
const s = {
|
|
6
|
+
base,
|
|
7
|
+
block,
|
|
8
|
+
thumb,
|
|
9
|
+
container
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
base,
|
|
13
|
+
block,
|
|
14
|
+
container,
|
|
15
|
+
s as default,
|
|
16
|
+
thumb
|
|
17
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ToggleGroupState } from '@koobiq/react-primitives';
|
|
2
|
+
export type ButtonToggleGroupContextProps = {
|
|
3
|
+
state: ToggleGroupState | null;
|
|
4
|
+
savedKey?: string | number;
|
|
5
|
+
};
|
|
6
|
+
export declare const ButtonToggleGroupContext: import("react").Context<ButtonToggleGroupContextProps>;
|
|
7
|
+
export declare function useButtonToggleGroupContext(): ButtonToggleGroupContextProps;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
const ButtonToggleGroupContext = createContext({
|
|
4
|
+
state: null
|
|
5
|
+
});
|
|
6
|
+
function useButtonToggleGroupContext() {
|
|
7
|
+
return useContext(ButtonToggleGroupContext);
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
ButtonToggleGroupContext,
|
|
11
|
+
useButtonToggleGroupContext
|
|
12
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef, useRef } from "react";
|
|
4
|
+
import { useDOMRef, useElementSize, useHover, useFocusRing, mergeProps, useMultiRef, clsx, isNotNil } from "@koobiq/react-core";
|
|
5
|
+
import { useToggleButtonGroupItem } from "@koobiq/react-primitives";
|
|
6
|
+
import { utilClasses } from "../../../../styles/utility.js";
|
|
7
|
+
import { useButtonToggleGroupContext } from "../../ButtonToggleGroupContext.js";
|
|
8
|
+
import s from "./ButtonToggle.module.css.js";
|
|
9
|
+
import { Tooltip } from "../../../Tooltip/Tooltip.js";
|
|
10
|
+
const textNormalMedium = utilClasses.typography["text-normal-medium"];
|
|
11
|
+
const ButtonToggle = forwardRef(
|
|
12
|
+
(props, ref) => {
|
|
13
|
+
const {
|
|
14
|
+
isDisabled: isDisabledProp = false,
|
|
15
|
+
children,
|
|
16
|
+
id,
|
|
17
|
+
icon,
|
|
18
|
+
className,
|
|
19
|
+
slotProps,
|
|
20
|
+
...other
|
|
21
|
+
} = props;
|
|
22
|
+
const domRef = useDOMRef(ref);
|
|
23
|
+
const contentRef = useRef(null);
|
|
24
|
+
const { state, savedKey } = useButtonToggleGroupContext();
|
|
25
|
+
const { ref: containerRef } = useElementSize();
|
|
26
|
+
const showTooltip = (contentRef.current?.scrollWidth || 0) > (contentRef.current?.clientWidth || 0);
|
|
27
|
+
const { buttonProps, isPressed, isSelected, isDisabled } = useToggleButtonGroupItem(
|
|
28
|
+
{ id, isDisabled: isDisabledProp },
|
|
29
|
+
state,
|
|
30
|
+
domRef
|
|
31
|
+
);
|
|
32
|
+
const { hoverProps, isHovered } = useHover({ ...props, isDisabled });
|
|
33
|
+
const { focusProps, isFocusVisible } = useFocusRing({});
|
|
34
|
+
const iconProps = mergeProps({ className: s.icon }, slotProps?.icon);
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
Tooltip,
|
|
37
|
+
{
|
|
38
|
+
delay: 300,
|
|
39
|
+
anchorRef: domRef,
|
|
40
|
+
disabled: !showTooltip,
|
|
41
|
+
...slotProps?.tooltip,
|
|
42
|
+
control: ({ ref: controlRef, ...controlProps }) => {
|
|
43
|
+
const rootRef = useMultiRef([domRef, controlRef]);
|
|
44
|
+
const rootProps = mergeProps(
|
|
45
|
+
{
|
|
46
|
+
className: clsx(
|
|
47
|
+
s.base,
|
|
48
|
+
textNormalMedium,
|
|
49
|
+
isHovered && s.hovered,
|
|
50
|
+
isPressed && s.pressed,
|
|
51
|
+
savedKey === id && s.selected,
|
|
52
|
+
isDisabled && s.disabled,
|
|
53
|
+
isFocusVisible && s.focusVisible,
|
|
54
|
+
className
|
|
55
|
+
),
|
|
56
|
+
"data-hovered": isHovered,
|
|
57
|
+
"data-pressed": isPressed,
|
|
58
|
+
"data-selected": isSelected,
|
|
59
|
+
"data-disabled": isDisabled,
|
|
60
|
+
"data-focus-visible": isFocusVisible,
|
|
61
|
+
ref: rootRef
|
|
62
|
+
},
|
|
63
|
+
controlProps,
|
|
64
|
+
focusProps,
|
|
65
|
+
hoverProps,
|
|
66
|
+
buttonProps,
|
|
67
|
+
other
|
|
68
|
+
);
|
|
69
|
+
const containerProps = mergeProps(
|
|
70
|
+
{ className: s.container, ref: containerRef },
|
|
71
|
+
slotProps?.container
|
|
72
|
+
);
|
|
73
|
+
const contentProps = mergeProps(
|
|
74
|
+
{ className: s.content, ref: contentRef },
|
|
75
|
+
slotProps?.content
|
|
76
|
+
);
|
|
77
|
+
return /* @__PURE__ */ jsx("button", { ...rootProps, children: /* @__PURE__ */ jsxs("span", { ...containerProps, children: [
|
|
78
|
+
isNotNil(icon) && /* @__PURE__ */ jsx("span", { ...iconProps, children: icon }),
|
|
79
|
+
isNotNil(children) && /* @__PURE__ */ jsx("span", { ...contentProps, children })
|
|
80
|
+
] }) });
|
|
81
|
+
},
|
|
82
|
+
children
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
ButtonToggle.displayName = "ButtonToggle";
|
|
88
|
+
export {
|
|
89
|
+
ButtonToggle
|
|
90
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
const base = "kbq-buttontoggle-caa007";
|
|
2
|
+
const hovered = "kbq-buttontoggle-hovered-4706db";
|
|
3
|
+
const pressed = "kbq-buttontoggle-pressed-6d5049";
|
|
4
|
+
const selected = "kbq-buttontoggle-selected-3e6996";
|
|
5
|
+
const disabled = "kbq-buttontoggle-disabled-c0d011";
|
|
6
|
+
const focusVisible = "kbq-buttontoggle-focusVisible-37d5be";
|
|
7
|
+
const container = "kbq-buttontoggle-container-f496bf";
|
|
8
|
+
const icon = "kbq-buttontoggle-icon-668db0";
|
|
9
|
+
const content = "kbq-buttontoggle-content-822c7d";
|
|
10
|
+
const s = {
|
|
11
|
+
base,
|
|
12
|
+
hovered,
|
|
13
|
+
pressed,
|
|
14
|
+
selected,
|
|
15
|
+
disabled,
|
|
16
|
+
focusVisible,
|
|
17
|
+
container,
|
|
18
|
+
icon,
|
|
19
|
+
content
|
|
20
|
+
};
|
|
21
|
+
export {
|
|
22
|
+
base,
|
|
23
|
+
container,
|
|
24
|
+
content,
|
|
25
|
+
s as default,
|
|
26
|
+
disabled,
|
|
27
|
+
focusVisible,
|
|
28
|
+
hovered,
|
|
29
|
+
icon,
|
|
30
|
+
pressed,
|
|
31
|
+
selected
|
|
32
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ComponentRef, ReactNode } from 'react';
|
|
2
|
+
import type { DataAttributeProps, ExtendableComponentPropsWithRef } from '@koobiq/react-core';
|
|
3
|
+
import type { TooltipProps } from '../../../Tooltip';
|
|
4
|
+
export type ButtonToggleKey = string | number;
|
|
5
|
+
export type ButtonToggleProps = ExtendableComponentPropsWithRef<{
|
|
6
|
+
/** An identifier for the item in the selectedKey of a ButtonToggleGroup. */
|
|
7
|
+
id: ButtonToggleKey;
|
|
8
|
+
/** Icon placed before the children. */
|
|
9
|
+
icon?: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* If `true`, the component is disabled.
|
|
12
|
+
* @default false
|
|
13
|
+
* */
|
|
14
|
+
isDisabled?: boolean;
|
|
15
|
+
/** Additional CSS-classes. */
|
|
16
|
+
className?: string;
|
|
17
|
+
/** The props used for each slot inside. */
|
|
18
|
+
slotProps?: {
|
|
19
|
+
tooltip?: TooltipProps;
|
|
20
|
+
icon?: ComponentPropsWithRef<'span'> & DataAttributeProps;
|
|
21
|
+
content?: ComponentPropsWithRef<'span'> & DataAttributeProps;
|
|
22
|
+
container?: ComponentPropsWithRef<'span'> & DataAttributeProps;
|
|
23
|
+
};
|
|
24
|
+
/** Unique identifier for testing purposes. */
|
|
25
|
+
'data-testid'?: string | number;
|
|
26
|
+
}, 'div'>;
|
|
27
|
+
export type ButtonToggleRef = ComponentRef<'button'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ButtonToggle';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type AnimationStateType = {
|
|
2
|
+
isAnimated?: boolean;
|
|
3
|
+
start?: [number, number];
|
|
4
|
+
end?: [number, number];
|
|
5
|
+
savedKey?: string | number;
|
|
6
|
+
};
|
|
7
|
+
type AnimationAction = {
|
|
8
|
+
type: 'SET_ANIMATED';
|
|
9
|
+
payload: {
|
|
10
|
+
start: [number, number];
|
|
11
|
+
end: [number, number];
|
|
12
|
+
};
|
|
13
|
+
} | {
|
|
14
|
+
type: 'SET_SAVED';
|
|
15
|
+
payload: {
|
|
16
|
+
savedKey?: string | number;
|
|
17
|
+
};
|
|
18
|
+
} | {
|
|
19
|
+
type: 'RESET';
|
|
20
|
+
};
|
|
21
|
+
export declare const initialAnimationState: AnimationStateType;
|
|
22
|
+
export declare function animationReducer(state: AnimationStateType, action: AnimationAction): AnimationStateType;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
const initialAnimationState = {};
|
|
3
|
+
function animationReducer(state, action) {
|
|
4
|
+
switch (action.type) {
|
|
5
|
+
case "SET_ANIMATED":
|
|
6
|
+
return {
|
|
7
|
+
isAnimated: true,
|
|
8
|
+
start: action.payload.start,
|
|
9
|
+
end: action.payload.end
|
|
10
|
+
};
|
|
11
|
+
case "SET_SAVED":
|
|
12
|
+
return {
|
|
13
|
+
isAnimated: false,
|
|
14
|
+
savedKey: action.payload.savedKey
|
|
15
|
+
};
|
|
16
|
+
case "RESET":
|
|
17
|
+
return {};
|
|
18
|
+
default:
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
animationReducer,
|
|
24
|
+
initialAnimationState
|
|
25
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ComponentPropsWithRef, ComponentRef, ReactElement } from 'react';
|
|
2
|
+
import type { DataAttributeProps, ExtendableComponentPropsWithRef } from '@koobiq/react-core';
|
|
3
|
+
import type { ButtonToggleProps } from './components';
|
|
4
|
+
export type ButtonToggleGroupKey = string | number;
|
|
5
|
+
export type ButtonToggleGroupBaseProps = {
|
|
6
|
+
/**
|
|
7
|
+
* Whether all items are disabled.
|
|
8
|
+
* @default false
|
|
9
|
+
* */
|
|
10
|
+
isDisabled?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* If `true`, the button will take up the full width of its container.
|
|
13
|
+
* @default false
|
|
14
|
+
* */
|
|
15
|
+
isBlock?: boolean;
|
|
16
|
+
/** The contents of the collection. */
|
|
17
|
+
children?: Array<ReactElement<ButtonToggleProps>>;
|
|
18
|
+
/**
|
|
19
|
+
* If `true`, each item's width will be equal.
|
|
20
|
+
* @default false
|
|
21
|
+
* */
|
|
22
|
+
hasEqualItemSize?: boolean;
|
|
23
|
+
/** The currently selected key in the collection (controlled). */
|
|
24
|
+
selectedKey?: ButtonToggleGroupKey;
|
|
25
|
+
/** The initial selected key in the collection (uncontrolled). */
|
|
26
|
+
defaultSelectedKey?: ButtonToggleGroupKey;
|
|
27
|
+
/** Handler that is called when the selection changes. */
|
|
28
|
+
onSelectionChange?: (keys: ButtonToggleGroupKey) => void;
|
|
29
|
+
/** Unique identifier for testing purposes. */
|
|
30
|
+
'data-testid'?: string | number;
|
|
31
|
+
/** The props used for each slot inside. */
|
|
32
|
+
slotProps?: {
|
|
33
|
+
thumb?: ComponentPropsWithRef<'div'> & DataAttributeProps;
|
|
34
|
+
container?: ComponentPropsWithRef<'div'> & DataAttributeProps;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export type ButtonToggleGroupProps = ExtendableComponentPropsWithRef<ButtonToggleGroupBaseProps, 'div'>;
|
|
38
|
+
export type ButtonToggleGroupRef = ComponentRef<'div'>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function getToggleButtonStyle(start = [0, 0], end = [0, 0]) {
|
|
2
|
+
const [startX, startSize] = start;
|
|
3
|
+
const [endX, endSize] = end;
|
|
4
|
+
return {
|
|
5
|
+
"--thumb-inline-size-start": `${startSize}px`,
|
|
6
|
+
"--thumb-inline-size-end": `${endSize}px`,
|
|
7
|
+
"--thumb-transform-start": `translateX(${startX}px)`,
|
|
8
|
+
"--thumb-transform-end": `translateX(${endX}px)`
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function getSelectedToggleButton(root) {
|
|
12
|
+
return root ? root.querySelector(
|
|
13
|
+
'[role="radio"][data-selected="true"] > span'
|
|
14
|
+
) : null;
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
getSelectedToggleButton,
|
|
18
|
+
getToggleButtonStyle
|
|
19
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -65,6 +65,8 @@ import { Divider } from "./components/Divider/Divider.js";
|
|
|
65
65
|
import { dividerPropDisplay, dividerPropOrientation } from "./components/Divider/types.js";
|
|
66
66
|
import { Menu } from "./components/Menu/Menu.js";
|
|
67
67
|
import { menuPropSelectionMode } from "./components/Menu/types.js";
|
|
68
|
+
import { ButtonToggleGroup } from "./components/ButtonToggleGroup/ButtonToggleGroup.js";
|
|
69
|
+
import { ButtonToggle } from "./components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.js";
|
|
68
70
|
import { flex, flexPropAlignItems, flexPropDirection, flexPropFlex, flexPropGap, flexPropJustifyContent, flexPropOrder, flexPropWrap } from "./components/layout/flex/flex.js";
|
|
69
71
|
import { spacing, spacingGap } from "./components/layout/spacing/spacing.js";
|
|
70
72
|
export {
|
|
@@ -74,6 +76,8 @@ export {
|
|
|
74
76
|
BreakpointsContext,
|
|
75
77
|
BreakpointsProvider,
|
|
76
78
|
Button,
|
|
79
|
+
ButtonToggle,
|
|
80
|
+
ButtonToggleGroup,
|
|
77
81
|
Checkbox,
|
|
78
82
|
Container,
|
|
79
83
|
Divider,
|
package/dist/style.css
CHANGED
|
@@ -1450,16 +1450,13 @@
|
|
|
1450
1450
|
background-color: var(--checkbox-bg-color);
|
|
1451
1451
|
outline-offset: calc(-1 * var(--checkbox-outline-width) / 2);
|
|
1452
1452
|
outline: var(--checkbox-outline-width) solid var(--checkbox-outline-color);
|
|
1453
|
+
flex-shrink: 0;
|
|
1453
1454
|
justify-content: center;
|
|
1454
1455
|
align-items: center;
|
|
1455
1456
|
display: flex;
|
|
1456
1457
|
position: relative;
|
|
1457
1458
|
}
|
|
1458
1459
|
|
|
1459
|
-
.kbq-checkbox-checkbox-dbb3d9 > * {
|
|
1460
|
-
flex-shrink: 0;
|
|
1461
|
-
}
|
|
1462
|
-
|
|
1463
1460
|
.kbq-checkbox-normal-646719 {
|
|
1464
1461
|
--checkbox-size: var(--kbq-size-l);
|
|
1465
1462
|
--checkbox-margin-block: var(--kbq-size-3xs);
|
|
@@ -2204,6 +2201,7 @@
|
|
|
2204
2201
|
transition: background-color var(--kbq-transition-default), border var(--kbq-transition-default), outline-color var(--kbq-transition-default);
|
|
2205
2202
|
outline-offset: calc(-1 * var(--radio-outline-width) / 2);
|
|
2206
2203
|
outline: var(--radio-outline-width) solid var(--radio-outline-color);
|
|
2204
|
+
flex-shrink: 0;
|
|
2207
2205
|
justify-content: center;
|
|
2208
2206
|
align-items: center;
|
|
2209
2207
|
display: flex;
|
|
@@ -2346,6 +2344,7 @@
|
|
|
2346
2344
|
border-radius: var(--toggle-track-border-radius);
|
|
2347
2345
|
outline: 2px solid var(--toggle-track-outline-color);
|
|
2348
2346
|
transition: background-color var(--kbq-transition-default), outline-color var(--kbq-transition-default);
|
|
2347
|
+
flex-shrink: 0;
|
|
2349
2348
|
position: relative;
|
|
2350
2349
|
}
|
|
2351
2350
|
|
|
@@ -2691,6 +2690,7 @@
|
|
|
2691
2690
|
min-block-size: 48px;
|
|
2692
2691
|
display: flex;
|
|
2693
2692
|
position: relative;
|
|
2693
|
+
overflow: hidden;
|
|
2694
2694
|
}
|
|
2695
2695
|
|
|
2696
2696
|
.kbq-dialog-container-a08202 {
|
|
@@ -3193,6 +3193,146 @@
|
|
|
3193
3193
|
box-sizing: border-box;
|
|
3194
3194
|
padding: var(--kbq-size-s) var(--kbq-size-m);
|
|
3195
3195
|
}
|
|
3196
|
+
.kbq-buttontogglegroup-79a88d {
|
|
3197
|
+
--thumb-inline-size-start: ;
|
|
3198
|
+
--thumb-transform-start: ;
|
|
3199
|
+
--thumb-inline-size-end: ;
|
|
3200
|
+
--thumb-transform-end: ;
|
|
3201
|
+
border-radius: var(--kbq-size-s);
|
|
3202
|
+
background-color: var(--kbq-background-contrast-fade);
|
|
3203
|
+
flex-wrap: nowrap;
|
|
3204
|
+
display: inline-flex;
|
|
3205
|
+
position: relative;
|
|
3206
|
+
overflow: hidden;
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3209
|
+
.kbq-buttontogglegroup-block-f9494f {
|
|
3210
|
+
inline-size: 100%;
|
|
3211
|
+
}
|
|
3212
|
+
|
|
3213
|
+
.kbq-buttontogglegroup-thumb-7ff4ae {
|
|
3214
|
+
box-sizing: border-box;
|
|
3215
|
+
inset-block: var(--kbq-size-xxs);
|
|
3216
|
+
border-radius: var(--kbq-size-xxs);
|
|
3217
|
+
background-color: var(--kbq-background-card);
|
|
3218
|
+
inline-size: var(--thumb-inline-size-start);
|
|
3219
|
+
transform: var(--thumb-transform-start);
|
|
3220
|
+
transition: inline-size .2s ease-in, transform .2s ease-in;
|
|
3221
|
+
position: absolute;
|
|
3222
|
+
}
|
|
3223
|
+
|
|
3224
|
+
.kbq-buttontogglegroup-thumb-7ff4ae[data-transition="entering"], .kbq-buttontogglegroup-thumb-7ff4ae[data-transition="entered"] {
|
|
3225
|
+
inline-size: var(--thumb-inline-size-end);
|
|
3226
|
+
transform: var(--thumb-transform-end);
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
.kbq-buttontogglegroup-container-e48aaf {
|
|
3230
|
+
inline-size: 100%;
|
|
3231
|
+
display: flex;
|
|
3232
|
+
}
|
|
3233
|
+
[data-animated="true"] .kbq-buttontoggle-caa007 {
|
|
3234
|
+
--button-toggle-bg-color: transparent;
|
|
3235
|
+
}
|
|
3236
|
+
|
|
3237
|
+
[data-equal-item-size="true"] .kbq-buttontoggle-caa007 {
|
|
3238
|
+
flex: 1;
|
|
3239
|
+
}
|
|
3240
|
+
|
|
3241
|
+
.kbq-buttontoggle-caa007 {
|
|
3242
|
+
--button-toggle-block-size: var(--kbq-size-xxl);
|
|
3243
|
+
--button-toggle-outline-width: var(--kbq-size-3xs);
|
|
3244
|
+
--button-toggle-padding-block: var(--kbq-size-xxs);
|
|
3245
|
+
--button-toggle-padding-inline-start: var(--kbq-size-3xs);
|
|
3246
|
+
--button-toggle-padding-inline-end: var(--kbq-size-3xs);
|
|
3247
|
+
--button-toggle-color: var(--kbq-foreground-contrast);
|
|
3248
|
+
--button-toggle-icon-color: var(--kbq-icon-contrast-fade);
|
|
3249
|
+
--button-toggle-bg-color: var(--kbq-background-contrast-fade);
|
|
3250
|
+
--button-toggle-outline-color: transparent;
|
|
3251
|
+
cursor: pointer;
|
|
3252
|
+
min-inline-size: 0;
|
|
3253
|
+
padding-block: var(--button-toggle-padding-block);
|
|
3254
|
+
padding-inline: var(--button-toggle-padding-inline-start) var(--button-toggle-padding-inline-end);
|
|
3255
|
+
block-size: calc(var(--button-toggle-block-size) + 2 * var(--button-toggle-padding-block));
|
|
3256
|
+
background: none;
|
|
3257
|
+
border: none;
|
|
3258
|
+
outline: none;
|
|
3259
|
+
flex: auto;
|
|
3260
|
+
align-items: center;
|
|
3261
|
+
display: inline-flex;
|
|
3262
|
+
}
|
|
3263
|
+
|
|
3264
|
+
.kbq-buttontoggle-caa007:first-child {
|
|
3265
|
+
--button-toggle-padding-inline-start: var(--kbq-size-xxs);
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
.kbq-buttontoggle-caa007:last-child {
|
|
3269
|
+
--button-toggle-padding-inline-end: var(--kbq-size-xxs);
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
.kbq-buttontoggle-hovered-4706db {
|
|
3273
|
+
--button-toggle-bg-color: var(--kbq-states-background-contrast-fade-hover);
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3276
|
+
.kbq-buttontoggle-pressed-6d5049 {
|
|
3277
|
+
--button-toggle-bg-color: var(--kbq-states-background-contrast-fade-active);
|
|
3278
|
+
}
|
|
3279
|
+
|
|
3280
|
+
.kbq-buttontoggle-selected-3e6996 {
|
|
3281
|
+
--button-toggle-bg-color: var(--kbq-background-card);
|
|
3282
|
+
}
|
|
3283
|
+
|
|
3284
|
+
.kbq-buttontoggle-selected-3e6996:where(.kbq-buttontoggle-pressed-6d5049) {
|
|
3285
|
+
--button-toggle-bg-color: var(--kbq-states-background-transparent-active);
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3288
|
+
.kbq-buttontoggle-disabled-c0d011 {
|
|
3289
|
+
--button-toggle-color: var(--kbq-states-foreground-disabled);
|
|
3290
|
+
--button-toggle-icon-color: inherit;
|
|
3291
|
+
cursor: not-allowed;
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
.kbq-buttontoggle-disabled-c0d011:where(.kbq-buttontoggle-selected-3e6996) {
|
|
3295
|
+
--button-toggle-bg-color: var(--kbq-states-background-disabled);
|
|
3296
|
+
}
|
|
3297
|
+
|
|
3298
|
+
.kbq-buttontoggle-focusVisible-37d5be {
|
|
3299
|
+
--button-toggle-outline-color: var(--kbq-states-line-focus-theme);
|
|
3300
|
+
}
|
|
3301
|
+
|
|
3302
|
+
.kbq-buttontoggle-container-f496bf {
|
|
3303
|
+
box-sizing: border-box;
|
|
3304
|
+
outline-offset: -1px;
|
|
3305
|
+
justify-content: center;
|
|
3306
|
+
align-items: center;
|
|
3307
|
+
gap: var(--kbq-size-xxs);
|
|
3308
|
+
inline-size: 100%;
|
|
3309
|
+
padding: 0 var(--kbq-size-xs);
|
|
3310
|
+
color: var(--button-toggle-color);
|
|
3311
|
+
border-radius: var(--kbq-size-xxs);
|
|
3312
|
+
min-inline-size: var(--kbq-size-3xl);
|
|
3313
|
+
block-size: var(--button-toggle-block-size);
|
|
3314
|
+
background-color: var(--button-toggle-bg-color);
|
|
3315
|
+
outline: var(--button-toggle-outline-width) solid;
|
|
3316
|
+
outline-color: var(--button-toggle-outline-color);
|
|
3317
|
+
transition: outline var(--kbq-transition-default);
|
|
3318
|
+
display: inline-flex;
|
|
3319
|
+
position: relative;
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
.kbq-buttontoggle-icon-668db0 {
|
|
3323
|
+
color: var(--button-toggle-icon-color);
|
|
3324
|
+
flex-direction: column;
|
|
3325
|
+
flex-shrink: 0;
|
|
3326
|
+
justify-content: center;
|
|
3327
|
+
align-items: center;
|
|
3328
|
+
display: flex;
|
|
3329
|
+
}
|
|
3330
|
+
|
|
3331
|
+
.kbq-buttontoggle-content-822c7d {
|
|
3332
|
+
white-space: nowrap;
|
|
3333
|
+
text-overflow: ellipsis;
|
|
3334
|
+
overflow: hidden;
|
|
3335
|
+
}
|
|
3196
3336
|
.kbq-spacing-mbs_0-be7021 {
|
|
3197
3337
|
margin-block-start: 0;
|
|
3198
3338
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koobiq/react-components",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.19",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"exports": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"@koobiq/design-tokens": "^3.12.1",
|
|
28
28
|
"@types/react-transition-group": "^4.4.12",
|
|
29
29
|
"react-transition-group": "^4.4.5",
|
|
30
|
-
"@koobiq/logger": "0.0.1-beta.
|
|
31
|
-
"@koobiq/react-core": "0.0.1-beta.
|
|
32
|
-
"@koobiq/react-primitives": "0.0.1-beta.
|
|
33
|
-
"@koobiq/react-icons": "0.0.1-beta.
|
|
30
|
+
"@koobiq/logger": "0.0.1-beta.19",
|
|
31
|
+
"@koobiq/react-core": "0.0.1-beta.19",
|
|
32
|
+
"@koobiq/react-primitives": "0.0.1-beta.19",
|
|
33
|
+
"@koobiq/react-icons": "0.0.1-beta.19"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"@koobiq/design-tokens": "^3.11.2",
|