@koobiq/react-primitives 0.19.0 → 0.21.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.
@@ -6,12 +6,15 @@ function useButton(props, ref) {
6
6
  const { focusProps, isFocused, isFocusVisible } = useFocusRing({
7
7
  within: true
8
8
  });
9
- const { hoverProps, isHovered } = useHover(props);
10
- const { buttonProps: buttonPropsReactAria, isPressed } = useButton$1(
9
+ const { hoverProps, isHovered } = useHover({
10
+ ...props,
11
+ isDisabled: props.isDisabled
12
+ });
13
+ const { buttonProps: buttonPropsAria, isPressed } = useButton$1(
11
14
  props,
12
15
  ref
13
16
  );
14
- const buttonProps = mergeProps(buttonPropsReactAria, focusProps, hoverProps);
17
+ const buttonProps = mergeProps(buttonPropsAria, focusProps, hoverProps);
15
18
  return {
16
19
  isPressed,
17
20
  isHovered,
@@ -89,7 +89,7 @@ export declare function useSwitch(props: UseSwitchProps, ref: RefObject<HTMLInpu
89
89
  onBlurCapture?: (import("react").FocusEventHandler<import("@react-types/shared").FocusableElement> & import("react").FocusEventHandler<HTMLInputElement>) | undefined;
90
90
  onChange?: (import("react").FormEventHandler<import("@react-types/shared").FocusableElement> & import("react").ChangeEventHandler<HTMLInputElement>) | undefined;
91
91
  onChangeCapture?: (import("react").FormEventHandler<import("@react-types/shared").FocusableElement> & import("react").FormEventHandler<HTMLInputElement>) | undefined;
92
- onBeforeInput?: (import("react").FormEventHandler<import("@react-types/shared").FocusableElement> & import("react").FormEventHandler<HTMLInputElement>) | undefined;
92
+ onBeforeInput?: (import("react").InputEventHandler<import("@react-types/shared").FocusableElement> & import("react").InputEventHandler<HTMLInputElement>) | undefined;
93
93
  onBeforeInputCapture?: (import("react").FormEventHandler<import("@react-types/shared").FocusableElement> & import("react").FormEventHandler<HTMLInputElement>) | undefined;
94
94
  onInput?: (import("react").FormEventHandler<import("@react-types/shared").FocusableElement> & import("react").FormEventHandler<HTMLInputElement>) | undefined;
95
95
  onInputCapture?: (import("react").FormEventHandler<import("@react-types/shared").FocusableElement> & import("react").FormEventHandler<HTMLInputElement>) | undefined;
@@ -139,8 +139,6 @@ export declare function useSwitch(props: UseSwitchProps, ref: RefObject<HTMLInpu
139
139
  onProgressCapture?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
140
140
  onRateChange?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
141
141
  onRateChangeCapture?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
142
- onResize?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
143
- onResizeCapture?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
144
142
  onSeeked?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
145
143
  onSeekedCapture?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
146
144
  onSeeking?: (import("react").ReactEventHandler<import("@react-types/shared").FocusableElement> & import("react").ReactEventHandler<HTMLInputElement>) | undefined;
@@ -221,6 +219,8 @@ export declare function useSwitch(props: UseSwitchProps, ref: RefObject<HTMLInpu
221
219
  onLostPointerCaptureCapture?: (import("react").PointerEventHandler<import("@react-types/shared").FocusableElement> & import("react").PointerEventHandler<HTMLInputElement>) | undefined;
222
220
  onScroll?: (import("react").UIEventHandler<import("@react-types/shared").FocusableElement> & import("react").UIEventHandler<HTMLInputElement>) | undefined;
223
221
  onScrollCapture?: (import("react").UIEventHandler<import("@react-types/shared").FocusableElement> & import("react").UIEventHandler<HTMLInputElement>) | undefined;
222
+ onScrollEnd?: (import("react").UIEventHandler<import("@react-types/shared").FocusableElement> & import("react").UIEventHandler<HTMLInputElement>) | undefined;
223
+ onScrollEndCapture?: (import("react").UIEventHandler<import("@react-types/shared").FocusableElement> & import("react").UIEventHandler<HTMLInputElement>) | undefined;
224
224
  onWheel?: (import("react").WheelEventHandler<import("@react-types/shared").FocusableElement> & import("react").WheelEventHandler<HTMLInputElement>) | undefined;
225
225
  onWheelCapture?: (import("react").WheelEventHandler<import("@react-types/shared").FocusableElement> & import("react").WheelEventHandler<HTMLInputElement>) | undefined;
226
226
  onAnimationStart?: (import("react").AnimationEventHandler<import("@react-types/shared").FocusableElement> & import("react").AnimationEventHandler<HTMLInputElement>) | undefined;
@@ -229,8 +229,16 @@ export declare function useSwitch(props: UseSwitchProps, ref: RefObject<HTMLInpu
229
229
  onAnimationEndCapture?: (import("react").AnimationEventHandler<import("@react-types/shared").FocusableElement> & import("react").AnimationEventHandler<HTMLInputElement>) | undefined;
230
230
  onAnimationIteration?: (import("react").AnimationEventHandler<import("@react-types/shared").FocusableElement> & import("react").AnimationEventHandler<HTMLInputElement>) | undefined;
231
231
  onAnimationIterationCapture?: (import("react").AnimationEventHandler<import("@react-types/shared").FocusableElement> & import("react").AnimationEventHandler<HTMLInputElement>) | undefined;
232
+ onToggle?: (import("react").ToggleEventHandler<import("@react-types/shared").FocusableElement> & import("react").ToggleEventHandler<HTMLInputElement>) | undefined;
233
+ onBeforeToggle?: (import("react").ToggleEventHandler<import("@react-types/shared").FocusableElement> & import("react").ToggleEventHandler<HTMLInputElement>) | undefined;
234
+ onTransitionCancel?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
235
+ onTransitionCancelCapture?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
232
236
  onTransitionEnd?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
233
237
  onTransitionEndCapture?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
238
+ onTransitionRun?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
239
+ onTransitionRunCapture?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
240
+ onTransitionStart?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
241
+ onTransitionStartCapture?: (import("react").TransitionEventHandler<import("@react-types/shared").FocusableElement> & import("react").TransitionEventHandler<HTMLInputElement>) | undefined;
234
242
  accept?: string | undefined;
235
243
  alt?: string | undefined;
236
244
  autoComplete?: import("react").HTMLInputAutoCompleteAttribute | undefined;
@@ -238,7 +246,7 @@ export declare function useSwitch(props: UseSwitchProps, ref: RefObject<HTMLInpu
238
246
  checked?: boolean | undefined;
239
247
  disabled?: boolean | undefined;
240
248
  form?: string | undefined;
241
- formAction?: string | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS] | undefined;
249
+ formAction?: string | ((formData: FormData) => void | Promise<void>) | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_EXPERIMENTAL_FORM_ACTIONS] | undefined;
242
250
  formEncType?: string | undefined;
243
251
  formMethod?: string | undefined;
244
252
  formNoValidate?: boolean | undefined;
@@ -303,8 +311,14 @@ export declare function useSwitch(props: UseSwitchProps, ref: RefObject<HTMLInpu
303
311
  results?: number | undefined;
304
312
  security?: string | undefined;
305
313
  unselectable?: "on" | "off" | undefined;
314
+ popover?: "" | "auto" | "manual" | "hint" | undefined;
315
+ popoverTargetAction?: "toggle" | "show" | "hide" | undefined;
316
+ popoverTarget?: string | undefined;
317
+ inert?: boolean | undefined;
306
318
  inputMode?: "none" | "text" | "tel" | "url" | "email" | "numeric" | "decimal" | "search" | undefined;
307
319
  is?: string | undefined;
320
+ exportparts?: string | undefined;
321
+ part?: string | undefined;
308
322
  ref: RefObject<HTMLInputElement | null>;
309
323
  };
310
324
  isInvalid: boolean | undefined;
@@ -1,4 +1,4 @@
1
1
  import type { ComponentPropsWithRef, ElementType } from 'react';
2
- import type { ButtonBaseProps } from './types.js';
2
+ import type { ButtonBaseProps } from './types';
3
3
  export declare const Button: import("@koobiq/react-core").PolyForwardComponent<"button", ButtonBaseProps, ElementType>;
4
4
  export type ButtonProps<As extends ElementType = 'button'> = ComponentPropsWithRef<typeof Button<As>>;
@@ -1,16 +1,15 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { polymorphicForwardRef, useDOMRef, filterDOMProps, mergeProps } from "@koobiq/react-core";
4
- import { useRenderProps } from "../../utils/index.js";
5
- import { useSlottedContext } from "../../utils/useSlottedContext.js";
4
+ import { useContextProps, useRenderProps } from "../../utils/index.js";
6
5
  import { ButtonContext } from "./ButtonContext.js";
7
6
  import { useButton } from "../../behaviors/useButton.js";
8
7
  const Button = polymorphicForwardRef(
9
8
  (props, ref) => {
10
- const { as, slot, tabIndex } = props;
11
- const Tag = as || "button";
12
- const commonProps = useSlottedContext(props, ButtonContext, slot);
9
+ const [ctxProps, ctxRef] = useContextProps(props, ref, ButtonContext);
13
10
  const {
11
+ as,
12
+ tabIndex,
14
13
  isLoading,
15
14
  isDisabled,
16
15
  value,
@@ -21,11 +20,12 @@ const Button = polymorphicForwardRef(
21
20
  formMethod,
22
21
  formNoValidate,
23
22
  formTarget
24
- } = commonProps;
25
- const domRef = useDOMRef(ref);
23
+ } = ctxProps;
24
+ const Tag = as || "button";
25
+ const domRef = useDOMRef(ctxRef);
26
26
  const { isHovered, isPressed, isFocused, isFocusVisible, buttonProps } = useButton(
27
27
  {
28
- ...commonProps,
28
+ ...ctxProps,
29
29
  ...(isLoading || isDisabled) && {
30
30
  onPress: void 0,
31
31
  onPressStart: void 0,
@@ -73,10 +73,11 @@ const Button = polymorphicForwardRef(
73
73
  "data-hovered": isHovered || void 0,
74
74
  "data-pressed": isPressed || void 0,
75
75
  "data-focused": isFocused || void 0,
76
+ "data-loading": isLoading || void 0,
76
77
  "data-disabled": isDisabled || void 0,
77
78
  "data-focus-visible": isFocusVisible || void 0,
78
- tabIndex: buttonProps.tabIndex,
79
- ..."tabIndex" in props && { tabIndex },
79
+ ..."tabIndex" in ctxProps && { tabIndex },
80
+ "aria-hidden": ctxProps["aria-hidden"],
80
81
  "aria-disabled": isLoading ? "true" : buttonProps["aria-disabled"],
81
82
  "aria-busy": isLoading,
82
83
  ref: domRef,
@@ -1,5 +1,3 @@
1
+ import type { ContextValue } from '../../utils';
1
2
  import type { ButtonProps } from './index';
2
- export type ButtonContextProps = {
3
- slots?: Record<string, ButtonProps>;
4
- };
5
- export declare const ButtonContext: import("react").Context<ButtonContextProps>;
3
+ export declare const ButtonContext: import("react").Context<ContextValue<ButtonProps, HTMLElement>>;
@@ -37,4 +37,5 @@ export type ButtonBaseProps = RenderProps<ButtonRenderProps> & {
37
37
  * Whether this button is loading.
38
38
  */
39
39
  isLoading?: boolean;
40
+ 'aria-hidden'?: boolean | 'true' | 'false';
40
41
  } & Omit<UseButtonProps<never>, 'elementType' | 'href'>;
@@ -2,6 +2,6 @@ import type { ComponentRef, HTMLAttributes, ReactNode, Ref } from 'react';
2
2
  export type InputProps = {
3
3
  children?: ReactNode;
4
4
  value?: string | number | readonly string[];
5
- ref?: Ref<HTMLInputElement>;
5
+ ref?: Ref<HTMLInputElement | HTMLTextAreaElement>;
6
6
  } & HTMLAttributes<HTMLInputElement | HTMLTextAreaElement>;
7
7
  export type InputRef = ComponentRef<'input'>;
@@ -1,14 +1,13 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { useContext } from "react";
4
- import { polymorphicForwardRef, mergeProps } from "@koobiq/react-core";
3
+ import { polymorphicForwardRef } from "@koobiq/react-core";
4
+ import { useContextProps } from "../../utils/index.js";
5
5
  import { LabelContext } from "./LabelContext.js";
6
6
  const Label = polymorphicForwardRef(
7
7
  (props, ref) => {
8
- const { as: Tag = "label", children, ...other } = props;
9
- const defaultProps = useContext(LabelContext);
10
- const commonProps = mergeProps(defaultProps, other);
11
- return /* @__PURE__ */ jsx(Tag, { ...commonProps, ref, children });
8
+ const [ctxProps, ctxRef] = useContextProps(props, ref, LabelContext);
9
+ const { as: Tag = "label", children, ...other } = ctxProps;
10
+ return /* @__PURE__ */ jsx(Tag, { ...other, ref: ctxRef, children });
12
11
  }
13
12
  );
14
13
  Label.displayName = "Label";
@@ -1,5 +1,3 @@
1
- export declare const LabelContext: import("react").Context<Omit<Omit<import("react").DetailedHTMLProps<import("react").LabelHTMLAttributes<HTMLLabelElement>, HTMLLabelElement>, "ref"> & {
2
- ref?: ((instance: HTMLLabelElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLLabelElement> | null | undefined;
3
- }, "children" | "as"> & import("./types").LabelBaseProps & {
4
- as?: "label" | undefined;
5
- }>;
1
+ import type { ContextValue } from '../../utils';
2
+ import type { LabelProps } from './index';
3
+ export declare const LabelContext: import("react").Context<ContextValue<LabelProps, HTMLElement>>;
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { createContext } from "react";
3
- const LabelContext = createContext({});
3
+ const LabelContext = createContext(null);
4
4
  export {
5
5
  LabelContext
6
6
  };
@@ -1,2 +1,4 @@
1
+ import type { ComponentPropsWithRef, ElementType } from 'react';
1
2
  import type { LinkBaseProps } from './types.js';
2
- export declare const Link: import("@koobiq/react-core").PolyForwardComponent<"a", LinkBaseProps, import("react").ElementType>;
3
+ export declare const Link: import("@koobiq/react-core").PolyForwardComponent<"a", LinkBaseProps, ElementType>;
4
+ export type LinkProps<As extends ElementType = 'a'> = ComponentPropsWithRef<typeof Link<As>>;
@@ -37,8 +37,13 @@ const Link = polymorphicForwardRef((props, ref) => {
37
37
  return /* @__PURE__ */ jsx(
38
38
  Tag,
39
39
  {
40
+ "data-hovered": isHovered || void 0,
41
+ "data-pressed": isPressed || void 0,
42
+ "data-focused": isFocused || void 0,
43
+ "data-disabled": props.isDisabled || void 0,
44
+ "data-focus-visible": isFocusVisible || void 0,
40
45
  ...mergeProps(linkProps, renderProps),
41
- tabIndex: props.tabIndex || linkProps.tabIndex,
46
+ ..."tabIndex" in props && { tabIndex: props.tabIndex },
42
47
  ref: domRef,
43
48
  children: renderProps.children
44
49
  }
@@ -7,9 +7,9 @@ import { useNumberField } from "@react-aria/numberfield";
7
7
  import { useNumberFieldState } from "@react-stately/numberfield";
8
8
  import { useSlottedContext, removeDataAttributes, useRenderProps, Provider } from "../../utils/index.js";
9
9
  import { GroupContext } from "../Group/GroupContext.js";
10
- import { ButtonContext } from "../Button/ButtonContext.js";
11
10
  import { LabelContext } from "../Label/LabelContext.js";
12
11
  import { InputContext } from "../Input/InputContext.js";
12
+ import { ButtonContext } from "../Button/ButtonContext.js";
13
13
  import { TextContext } from "../Text/TextContext.js";
14
14
  import { FieldErrorContext } from "../FieldError/FieldError.js";
15
15
  import { FormContext } from "../Form/Form.js";
@@ -57,14 +57,8 @@ const NumberField = forwardRef(
57
57
  ButtonContext,
58
58
  {
59
59
  slots: {
60
- increment: {
61
- ...incrementButtonProps,
62
- disabled: incrementButtonProps.isDisabled
63
- },
64
- decrement: {
65
- ...decrementButtonProps,
66
- disabled: decrementButtonProps.isDisabled
67
- }
60
+ increment: incrementButtonProps,
61
+ decrement: decrementButtonProps
68
62
  }
69
63
  }
70
64
  ],
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  import { polymorphicForwardRef } from "@koobiq/react-core";
4
- import { useSlottedContext } from "../../utils/useSlottedContext.js";
4
+ import { useContextProps } from "../../utils/index.js";
5
5
  import { TextContext } from "./TextContext.js";
6
6
  const Text = polymorphicForwardRef((props, ref) => {
7
- const { as: Tag = "p", children, slot, ...other } = props;
8
- const commonProps = useSlottedContext(other, TextContext, slot);
9
- return /* @__PURE__ */ jsx(Tag, { ...commonProps, ref, children });
7
+ const [ctxProps, ctxRef] = useContextProps(props, ref, TextContext);
8
+ const { as: Tag = "p", children, ...other } = ctxProps;
9
+ return /* @__PURE__ */ jsx(Tag, { ...other, ref: ctxRef, children });
10
10
  });
11
11
  Text.displayName = "Text";
12
12
  export {
@@ -1,5 +1,3 @@
1
+ import type { ContextValue } from '../../utils';
1
2
  import type { TextProps } from './Text';
2
- export type TextContextProps = {
3
- slots?: Record<string, TextProps>;
4
- };
5
- export declare const TextContext: import("react").Context<TextContextProps>;
3
+ export declare const TextContext: import("react").Context<ContextValue<TextProps, HTMLElement>>;
@@ -1,6 +1,8 @@
1
1
  "use client";
2
2
  import { createContext } from "react";
3
- const TextContext = createContext({});
3
+ const TextContext = createContext(
4
+ {}
5
+ );
4
6
  export {
5
7
  TextContext
6
8
  };
@@ -1,20 +1,49 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { forwardRef, useRef } from "react";
4
- import { filterDOMProps } from "@koobiq/react-core";
3
+ import { forwardRef, useRef, useCallback } from "react";
4
+ import { useLocalizedStringFormatter, useControlledState, useIsomorphicEffect, filterDOMProps } from "@koobiq/react-core";
5
5
  import { useTextField } from "@react-aria/textfield";
6
6
  import { useSlottedContext, removeDataAttributes, useRenderProps, Provider } from "../../utils/index.js";
7
+ import intlMessages from "./intl.json.js";
7
8
  import { InputContext } from "../Input/InputContext.js";
8
9
  import { TextareaContext } from "../Textarea/TextareaContext.js";
10
+ import { ButtonContext } from "../Button/ButtonContext.js";
9
11
  import { FormContext } from "../Form/Form.js";
10
12
  import { LabelContext } from "../Label/LabelContext.js";
11
13
  import { TextContext } from "../Text/TextContext.js";
12
14
  import { FieldErrorContext } from "../FieldError/FieldError.js";
13
15
  function TextFieldRender(props, ref) {
14
- const { isDisabled, isReadOnly, isRequired } = props;
16
+ const { isDisabled, isReadOnly, isRequired, onClear, isClearable } = props;
17
+ const stringFormatter = useLocalizedStringFormatter(intlMessages);
18
+ const inputRef = useRef(null);
19
+ const [inputValue, setInputValue] = useControlledState(
20
+ props.value,
21
+ props.defaultValue ?? "",
22
+ props?.onChange
23
+ );
24
+ const setValue = useCallback((value) => {
25
+ setInputValue(value);
26
+ }, []);
27
+ const handleClear = useCallback(() => {
28
+ setInputValue("");
29
+ onClear?.();
30
+ inputRef?.current?.focus();
31
+ }, [setInputValue, onClear]);
32
+ useIsomorphicEffect(() => {
33
+ if (!inputRef.current) return;
34
+ setInputValue(inputRef.current.value);
35
+ }, [inputRef.current]);
36
+ const handleKeyDown = useCallback(
37
+ (e) => {
38
+ if (e.key === "Escape" && inputValue && (isClearable || onClear) && !isReadOnly) {
39
+ setInputValue("");
40
+ onClear?.();
41
+ }
42
+ },
43
+ [inputValue, setInputValue, onClear, isClearable, isReadOnly]
44
+ );
15
45
  const { validationBehavior: formValidationBehavior } = useSlottedContext(FormContext) || {};
16
46
  const validationBehavior = props.validationBehavior ?? formValidationBehavior ?? "aria";
17
- const inputRef = useRef(null);
18
47
  const {
19
48
  labelProps,
20
49
  inputProps,
@@ -24,6 +53,12 @@ function TextFieldRender(props, ref) {
24
53
  } = useTextField(
25
54
  {
26
55
  ...removeDataAttributes(props),
56
+ value: inputValue,
57
+ onKeyDown: (e) => {
58
+ props?.onKeyDown?.(e);
59
+ handleKeyDown(e);
60
+ },
61
+ onChange: setInputValue,
27
62
  validationBehavior
28
63
  },
29
64
  inputRef
@@ -36,7 +71,11 @@ function TextFieldRender(props, ref) {
36
71
  isInvalid: validation.isInvalid || false,
37
72
  isDisabled: isDisabled || false,
38
73
  isReadOnly: isReadOnly || false,
39
- isRequired: isRequired || false
74
+ isRequired: isRequired || false,
75
+ state: {
76
+ value: inputValue,
77
+ set: setValue
78
+ }
40
79
  }
41
80
  });
42
81
  return /* @__PURE__ */ jsx(
@@ -65,6 +104,19 @@ function TextFieldRender(props, ref) {
65
104
  }
66
105
  }
67
106
  ],
107
+ [
108
+ ButtonContext,
109
+ {
110
+ slots: {
111
+ "clear-button": {
112
+ "aria-label": stringFormatter.format("clear"),
113
+ preventFocusOnPress: true,
114
+ onPress: handleClear,
115
+ tabIndex: -1
116
+ }
117
+ }
118
+ }
119
+ ],
68
120
  [FieldErrorContext, validation]
69
121
  ],
70
122
  children: renderProps.children
@@ -0,0 +1,7 @@
1
+ const intlMessages = {
2
+ "ru-RU": { "clear": "Очистить поле" },
3
+ "en-US": { "clear": "Clear input" }
4
+ };
5
+ export {
6
+ intlMessages as default
7
+ };
@@ -23,9 +23,17 @@ export type TextFieldRenderProps = {
23
23
  * @selector [data-required]
24
24
  */
25
25
  isRequired: boolean;
26
+ state: {
27
+ value: string;
28
+ set: (value: string) => void;
29
+ };
26
30
  };
27
31
  type TextFieldBaseProps = RenderProps<TextFieldRenderProps> & {
28
32
  inputElementType?: 'input' | 'textarea';
33
+ /** Handler that is called when the clear button is clicked. */
34
+ onClear?: () => void;
35
+ /** Whether the field can be emptied. */
36
+ isClearable?: boolean;
29
37
  };
30
38
  export type TextFieldProps<T = HTMLInputElement> = ExtendableProps<TextFieldBaseProps, AriaTextFieldProps<T>>;
31
39
  export type TextFieldComponentProps = <T = HTMLInputElement>(props: TextFieldProps<T>) => ReactElement | null;
@@ -2,6 +2,6 @@ import type { ComponentRef, HTMLAttributes, ReactNode, Ref } from 'react';
2
2
  export type TextareaProps = {
3
3
  children?: ReactNode;
4
4
  value?: string | number | readonly string[];
5
- ref?: Ref<HTMLTextAreaElement>;
5
+ ref?: Ref<HTMLTextAreaElement | HTMLInputElement>;
6
6
  } & HTMLAttributes<HTMLInputElement | HTMLTextAreaElement>;
7
7
  export type TextareaRef = ComponentRef<'textarea'>;
package/dist/index.d.ts CHANGED
@@ -35,6 +35,7 @@ export * from '@react-aria/combobox';
35
35
  export * from '@react-stately/combobox';
36
36
  export * from '@react-aria/toast';
37
37
  export * from '@react-stately/toast';
38
+ export * from '@react-aria/breadcrumbs';
38
39
  export type { CalendarProps, CalendarAria, CalendarGridAria, CalendarCellAria, AriaCalendarProps, AriaCalendarCellProps, AriaCalendarGridProps, } from '@react-aria/calendar';
39
40
  export { useCalendar, useCalendarCell, useCalendarGrid, } from '@react-aria/calendar';
40
41
  export * from '@react-stately/calendar';
package/dist/index.js CHANGED
@@ -34,6 +34,7 @@ export * from "@react-aria/combobox";
34
34
  export * from "@react-stately/combobox";
35
35
  export * from "@react-aria/toast";
36
36
  export * from "@react-stately/toast";
37
+ export * from "@react-aria/breadcrumbs";
37
38
  import { useCalendar, useCalendarCell, useCalendarGrid } from "@react-aria/calendar";
38
39
  export * from "@react-stately/calendar";
39
40
  export * from "@react-stately/form";
@@ -1,6 +1,6 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { useMemo, useContext } from "react";
3
- import { useObjectRef, mergeRefs, mergeProps } from "@koobiq/react-core";
3
+ import { isNotNil, useObjectRef, mergeRefs, mergeProps } from "@koobiq/react-core";
4
4
  const DEFAULT_SLOT = Symbol("default");
5
5
  function useRenderProps(props) {
6
6
  const {
@@ -69,7 +69,7 @@ function removeDataAttributes(props) {
69
69
  }
70
70
  function useSlottedContext(context, slot) {
71
71
  const ctx = useContext(context);
72
- if (slot === null) {
72
+ if (!isNotNil(slot)) {
73
73
  return null;
74
74
  }
75
75
  if (ctx && typeof ctx === "object" && "slots" in ctx && ctx.slots) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@koobiq/react-primitives",
3
- "version": "0.19.0",
3
+ "version": "0.21.0",
4
4
  "license": "MIT",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -24,6 +24,7 @@
24
24
  },
25
25
  "sideEffects": false,
26
26
  "dependencies": {
27
+ "@react-aria/breadcrumbs": "^3.5.29",
27
28
  "@react-aria/button": "^3.9.0",
28
29
  "@react-aria/calendar": "^3.8.3",
29
30
  "@react-aria/checkbox": "^3.16.2",
@@ -70,8 +71,8 @@
70
71
  "@react-stately/toggle": "^3.9.2",
71
72
  "@react-stately/tooltip": "^3.5.5",
72
73
  "@react-stately/tree": "^3.8.9",
73
- "@koobiq/logger": "0.19.0",
74
- "@koobiq/react-core": "0.19.0"
74
+ "@koobiq/react-core": "0.21.0",
75
+ "@koobiq/logger": "0.21.0"
75
76
  },
76
77
  "peerDependencies": {
77
78
  "react": "18.x || 19.x",
@@ -1,4 +0,0 @@
1
- import type { Context } from 'react';
2
- export declare function useSlottedContext<PROPS extends object, CONTEXT extends Context<{
3
- slots?: Record<string, any>;
4
- }>>(props: PROPS, context: CONTEXT, slot: string | undefined): PROPS;
@@ -1,11 +0,0 @@
1
- import { useContext } from "react";
2
- import { mergeProps } from "@koobiq/react-core";
3
- function useSlottedContext(props, context, slot) {
4
- const slotContext = useContext(context);
5
- if (!slot) return props;
6
- const propsContext = slotContext.slots?.[slot];
7
- return mergeProps(props, propsContext);
8
- }
9
- export {
10
- useSlottedContext
11
- };