@koobiq/react-components 0.0.1-beta.2 → 0.0.1-beta.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/components/Alert/Alert.js +2 -2
  2. package/dist/components/Alert/components/AlertIcon/utils.js +1 -1
  3. package/dist/components/Alert/intl.json.js +2 -6
  4. package/dist/components/Alert/types.d.ts +1 -1
  5. package/dist/components/AnimatedIcon/AnimatedIcon.d.ts +4 -0
  6. package/dist/components/AnimatedIcon/AnimatedIcon.js +50 -0
  7. package/dist/components/AnimatedIcon/AnimatedIcon.module.css.js +11 -0
  8. package/dist/components/AnimatedIcon/index.d.ts +2 -0
  9. package/dist/components/AnimatedIcon/types.d.ts +19 -0
  10. package/dist/components/Button/Button.js +1 -1
  11. package/dist/components/Button/Button.module.css.js +2 -2
  12. package/dist/components/Button/types.d.ts +4 -5
  13. package/dist/components/ButtonToggleGroup/ButtonToggleGroup.d.ts +2 -0
  14. package/dist/components/ButtonToggleGroup/ButtonToggleGroup.js +130 -0
  15. package/dist/components/ButtonToggleGroup/ButtonToggleGroup.module.css.js +17 -0
  16. package/dist/components/ButtonToggleGroup/ButtonToggleGroupContext.d.ts +7 -0
  17. package/dist/components/ButtonToggleGroup/ButtonToggleGroupContext.js +12 -0
  18. package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.d.ts +2 -0
  19. package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.js +90 -0
  20. package/dist/components/ButtonToggleGroup/components/ButtonToggle/ButtonToggle.module.css.js +32 -0
  21. package/dist/components/ButtonToggleGroup/components/ButtonToggle/index.d.ts +2 -0
  22. package/dist/components/ButtonToggleGroup/components/ButtonToggle/types.d.ts +27 -0
  23. package/dist/components/ButtonToggleGroup/components/index.d.ts +1 -0
  24. package/dist/components/ButtonToggleGroup/index.d.ts +3 -0
  25. package/dist/components/ButtonToggleGroup/reducer.d.ts +23 -0
  26. package/dist/components/ButtonToggleGroup/reducer.js +25 -0
  27. package/dist/components/ButtonToggleGroup/types.d.ts +38 -0
  28. package/dist/components/ButtonToggleGroup/utils.d.ts +3 -0
  29. package/dist/components/ButtonToggleGroup/utils.js +19 -0
  30. package/dist/components/Checkbox/Checkbox.js +18 -8
  31. package/dist/components/Collections/Divider.d.ts +19 -0
  32. package/dist/components/Collections/Divider.js +14 -0
  33. package/dist/components/Collections/Header.d.ts +20 -0
  34. package/dist/components/Collections/Header.js +16 -0
  35. package/dist/components/Collections/Item.d.ts +14 -0
  36. package/dist/components/Collections/Item.js +10 -0
  37. package/dist/components/{List/ListSection.d.ts → Collections/Section.d.ts} +6 -6
  38. package/dist/components/Collections/Section.js +10 -0
  39. package/dist/components/Collections/index.d.ts +4 -0
  40. package/dist/components/Container/Container.js +2 -1
  41. package/dist/components/Container/utils.d.ts +1 -1
  42. package/dist/components/Dialog/Dialog.d.ts +9 -1
  43. package/dist/components/Dialog/Dialog.js +31 -17
  44. package/dist/components/Dialog/components/DialogBody.d.ts +13 -0
  45. package/dist/components/Dialog/components/{DialogContent.js → DialogBody.js} +9 -8
  46. package/dist/components/Dialog/components/DialogCloseButton.d.ts +14 -1
  47. package/dist/components/Dialog/components/DialogCloseButton.js +3 -6
  48. package/dist/components/Dialog/components/index.d.ts +1 -1
  49. package/dist/components/Dialog/index.d.ts +0 -1
  50. package/dist/components/Dialog/intl.json.js +2 -6
  51. package/dist/components/Divider/Divider.d.ts +4 -0
  52. package/dist/components/Divider/Divider.js +44 -0
  53. package/dist/components/Divider/Divider.module.css.js +29 -0
  54. package/dist/components/Divider/index.d.ts +2 -0
  55. package/dist/components/Divider/types.d.ts +26 -0
  56. package/dist/components/Divider/types.js +6 -0
  57. package/dist/components/FieldComponents/FieldControl/FieldControl.d.ts +1 -1
  58. package/dist/components/FieldComponents/FieldInputGroup/FieldInputGroup.d.ts +8 -2
  59. package/dist/components/FieldComponents/FieldInputGroup/FieldInputGroup.js +32 -30
  60. package/dist/components/FieldComponents/FieldNumberControl/FieldNumberControl.d.ts +1 -1
  61. package/dist/components/FieldComponents/FieldSelect/FieldSelect.d.ts +12 -0
  62. package/dist/components/FieldComponents/FieldSelect/FieldSelect.js +37 -0
  63. package/dist/components/FieldComponents/FieldSelect/FieldSelect.module.css.js +20 -0
  64. package/dist/components/FieldComponents/FieldSelect/index.d.ts +1 -0
  65. package/dist/components/FieldComponents/index.d.ts +1 -0
  66. package/dist/components/FlexBox/FlexBox.d.ts +4 -0
  67. package/dist/components/FlexBox/FlexBox.js +47 -0
  68. package/dist/components/FlexBox/index.d.ts +2 -0
  69. package/dist/components/FlexBox/types.d.ts +27 -0
  70. package/dist/components/Grid/Grid.d.ts +8 -2
  71. package/dist/components/Grid/Grid.js +5 -2
  72. package/dist/components/IconButton/types.d.ts +5 -4
  73. package/dist/components/Input/Input.d.ts +1 -0
  74. package/dist/components/Input/Input.js +11 -11
  75. package/dist/components/Input/types.d.ts +2 -1
  76. package/dist/components/Link/Link.js +13 -15
  77. package/dist/components/Link/types.d.ts +4 -4
  78. package/dist/components/List/List.d.ts +17 -3
  79. package/dist/components/List/List.js +32 -18
  80. package/dist/components/List/List.module.css.js +0 -3
  81. package/dist/components/List/components/ListItemText/ListItemText.js +26 -0
  82. package/dist/components/List/components/ListItemText/ListItemText.module.css.js +11 -0
  83. package/dist/components/List/components/ListOption/ListOption.d.ts +3 -2
  84. package/dist/components/List/components/ListOption/ListOption.js +11 -16
  85. package/dist/components/List/components/ListSection/ListSection.d.ts +3 -2
  86. package/dist/components/List/components/ListSection/ListSection.js +1 -4
  87. package/dist/components/List/index.d.ts +2 -2
  88. package/dist/components/List/types.d.ts +13 -2
  89. package/dist/components/Menu/Menu.d.ts +15 -0
  90. package/dist/components/Menu/Menu.js +68 -0
  91. package/dist/components/Menu/Menu.module.css.js +8 -0
  92. package/dist/components/Menu/components/MenuHeader/MenuHeader.d.ts +5 -0
  93. package/dist/components/Menu/components/MenuHeader/MenuHeader.js +9 -0
  94. package/dist/components/Menu/components/MenuHeader/index.d.ts +1 -0
  95. package/dist/components/Menu/components/MenuInner/MenuInner.d.ts +3 -0
  96. package/dist/components/Menu/components/MenuInner/MenuInner.js +45 -0
  97. package/dist/components/Menu/components/MenuInner/MenuInner.module.css.js +11 -0
  98. package/dist/components/Menu/components/MenuInner/index.d.ts +1 -0
  99. package/dist/components/Menu/components/MenuItem/MenuItem.d.ts +6 -0
  100. package/dist/components/Menu/components/MenuItem/MenuItem.js +36 -0
  101. package/dist/components/Menu/components/MenuItem/index.d.ts +1 -0
  102. package/dist/components/Menu/components/MenuSection/MenuSection.d.ts +6 -0
  103. package/dist/components/Menu/components/MenuSection/MenuSection.js +30 -0
  104. package/dist/components/Menu/components/MenuSection/MenuSection.module.css.js +11 -0
  105. package/dist/components/Menu/components/MenuSection/index.d.ts +1 -0
  106. package/dist/components/Menu/components/index.d.ts +1 -0
  107. package/dist/components/Menu/index.d.ts +2 -0
  108. package/dist/components/Menu/types.d.ts +62 -0
  109. package/dist/components/Menu/types.js +4 -0
  110. package/dist/components/Modal/Modal.d.ts +9 -1
  111. package/dist/components/Modal/Modal.js +21 -16
  112. package/dist/components/Modal/index.d.ts +15 -2
  113. package/dist/components/Modal/index.js +9 -0
  114. package/dist/components/Modal/types.d.ts +7 -0
  115. package/dist/components/Popover/Popover.d.ts +12 -2
  116. package/dist/components/Popover/Popover.js +143 -128
  117. package/dist/components/Popover/Popover.module.css.js +3 -0
  118. package/dist/components/Popover/index.d.ts +15 -2
  119. package/dist/components/Popover/index.js +9 -0
  120. package/dist/components/Popover/types.d.ts +28 -4
  121. package/dist/components/Popover/types.js +9 -1
  122. package/dist/components/ProgressBar/ProgressBar.module.css.js +1 -2
  123. package/dist/components/ProgressSpinner/ProgressSpinner.module.css.js +1 -2
  124. package/dist/components/Provider/BreakpointsProvider.d.ts +2 -1
  125. package/dist/components/Provider/BreakpointsProvider.js +8 -1
  126. package/dist/components/Provider/Provider.d.ts +1 -1
  127. package/dist/components/Provider/Provider.js +9 -1
  128. package/dist/components/Provider/types.d.ts +5 -0
  129. package/dist/components/Provider/utils/useBreakpoints.d.ts +2 -1
  130. package/dist/components/Provider/utils/useBreakpoints.js +2 -2
  131. package/dist/components/RadioGroup/RadioContext.js +1 -0
  132. package/dist/components/RadioGroup/RadioGroup.js +2 -1
  133. package/dist/components/RadioGroup/components/Radio/Radio.js +3 -2
  134. package/dist/components/RadioGroup/components/Radio/Radio.module.css.js +3 -0
  135. package/dist/components/Select/Select.d.ts +11 -0
  136. package/dist/components/Select/Select.js +179 -0
  137. package/dist/components/Select/Select.module.css.js +20 -0
  138. package/dist/components/Select/index.d.ts +2 -0
  139. package/dist/components/Select/types.d.ts +87 -0
  140. package/dist/components/SidePanel/SidePanel.d.ts +9 -1
  141. package/dist/components/SidePanel/SidePanel.js +24 -19
  142. package/dist/components/SidePanel/index.d.ts +15 -2
  143. package/dist/components/SidePanel/index.js +9 -0
  144. package/dist/components/SidePanel/types.d.ts +7 -0
  145. package/dist/components/SkeletonBlock/SkeletonBlock.module.css.js +0 -1
  146. package/dist/components/SkeletonTypography/utils.js +3 -0
  147. package/dist/components/Toggle/Toggle.js +1 -1
  148. package/dist/components/Tooltip/Tooltip.d.ts +2 -1
  149. package/dist/components/Tooltip/Tooltip.js +9 -8
  150. package/dist/components/Tooltip/types.d.ts +9 -4
  151. package/dist/components/Typography/Typography.js +2 -2
  152. package/dist/components/Typography/Typography.module.css.js +2 -1
  153. package/dist/components/Typography/types.d.ts +7 -2
  154. package/dist/components/Typography/types.js +2 -1
  155. package/dist/components/index.d.ts +6 -0
  156. package/dist/components/layout/flex/flex.d.ts +15 -4
  157. package/dist/components/layout/flex/flex.js +6 -1
  158. package/dist/components/layout/flex/flex.module.css.js +78 -39
  159. package/dist/index.js +43 -23
  160. package/dist/style.css +756 -352
  161. package/dist/styles/utility.d.ts +2 -0
  162. package/dist/styles/utility.js +3 -2
  163. package/dist/styles/utility.module.css.js +5 -2
  164. package/dist/types.d.ts +1 -0
  165. package/package.json +11 -6
  166. package/dist/components/Dialog/DialogContext.d.ts +0 -9
  167. package/dist/components/Dialog/DialogContext.js +0 -12
  168. package/dist/components/Dialog/components/DialogContent.d.ts +0 -12
  169. package/dist/components/Input/components/FieldAddon/FieldAddon.d.ts +0 -10
  170. package/dist/components/Input/components/FieldAddon/index.d.ts +0 -1
  171. package/dist/components/Input/components/FieldCaption/FieldCaption.d.ts +0 -6
  172. package/dist/components/Input/components/FieldCaption/index.d.ts +0 -1
  173. package/dist/components/Input/components/FieldControl/FieldControl.d.ts +0 -9
  174. package/dist/components/Input/components/FieldControl/index.d.ts +0 -1
  175. package/dist/components/Input/components/FieldError/FieldError.d.ts +0 -7
  176. package/dist/components/Input/components/FieldError/index.d.ts +0 -1
  177. package/dist/components/Input/components/FieldInput/FieldInput.d.ts +0 -9
  178. package/dist/components/Input/components/FieldInput/index.d.ts +0 -1
  179. package/dist/components/Input/components/FieldInputGroup/FieldInputGroup.d.ts +0 -7
  180. package/dist/components/Input/components/FieldInputGroup/index.d.ts +0 -1
  181. package/dist/components/Input/components/FieldLabel/FieldLabel.d.ts +0 -9
  182. package/dist/components/Input/components/FieldLabel/index.d.ts +0 -1
  183. package/dist/components/Input/components/index.d.ts +0 -7
  184. package/dist/components/List/ListItem.d.ts +0 -11
  185. package/dist/components/List/ListItem.js +0 -11
  186. package/dist/components/List/ListSection.js +0 -11
  187. package/dist/components/List/components/ListOption/ListOption.module.css.js +0 -23
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from "react/jsx-runtime";
3
- import { polymorphicForwardRef, mergeProps, clsx, isNotNil } from "@koobiq/react-core";
3
+ import { polymorphicForwardRef, mergeProps, isNotNil, clsx } from "@koobiq/react-core";
4
4
  import { IconXmark16 } from "@koobiq/react-icons";
