diff --git a/.changeset/friendly-books-compare.md b/.changeset/friendly-books-compare.md
new file mode 100644
index 00000000..4da7a222
--- /dev/null
+++ b/.changeset/friendly-books-compare.md
@@ -0,0 +1,5 @@
+---
+'@cube-dev/ui-kit': minor
+---
+
+Add casting property to Field component to cast Field value to different type that input allows
diff --git a/src/components/forms/FileInput/FileInput.tsx b/src/components/forms/FileInput/FileInput.tsx
index de69117e..9e9466e0 100644
--- a/src/components/forms/FileInput/FileInput.tsx
+++ b/src/components/forms/FileInput/FileInput.tsx
@@ -22,7 +22,7 @@ import {
tasty,
} from '../../../tasty';
import { FieldBaseProps } from '../../../shared';
-import { FieldWrapper } from '../FieldWrapper';
+import { wrapWithField } from '../wrapper';
import type { AriaTextFieldProps } from '@react-types/textfield';
@@ -135,6 +135,8 @@ function extractContents(element, callback) {
}
function FileInput(props: CubeFileInputProps, ref) {
+ props = useProviderProps(props);
+
let {
id,
name,
@@ -163,11 +165,14 @@ function FileInput(props: CubeFileInputProps, ref) {
type = 'file',
inputProps,
...otherProps
- } = useProviderProps(props);
+ } = props;
+
const [value, setValue] = useState();
const [dragHover, setDragHover] = useState(false);
+
let domRef = useRef(null);
let defaultInputRef = useRef(null);
+
inputRef = inputRef || defaultInputRef;
let styles = extractStyles(otherProps, CONTAINER_STYLES);
@@ -247,31 +252,10 @@ function FileInput(props: CubeFileInputProps, ref) {
);
- return (
-
- );
+ return wrapWithField(fileInput, domRef, {
+ ...props,
+ styles,
+ });
}
/**
diff --git a/src/components/forms/Form/ComplexForm.stories.tsx b/src/components/forms/Form/ComplexForm.stories.tsx
index 695a529e..0cee8fdf 100644
--- a/src/components/forms/Form/ComplexForm.stories.tsx
+++ b/src/components/forms/Form/ComplexForm.stories.tsx
@@ -36,43 +36,43 @@ export default {
parameters: { controls: { exclude: baseProps } },
};
-const UnknownSubmitErrorTemplate: StoryFn = (args) => {
- const [form] = Form.useForm();
-
- return (
-
- );
-};
+// const UnknownSubmitErrorTemplate: StoryFn = (args) => {
+// const [form] = Form.useForm();
+//
+// return (
+//
+// );
+// };
const CustomSubmitErrorTemplate: StoryFn = (args) => {
const [form] = Form.useForm();
@@ -387,8 +387,8 @@ ErrorMessage.play = CustomErrorMessage.play = async ({ canvasElement }) => {
await waitFor(() => expect(canvas.getByRole('alert')).toBeInTheDocument());
};
-export const UnknownErrorMessage = UnknownSubmitErrorTemplate.bind({});
-
+// export const UnknownErrorMessage = UnknownSubmitErrorTemplate.bind({});
+//
// UnknownErrorMessage.play = async ({ canvasElement }) => {
// const canvas = within(canvasElement);
// const button = await canvas.getByRole('button');
diff --git a/src/components/forms/Form/types.ts b/src/components/forms/Form/types.ts
index aed693f4..1c2189c3 100644
--- a/src/components/forms/Form/types.ts
+++ b/src/components/forms/Form/types.ts
@@ -8,7 +8,7 @@ export type CubeFieldData = {
readonly name: Name;
errors: ReactNode[];
value?: Value;
- inputValue?: Value;
+ inputValue?: Value | string | undefined | null;
touched?: boolean;
rules?: any[];
validating?: boolean;
diff --git a/src/components/forms/Form/use-field/use-field-props.tsx b/src/components/forms/Form/use-field/use-field-props.tsx
index 5061d938..b8ec2868 100644
--- a/src/components/forms/Form/use-field/use-field-props.tsx
+++ b/src/components/forms/Form/use-field/use-field-props.tsx
@@ -77,7 +77,6 @@ export function useFieldProps<
// eslint-disable-next-line react-hooks/rules-of-hooks
const onBlurChained = useChainedCallback(
field?.onBlur,
- // TODO: remove type casting after updating to typescipt@4.9
'onBlur' in props ? (props as any).onBlur : undefined,
);
diff --git a/src/components/forms/Form/use-field/use-field.ts b/src/components/forms/Form/use-field/use-field.ts
index e0cc1794..4d13db04 100644
--- a/src/components/forms/Form/use-field/use-field.ts
+++ b/src/components/forms/Form/use-field/use-field.ts
@@ -172,11 +172,13 @@ export function useField>(
}
});
+ let inputValue = field?.inputValue;
+
return useMemo(
() => ({
id: fieldId,
name: fieldName,
- value: field?.inputValue,
+ value: inputValue,
validateTrigger,
form,
field,
diff --git a/src/components/forms/Slider/SliderBase.tsx b/src/components/forms/Slider/SliderBase.tsx
index 5cebb9b3..20bf29fc 100644
--- a/src/components/forms/Slider/SliderBase.tsx
+++ b/src/components/forms/Slider/SliderBase.tsx
@@ -4,10 +4,11 @@ import { FocusableRef } from '@react-types/shared';
import { SliderState, useSliderState } from 'react-stately';
import { useSlider, useNumberFormatter } from 'react-aria';
-import { FieldWrapper } from '../FieldWrapper';
import { extractStyles, OUTER_STYLES, tasty } from '../../../tasty';
import { useFieldProps, useFormProps } from '../Form';
import { Text } from '../../content/Text';
+import { mergeProps } from '../../../utils/react';
+import { wrapWithField } from '../wrapper';
import { SliderControlsElement, SliderElement } from './elements';
import { CubeSliderBaseProps } from './types';
@@ -211,27 +212,17 @@ function SliderBase(
styles = extractStyles(otherProps, OUTER_STYLES, styles);
- return (
-
+ extra,
+ },
+ { labelProps },
+ ),
);
}
diff --git a/src/components/forms/wrapper.tsx b/src/components/forms/wrapper.tsx
index bef1ced6..47527e2c 100644
--- a/src/components/forms/wrapper.tsx
+++ b/src/components/forms/wrapper.tsx
@@ -1,4 +1,5 @@
import { ReactElement, RefObject } from 'react';
+import { FocusableRef } from '@react-types/shared';
import { FieldBaseProps, FormBaseProps } from '../../shared';
import { BaseProps, Styles } from '../../tasty';
@@ -11,7 +12,7 @@ interface WrapWithFieldProps extends FieldBaseProps, BaseProps, FormBaseProps {
export function wrapWithField(
component: ReactElement,
- ref: RefObject,
+ ref: RefObject | FocusableRef,
props: T,
) {
let {
@@ -20,13 +21,14 @@ export function wrapWithField(
labelPosition = 'top',
labelStyles,
isRequired,
+ isDisabled,
necessityIndicator,
- necessityLabel,
- validationState,
message,
+ messageStyles,
description,
- isDisabled,
+ validationState,
labelProps,
+ fieldProps,
requiredMark = true,
tooltip,
isHidden,
@@ -38,23 +40,24 @@ export function wrapWithField(
return (
(
qa,
label,
extra,
- labelPosition = 'top',
labelStyles,
isRequired,
necessityIndicator,
@@ -174,7 +173,6 @@ export const ComboBox = forwardRef(function ComboBox(
autoComplete = 'off',
direction = 'bottom',
shouldFlip = true,
- requiredMark = true,
menuTrigger = 'input',
suffixPosition = 'before',
loadingState,
@@ -400,31 +398,14 @@ export const ComboBox = forwardRef(function ComboBox(
);
- return (
-
+ return wrapWithField, 'children'>>(
+ comboBoxField,
+ ref,
+ mergeProps({ ...props, styles }, { labelProps }),
);
}) as unknown as ((
props: CubeComboBoxProps & { ref?: ForwardedRef },
-) => JSX.Element) & { Item: typeof Item };
+) => ReactElement) & { Item: typeof Item };
ComboBox.Item = Item;
Object.defineProperty(ComboBox, 'cubeInputType', {
diff --git a/src/components/pickers/Select/Select.tsx b/src/components/pickers/Select/Select.tsx
index a7c82a51..2abbb9eb 100644
--- a/src/components/pickers/Select/Select.tsx
+++ b/src/components/pickers/Select/Select.tsx
@@ -20,8 +20,8 @@ import {
useOverlayPosition,
useSelect,
} from 'react-aria';
-import { DOMRef } from '@react-types/shared';
import styled from 'styled-components';
+import { DOMRef } from '@react-types/shared';
import { useFieldProps, useFormProps } from '../../forms';
import { useProviderProps } from '../../../provider';
@@ -37,13 +37,13 @@ import {
tasty,
} from '../../../tasty';
import { useFocus } from '../../../utils/react/interactions';
-import { FieldWrapper } from '../../forms/FieldWrapper';
import { OverlayWrapper } from '../../overlays/OverlayWrapper';
import { FieldBaseProps } from '../../../shared';
import { getOverlayTransitionCSS } from '../../../utils/transitions';
import { mergeProps, useCombinedRefs } from '../../../utils/react';
import { DEFAULT_INPUT_STYLES, INPUT_WRAPPER_STYLES } from '../../forms';
import { DEFAULT_BUTTON_STYLES } from '../../actions';
+import { wrapWithField } from '../../forms/wrapper';
import { LoadingIcon } from '../../../icons';
import { InvalidIcon } from '../../shared/InvalidIcon';
import { ValidIcon } from '../../shared/ValidIcon';
@@ -296,7 +296,6 @@ function Select(
label,
extra,
icon,
- labelPosition = 'top',
labelStyles,
isRequired,
necessityIndicator,
@@ -320,7 +319,6 @@ function Select(
description,
direction = 'bottom',
shouldFlip = true,
- requiredMark = true,
placeholder,
tooltip,
size,
@@ -471,28 +469,16 @@ function Select(
);
- return (
- , 'children'>>(
+ selectField,
+ ref,
+ mergeProps(
+ {
+ ...props,
styles,
- isRequired,
- labelStyles,
- necessityIndicator,
- labelProps,
- isDisabled,
- validationState,
- message,
- description,
- requiredMark,
- tooltip,
- labelSuffix,
- Component: selectField,
- ref: ref,
- }}
- />
+ },
+ { labelProps },
+ ),
);
}
diff --git a/src/shared/form.ts b/src/shared/form.ts
index 324306a5..e096e360 100644
--- a/src/shared/form.ts
+++ b/src/shared/form.ts
@@ -57,6 +57,8 @@ export interface FieldBaseProps extends FormBaseProps {
labelStyles?: Styles;
/** Whether the field is inside the form. Private field. */
insideForm?: boolean;
+ fieldProps?: Props;
+ messageStyles?: Styles;
}
export interface FormBaseProps {