@koobiq/react-primitives 0.8.0 → 0.9.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/Button/Button.js +5 -5
- package/dist/components/Button/types.d.ts +0 -1
- package/dist/components/Checkbox/Checkbox.js +8 -8
- package/dist/components/FieldError/FieldError.d.ts +8 -0
- package/dist/components/FieldError/FieldError.js +23 -0
- package/dist/components/FieldError/index.d.ts +1 -0
- package/dist/components/NumberField/NumberField.d.ts +1 -1
- package/dist/components/NumberField/NumberField.js +67 -49
- package/dist/components/NumberField/types.d.ts +3 -3
- package/dist/components/ProgressBar/ProgressBar.js +1 -1
- package/dist/components/Radio/RadioGroup.js +43 -19
- package/dist/components/TextField/TextField.js +10 -6
- package/dist/components/index.d.ts +1 -0
- package/dist/index.js +3 -0
- package/package.json +3 -3
|
@@ -68,11 +68,11 @@ const Button = polymorphicForwardRef(
|
|
|
68
68
|
},
|
|
69
69
|
...buttonProps,
|
|
70
70
|
...renderProps,
|
|
71
|
-
"data-hovered": isHovered,
|
|
72
|
-
"data-pressed": isPressed,
|
|
73
|
-
"data-focused": isFocused,
|
|
74
|
-
"data-disabled": isDisabled,
|
|
75
|
-
"data-focus-visible": isFocusVisible,
|
|
71
|
+
"data-hovered": isHovered || void 0,
|
|
72
|
+
"data-pressed": isPressed || void 0,
|
|
73
|
+
"data-focused": isFocused || void 0,
|
|
74
|
+
"data-disabled": isDisabled || void 0,
|
|
75
|
+
"data-focus-visible": isFocusVisible || void 0,
|
|
76
76
|
tabIndex: buttonProps.tabIndex,
|
|
77
77
|
..."tabIndex" in props && { tabIndex },
|
|
78
78
|
"aria-disabled": isLoading ? "true" : buttonProps["aria-disabled"],
|
|
@@ -47,14 +47,14 @@ const Checkbox = forwardRef(
|
|
|
47
47
|
return /* @__PURE__ */ jsxs(
|
|
48
48
|
"label",
|
|
49
49
|
{
|
|
50
|
-
"data-hovered": isHovered,
|
|
51
|
-
"data-pressed": isPressed,
|
|
52
|
-
"data-focused": isFocused,
|
|
53
|
-
"data-invalid": isInvalid,
|
|
54
|
-
"data-selected": isSelected,
|
|
55
|
-
"data-disabled": isDisabled,
|
|
56
|
-
"data-read-only": isReadOnly,
|
|
57
|
-
"data-focus-visible": isFocusVisible,
|
|
50
|
+
"data-hovered": isHovered || void 0,
|
|
51
|
+
"data-pressed": isPressed || void 0,
|
|
52
|
+
"data-focused": isFocused || void 0,
|
|
53
|
+
"data-invalid": isInvalid || void 0,
|
|
54
|
+
"data-selected": isSelected || void 0,
|
|
55
|
+
"data-disabled": isDisabled || void 0,
|
|
56
|
+
"data-read-only": isReadOnly || void 0,
|
|
57
|
+
"data-focus-visible": isFocusVisible || void 0,
|
|
58
58
|
...mergeProps(DOMProps, labelProps, renderProps),
|
|
59
59
|
ref,
|
|
60
60
|
children: [
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ComponentPropsWithRef, type ElementType } from 'react';
|
|
2
|
+
import type { ValidationResult } from '@koobiq/react-core';
|
|
3
|
+
import { type RenderProps } from '../../utils';
|
|
4
|
+
export declare const FieldErrorContext: import("react").Context<ValidationResult | null>;
|
|
5
|
+
export type FieldErrorRenderProps = ValidationResult;
|
|
6
|
+
export type FieldErrorBaseProps = RenderProps<FieldErrorRenderProps>;
|
|
7
|
+
export declare const FieldError: import("@koobiq/react-core").PolyForwardComponent<"p", FieldErrorBaseProps, ElementType>;
|
|
8
|
+
export type FieldErrorProps<As extends ElementType = 'p'> = ComponentPropsWithRef<typeof FieldError<As>>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
import { polymorphicForwardRef, isNotNil } from "@koobiq/react-core";
|
|
4
|
+
import { useRenderProps } from "../../utils/index.js";
|
|
5
|
+
import { Text } from "../Text/Text.js";
|
|
6
|
+
const FieldErrorContext = createContext(null);
|
|
7
|
+
const FieldError = polymorphicForwardRef(
|
|
8
|
+
(props, ref) => {
|
|
9
|
+
const { as = "p" } = props;
|
|
10
|
+
const validation = useContext(FieldErrorContext);
|
|
11
|
+
const renderProps = useRenderProps({
|
|
12
|
+
...props,
|
|
13
|
+
values: validation,
|
|
14
|
+
defaultChildren: validation.validationErrors.length === 0 ? void 0 : validation.validationErrors.join(" ")
|
|
15
|
+
});
|
|
16
|
+
return isNotNil(renderProps.children) && validation.isInvalid ? /* @__PURE__ */ jsx(Text, { as, slot: "errorMessage", ...renderProps, ref, children: renderProps.children }) : null;
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
FieldError.displayName = "FieldError";
|
|
20
|
+
export {
|
|
21
|
+
FieldError,
|
|
22
|
+
FieldErrorContext
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './FieldError';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const NumberField: import("react").ForwardRefExoticComponent<Omit<import("@react-types/numberfield").AriaNumberFieldProps
|
|
1
|
+
export declare const NumberField: import("react").ForwardRefExoticComponent<Omit<import("@react-types/numberfield").AriaNumberFieldProps & Pick<Omit<import("react").DetailedHTMLProps<import("react").InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref">, "form" | "name" | "disabled">, keyof import("../..").RenderProps<import("./types").NumberFieldRenderProps>> & import("../..").RenderProps<import("./types").NumberFieldRenderProps> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef, useRef } from "react";
|
|
4
4
|
import { filterDOMProps } from "@koobiq/react-core";
|
|
5
|
+
import { useLocale } from "@react-aria/i18n";
|
|
6
|
+
import { useNumberField } from "@react-aria/numberfield";
|
|
7
|
+
import { useNumberFieldState } from "@react-stately/numberfield";
|
|
5
8
|
import { removeDataAttributes, useRenderProps, Provider } from "../../utils/index.js";
|
|
6
|
-
import { useNumberField } from "../../behaviors/useNumberField.js";
|
|
7
9
|
import { GroupContext } from "../Group/GroupContext.js";
|
|
8
10
|
import { ButtonContext } from "../Button/ButtonContext.js";
|
|
9
11
|
import { LabelContext } from "../Label/LabelContext.js";
|
|
10
12
|
import { InputContext } from "../Input/InputContext.js";
|
|
11
13
|
import { TextContext } from "../Text/TextContext.js";
|
|
14
|
+
import { FieldErrorContext } from "../FieldError/FieldError.js";
|
|
12
15
|
const NumberField = forwardRef(
|
|
13
16
|
(props, ref) => {
|
|
14
|
-
const { isDisabled, isReadOnly, isRequired
|
|
17
|
+
const { isDisabled, isReadOnly, isRequired } = props;
|
|
15
18
|
const inputRef = useRef(null);
|
|
19
|
+
const { locale } = useLocale();
|
|
20
|
+
const state = useNumberFieldState({ ...props, locale });
|
|
16
21
|
const {
|
|
17
22
|
labelProps,
|
|
18
23
|
inputProps,
|
|
@@ -20,64 +25,77 @@ const NumberField = forwardRef(
|
|
|
20
25
|
descriptionProps,
|
|
21
26
|
errorMessageProps,
|
|
22
27
|
incrementButtonProps,
|
|
23
|
-
decrementButtonProps
|
|
24
|
-
|
|
28
|
+
decrementButtonProps,
|
|
29
|
+
...validation
|
|
30
|
+
} = useNumberField(removeDataAttributes(props), state, inputRef);
|
|
25
31
|
const DOMProps = filterDOMProps(props);
|
|
26
32
|
delete DOMProps.id;
|
|
27
33
|
const renderProps = useRenderProps({
|
|
28
34
|
...props,
|
|
29
35
|
values: {
|
|
30
|
-
isInvalid: isInvalid || false,
|
|
36
|
+
isInvalid: validation.isInvalid || false,
|
|
31
37
|
isDisabled: isDisabled || false,
|
|
32
38
|
isReadonly: isReadOnly || false,
|
|
33
39
|
isRequired: isRequired || false
|
|
34
40
|
}
|
|
35
41
|
});
|
|
36
|
-
return /* @__PURE__ */
|
|
37
|
-
|
|
42
|
+
return /* @__PURE__ */ jsxs(
|
|
43
|
+
Provider,
|
|
38
44
|
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
ButtonContext,
|
|
55
|
-
{
|
|
56
|
-
slots: {
|
|
57
|
-
increment: {
|
|
58
|
-
...incrementButtonProps,
|
|
59
|
-
disabled: incrementButtonProps.isDisabled
|
|
60
|
-
},
|
|
61
|
-
decrement: {
|
|
62
|
-
...decrementButtonProps,
|
|
63
|
-
disabled: decrementButtonProps.isDisabled
|
|
64
|
-
}
|
|
65
|
-
}
|
|
45
|
+
values: [
|
|
46
|
+
[LabelContext, labelProps],
|
|
47
|
+
[InputContext, { ...inputProps, ref: inputRef }],
|
|
48
|
+
[GroupContext, groupProps],
|
|
49
|
+
[
|
|
50
|
+
ButtonContext,
|
|
51
|
+
{
|
|
52
|
+
slots: {
|
|
53
|
+
increment: {
|
|
54
|
+
...incrementButtonProps,
|
|
55
|
+
disabled: incrementButtonProps.isDisabled
|
|
56
|
+
},
|
|
57
|
+
decrement: {
|
|
58
|
+
...decrementButtonProps,
|
|
59
|
+
disabled: decrementButtonProps.isDisabled
|
|
66
60
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
TextContext,
|
|
66
|
+
{
|
|
67
|
+
slots: {
|
|
68
|
+
description: descriptionProps,
|
|
69
|
+
errorMessage: errorMessageProps
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
],
|
|
73
|
+
[FieldErrorContext, validation]
|
|
74
|
+
],
|
|
75
|
+
children: [
|
|
76
|
+
/* @__PURE__ */ jsx(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
...DOMProps,
|
|
80
|
+
...renderProps,
|
|
81
|
+
"data-invalid": validation.isInvalid || void 0,
|
|
82
|
+
"data-readonly": isReadOnly || void 0,
|
|
83
|
+
"data-required": isRequired || void 0,
|
|
84
|
+
"data-disabled": isDisabled || void 0,
|
|
85
|
+
ref
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
props.name && /* @__PURE__ */ jsx(
|
|
89
|
+
"input",
|
|
90
|
+
{
|
|
91
|
+
type: "hidden",
|
|
92
|
+
name: props.name,
|
|
93
|
+
form: props.form,
|
|
94
|
+
value: Number.isNaN(state.numberValue) ? "" : state.numberValue,
|
|
95
|
+
disabled: props.isDisabled || void 0
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
]
|
|
81
99
|
}
|
|
82
100
|
);
|
|
83
101
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { ComponentRef } from 'react';
|
|
1
|
+
import type { ComponentPropsWithoutRef, ComponentRef } from 'react';
|
|
2
2
|
import type { ExtendableProps } from '@koobiq/react-core';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AriaNumberFieldProps } from '@react-aria/numberfield';
|
|
4
4
|
import type { RenderProps } from '../../utils';
|
|
5
5
|
export type NumberFieldRenderProps = {
|
|
6
6
|
/**
|
|
@@ -25,6 +25,6 @@ export type NumberFieldRenderProps = {
|
|
|
25
25
|
isRequired: boolean;
|
|
26
26
|
};
|
|
27
27
|
type NumberFieldBaseProps = RenderProps<NumberFieldRenderProps>;
|
|
28
|
-
export type NumberFieldProps = ExtendableProps<NumberFieldBaseProps,
|
|
28
|
+
export type NumberFieldProps = ExtendableProps<NumberFieldBaseProps, AriaNumberFieldProps & Pick<ComponentPropsWithoutRef<'input'>, 'name' | 'form' | 'disabled'>>;
|
|
29
29
|
export type NumberFieldRef = ComponentRef<'div'>;
|
|
30
30
|
export {};
|
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { filterDOMProps } from "@koobiq/react-core";
|
|
5
|
+
import { removeDataAttributes, useRenderProps, Provider } from "../../utils/index.js";
|
|
5
6
|
import { useRadioGroupState } from "../../behaviors/useRadioGroupState.js";
|
|
6
7
|
import { useRadioGroup } from "../../behaviors/useRadioGroup.js";
|
|
8
|
+
import { FieldErrorContext } from "../FieldError/FieldError.js";
|
|
7
9
|
import { RadioContext } from "./RadioContext.js";
|
|
8
10
|
import { LabelContext } from "../Label/LabelContext.js";
|
|
9
11
|
import { TextContext } from "../Text/TextContext.js";
|
|
10
12
|
const RadioGroup = forwardRef(
|
|
11
13
|
(props, ref) => {
|
|
12
14
|
const state = useRadioGroupState(props);
|
|
13
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
radioGroupProps,
|
|
17
|
+
labelProps,
|
|
18
|
+
descriptionProps,
|
|
19
|
+
errorMessageProps,
|
|
20
|
+
...validation
|
|
21
|
+
} = useRadioGroup(removeDataAttributes(props), state);
|
|
14
22
|
const renderProps = useRenderProps({
|
|
15
23
|
...props,
|
|
16
24
|
values: {
|
|
@@ -22,25 +30,41 @@ const RadioGroup = forwardRef(
|
|
|
22
30
|
state
|
|
23
31
|
}
|
|
24
32
|
});
|
|
25
|
-
|
|
26
|
-
|
|
33
|
+
const DOMProps = filterDOMProps(props);
|
|
34
|
+
delete DOMProps.id;
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"div",
|
|
27
37
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
...DOMProps,
|
|
39
|
+
"data-invalid": validation.isInvalid || void 0,
|
|
40
|
+
"data-readonly": state.isInvalid || void 0,
|
|
41
|
+
"data-required": state.isRequired || void 0,
|
|
42
|
+
"data-disabled": state.isDisabled || void 0,
|
|
43
|
+
...radioGroupProps,
|
|
44
|
+
...renderProps,
|
|
45
|
+
ref,
|
|
46
|
+
children: /* @__PURE__ */ jsx(
|
|
47
|
+
Provider,
|
|
48
|
+
{
|
|
49
|
+
values: [
|
|
50
|
+
[RadioContext, state],
|
|
51
|
+
[LabelContext, labelProps],
|
|
52
|
+
[
|
|
53
|
+
TextContext,
|
|
54
|
+
{
|
|
55
|
+
slots: {
|
|
56
|
+
description: descriptionProps,
|
|
57
|
+
errorMessage: errorMessageProps
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
],
|
|
61
|
+
[FieldErrorContext, validation]
|
|
62
|
+
],
|
|
63
|
+
children: renderProps.children
|
|
64
|
+
}
|
|
65
|
+
)
|
|
42
66
|
}
|
|
43
|
-
)
|
|
67
|
+
);
|
|
44
68
|
}
|
|
45
69
|
);
|
|
46
70
|
RadioGroup.displayName = "RadioGroup";
|
|
@@ -8,17 +8,20 @@ import { InputContext } from "../Input/InputContext.js";
|
|
|
8
8
|
import { TextareaContext } from "../Textarea/TextareaContext.js";
|
|
9
9
|
import { LabelContext } from "../Label/LabelContext.js";
|
|
10
10
|
import { TextContext } from "../Text/TextContext.js";
|
|
11
|
+
import { FieldErrorContext } from "../FieldError/FieldError.js";
|
|
11
12
|
function TextFieldRender(props, ref) {
|
|
12
13
|
const { isDisabled, isReadOnly, isRequired } = props;
|
|
13
14
|
const inputRef = useRef(null);
|
|
14
15
|
const {
|
|
15
|
-
isInvalid,
|
|
16
16
|
labelProps,
|
|
17
17
|
inputProps,
|
|
18
18
|
descriptionProps,
|
|
19
|
-
errorMessageProps
|
|
19
|
+
errorMessageProps,
|
|
20
|
+
...validation
|
|
20
21
|
} = useTextField(
|
|
21
|
-
{
|
|
22
|
+
{
|
|
23
|
+
...removeDataAttributes(props)
|
|
24
|
+
},
|
|
22
25
|
inputRef
|
|
23
26
|
);
|
|
24
27
|
const DOMProps = filterDOMProps(props);
|
|
@@ -26,7 +29,7 @@ function TextFieldRender(props, ref) {
|
|
|
26
29
|
const renderProps = useRenderProps({
|
|
27
30
|
...props,
|
|
28
31
|
values: {
|
|
29
|
-
isInvalid: isInvalid || false,
|
|
32
|
+
isInvalid: validation.isInvalid || false,
|
|
30
33
|
isDisabled: isDisabled || false,
|
|
31
34
|
isReadOnly: isReadOnly || false,
|
|
32
35
|
isRequired: isRequired || false
|
|
@@ -37,7 +40,7 @@ function TextFieldRender(props, ref) {
|
|
|
37
40
|
{
|
|
38
41
|
...DOMProps,
|
|
39
42
|
...renderProps,
|
|
40
|
-
"data-invalid": isInvalid || void 0,
|
|
43
|
+
"data-invalid": validation.isInvalid || void 0,
|
|
41
44
|
"data-readonly": isReadOnly || void 0,
|
|
42
45
|
"data-required": isRequired || void 0,
|
|
43
46
|
"data-disabled": isDisabled || void 0,
|
|
@@ -57,7 +60,8 @@ function TextFieldRender(props, ref) {
|
|
|
57
60
|
errorMessage: errorMessageProps
|
|
58
61
|
}
|
|
59
62
|
}
|
|
60
|
-
]
|
|
63
|
+
],
|
|
64
|
+
[FieldErrorContext, validation]
|
|
61
65
|
],
|
|
62
66
|
children: renderProps.children
|
|
63
67
|
}
|
package/dist/index.js
CHANGED
|
@@ -63,10 +63,13 @@ import { TextareaContext, useTextareaContext } from "./components/Textarea/Texta
|
|
|
63
63
|
import { ProgressBar } from "./components/ProgressBar/ProgressBar.js";
|
|
64
64
|
import { TextField } from "./components/TextField/TextField.js";
|
|
65
65
|
import { NumberField } from "./components/NumberField/NumberField.js";
|
|
66
|
+
import { FieldError, FieldErrorContext } from "./components/FieldError/FieldError.js";
|
|
66
67
|
export {
|
|
67
68
|
Button,
|
|
68
69
|
ButtonContext,
|
|
69
70
|
Checkbox,
|
|
71
|
+
FieldError,
|
|
72
|
+
FieldErrorContext,
|
|
70
73
|
Group,
|
|
71
74
|
GroupContext,
|
|
72
75
|
Input,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@koobiq/react-primitives",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"@react-stately/toggle": "^3.7.0",
|
|
65
65
|
"@react-stately/tooltip": "^3.5.5",
|
|
66
66
|
"@react-stately/tree": "^3.8.9",
|
|
67
|
-
"@koobiq/logger": "0.
|
|
68
|
-
"@koobiq/react-core": "0.
|
|
67
|
+
"@koobiq/logger": "0.9.0",
|
|
68
|
+
"@koobiq/react-core": "0.9.0"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"react": "18.x || 19.x",
|