5
5
  import { useLocalizedStringFormatter } from "@koobiq/react-primitives";
6
6
  import s from "./Alert.module.css.js";
@@ -42,7 +42,7 @@ const Alert = polymorphicForwardRef(
42
42
  {
43
43
  "aria-label": stringFormatter.format("close"),
44
44
  variant: "fade-contrast",
45
- onClick: onClose,
45
+ onPress: onClose,
46
46
  className: s.closeIcon
47
47
  },
48
48
  slotProps?.closeIcon
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { IconInfoCircle16, IconCheck16, IconExclamationTriangle16, IconCheckCircle16 } from "@koobiq/react-icons";
2
+ import { IconExclamationTriangle16, IconCheckCircle16, IconInfoCircle16, IconCheck16 } from "@koobiq/react-icons";
3
3
  const iconProps = {
4
4
  focusable: false,
5
5
  "aria-hidden": true
@@ -1,10 +1,6 @@
1
1
  const intlMessages = {
2
- "ru-RU": {
3
- close: "Закрыть"
4
- },
5
- "en-US": {
6
- close: "Close"
7
- }
2
+ "ru-RU": { "close": "Закрыть" },
3
+ "en-US": { "close": "Close" }
8
4
  };
9
5
  export {
10
6
  intlMessages as default
@@ -34,7 +34,7 @@ export type AlertBaseProps = {
34
34
  /** Override default icon. */
35
35
  icon?: ReactNode;
36
36
  /** A callback function called when the user clicks the alert's close button. */
37
- onClose?: IconButtonProps['onClick'];
37
+ onClose?: IconButtonProps['onPress'];
38
38
  slotProps?: {
39
39
  content?: ComponentPropsWithRef<'div'>;
40
40
  statusIcon?: ComponentPropsWithRef<'div'>;
@@ -0,0 +1,4 @@
1
+ import type { ComponentPropsWithRef, ElementType } from 'react';
2
+ import type { AnimatedIconBaseProps } from './index';
3
+ export declare const AnimatedIcon: import("@koobiq/react-core").PolyForwardComponent<"span", AnimatedIconBaseProps, ElementType>;
4
+ export type AnimatedIconProps<As extends ElementType = 'span'> = ComponentPropsWithRef<typeof AnimatedIcon<As>>;
@@ -0,0 +1,50 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { polymorphicForwardRef, useRefs, clsx } from "@koobiq/react-core";
4
+ import { Transition } from "react-transition-group";
5
+ import s from "./AnimatedIcon.module.css.js";
6
+ const AnimatedIcon = polymorphicForwardRef((props, ref) => {
7
+ const {
8
+ transition = 300,
9
+ as: Tag = "span",
10
+ activeIndex = 0,
11
+ directions,
12
+ className,
13
+ icons = [],
14
+ style: styleProp,
15
+ ...other
16
+ } = props;
17
+ const refs = useRefs(icons.length);
18
+ const singleIcon = icons?.[0];
19
+ const innerRender = icons.length === 1 ? singleIcon : icons.map((icon, index) => /* @__PURE__ */ jsx(
20
+ Transition,
21
+ {
22
+ in: activeIndex === index,
23
+ timeout: transition,
24
+ nodeRef: refs[index],
25
+ unmountOnExit: true,
26
+ children: (transition2) => /* @__PURE__ */ jsx(
27
+ "span",
28
+ {
29
+ className: s.icon,
30
+ "data-index": index,
31
+ ref: refs[index],
32
+ "data-transition": transition2,
33
+ children: icon
34
+ }
35
+ )
36
+ },
37
+ index
38
+ ));
39
+ const style = {
40
+ ...styleProp,
41
+ "--animated-icon-transition": `${transition}ms`,
42
+ ...typeof directions?.[activeIndex] === "number" && {
43
+ "--animated-icon-direction": `rotate(${directions[activeIndex]}deg)`
44
+ }
45
+ };
46
+ return /* @__PURE__ */ jsx(Tag, { ...other, className: clsx(s.base, className), style, ref, children: innerRender });
47
+ });
48
+ export {
49
+ AnimatedIcon
50
+ };
@@ -0,0 +1,11 @@
1
+ const base = "kbq-animatedicon-61fd86";
2
+ const icon = "kbq-animatedicon-icon-2feff8";
3
+ const s = {
4
+ base,
5
+ icon
6
+ };
7
+ export {
8
+ base,
9
+ s as default,
10
+ icon
11
+ };
@@ -0,0 +1,2 @@
1
+ export * from './AnimatedIcon';
2
+ export * from './types';
@@ -0,0 +1,19 @@
1
+ import type { ComponentRef, CSSProperties, ReactNode } from 'react';
2
+ export type AnimatedIconBaseProps = {
3
+ /** A list of icons. */
4
+ icons?: ReactNode[];
5
+ /** A list of directions for the icons. */
6
+ directions?: number[];
7
+ /**
8
+ * Animation duration in milliseconds.
9
+ * @default 300
10
+ * */
11
+ transition?: number;
12
+ /** Index of the active icon. */
13
+ activeIndex?: number;
14
+ /** Additional CSS-classes. */
15
+ className?: string;
16
+ /** Inline styles. */
17
+ style?: CSSProperties;
18
+ };
19
+ export type AnimatedIconRef = ComponentRef<'span'>;
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsxs, Fragment, jsx } from "react/jsx-runtime";
2
+ import { jsxs, jsx, Fragment } from "react/jsx-runtime";
3
3
  import { polymorphicForwardRef, clsx } from "@koobiq/react-core";
4
4
  import { Button as Button$1 } from "@koobiq/react-primitives";
5
5
  import s from "./Button.module.css.js";
@@ -1,8 +1,8 @@
1
1
  const base = "kbq-button-d95067";
2
2
  const hovered = "kbq-button-hovered-037da3";
3
+ const progress = "kbq-button-progress-f454f0";
3
4
  const pressed = "kbq-button-pressed-508d5d";
4
5
  const focusVisible = "kbq-button-focusVisible-e63c2b";
5
- const progress = "kbq-button-progress-f454f0";
6
6
  const disabled = "kbq-button-disabled-1df5f6";
7
7
  const fullWidth = "kbq-button-fullWidth-c149b8";
8
8
  const onlyIcon = "kbq-button-onlyIcon-e1268c";
@@ -12,9 +12,9 @@ const label = "kbq-button-label-9f6f6b";
12
12
  const s = {
13
13
  base,
14
14
  hovered,
15
+ progress,
15
16
  pressed,
16
17
  focusVisible,
17
- progress,
18
18
  disabled,
19
19
  fullWidth,
20
20
  onlyIcon,
@@ -1,9 +1,9 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { ButtonOptions, HoverEvent } from '@koobiq/react-primitives';
2
+ import type { ExtendableProps } from '@koobiq/react-core';
3
+ import type { HoverEvent, UseButtonProps } from '@koobiq/react-primitives';
3
4
  export declare const buttonPropVariant: readonly ["contrast-filled", "contrast-transparent", "fade-contrast-filled", "fade-contrast-outline", "fade-theme-outline", "theme-transparent"];
4
5
  export type ButtonPropVariant = (typeof buttonPropVariant)[number];
5
- export type ButtonPropOnClick = ButtonOptions['onPress'];
6
- export type ButtonBaseProps = {
6
+ export type ButtonBaseProps = ExtendableProps<{
7
7
  /** The content of the component. */
8
8
  children?: ReactNode;
9
9
  /**
@@ -43,5 +43,4 @@ export type ButtonBaseProps = {
43
43
  onHoverStart?: (e: HoverEvent) => void;
44
44
  /** Handler that is called when a hover interaction ends. */
45
45
  onHoverEnd?: (e: HoverEvent) => void;
46
- onClick?: ButtonPropOnClick;
47
- };
46
+ }, UseButtonProps>;
@@ -0,0 +1,2 @@
1
+ import type { ButtonToggleGroupProps } from './types';
2
+ export declare const ButtonToggleGroup: import("react").ForwardRefExoticComponent<Omit<ButtonToggleGroupProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
@@ -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,2 @@
1
+ import type { ButtonToggleProps } from './types';
2
+ export declare const ButtonToggle: import("react").ForwardRefExoticComponent<Omit<ButtonToggleProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
@@ -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,2 @@
1
+ export * from './ButtonToggle';
2
+ export * from './types';
@@ -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,3 @@
1
+ export * from './ButtonToggleGroup';
2
+ export * from './components';
3
+ export * from './types';
@@ -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,3 @@
1
+ import type { CSSProperties } from 'react';
2
+ export declare function getToggleButtonStyle(start?: [number, number], end?: [number, number]): CSSProperties;
3
+ export declare function getSelectedToggleButton(root: HTMLElement | null): HTMLElement | null;
@@ -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
+ };