From 56066fe1aa2604ae4576b99e71051478c7f1d48f Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Fri, 10 Apr 2026 17:07:08 +0200 Subject: [PATCH] chore: remove formik dependency (#44744) ## Problem Now that all forms have been migrated to `react-hook-form`, we can remove `formik` as well as some unused deprecated components ## Summary by CodeRabbit * **Chores** * Removed formik dependency from the UI package. * Removed Form and InputNumber components and their public re-exports. * Removed FormContext and the form hook exports. * Simplified multiple components (Input, Checkbox, Radio, Select, Toggle, Listbox) by removing form-context integration. * Removed InputNumber styling and theme configuration. --- packages/ui/index.tsx | 2 - packages/ui/package.json | 1 - .../ui/src/components/Checkbox/Checkbox.tsx | 26 --- packages/ui/src/components/Form/Form.tsx | 104 ---------- .../ui/src/components/Form/FormContext.tsx | 51 ----- packages/ui/src/components/Form/index.tsx | 1 - packages/ui/src/components/Input/Input.tsx | 80 +------- .../InputNumber/InputNumber.module.css | 134 ------------ .../components/InputNumber/InputNumber.tsx | 194 ------------------ .../ui/src/components/InputNumber/index.ts | 1 - .../ui/src/components/Listbox/Listbox2.tsx | 45 +--- packages/ui/src/components/Radio/Radio.tsx | 38 +--- packages/ui/src/components/Select/Select.tsx | 33 +-- packages/ui/src/components/Toggle/Toggle.tsx | 44 ---- packages/ui/src/lib/theme/defaultTheme.ts | 44 ---- pnpm-lock.yaml | 51 +---- 16 files changed, 9 insertions(+), 840 deletions(-) delete mode 100644 packages/ui/src/components/Form/Form.tsx delete mode 100644 packages/ui/src/components/Form/FormContext.tsx delete mode 100644 packages/ui/src/components/Form/index.tsx delete mode 100644 packages/ui/src/components/InputNumber/InputNumber.module.css delete mode 100644 packages/ui/src/components/InputNumber/InputNumber.tsx delete mode 100644 packages/ui/src/components/InputNumber/index.ts diff --git a/packages/ui/index.tsx b/packages/ui/index.tsx index 277d28b6cc9..efbc29f3f1c 100644 --- a/packages/ui/index.tsx +++ b/packages/ui/index.tsx @@ -40,10 +40,8 @@ export * from './src/components/Select' export * from './src/components/Listbox' export * from './src/components/Checkbox' export * from './src/components/Input' -export * from './src/components/InputNumber' export * from './src/components/Radio' export * from './src/components/Toggle' -export * from './src/components/Form' export * from './src/components/ExpandingTextArea' // layout diff --git a/packages/ui/package.json b/packages/ui/package.json index 16c1fb1287d..4c753880812 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -54,7 +54,6 @@ "cmdk": "^1.1.1", "color": "^4.2.3", "date-fns": "^2.30.0", - "formik": "^2.2.9", "framer-motion": "^11.0.3", "input-otp": "^1.2.3", "lodash": "catalog:", diff --git a/packages/ui/src/components/Checkbox/Checkbox.tsx b/packages/ui/src/components/Checkbox/Checkbox.tsx index f98fafb97ce..e87a0f39d00 100644 --- a/packages/ui/src/components/Checkbox/Checkbox.tsx +++ b/packages/ui/src/components/Checkbox/Checkbox.tsx @@ -4,7 +4,6 @@ import React from 'react' import { FormLayout } from '../../lib/Layout/FormLayout/FormLayout' import styleHandler from '../../lib/theme/styleHandler' -import { useFormContext } from '../Form/FormContext' import CheckboxStyles from './Checkbox.module.css' import { CheckboxContext } from './CheckboxContext' @@ -109,16 +108,12 @@ export function Checkbox({ afterLabel, beforeLabel, description, - checked, value, onChange, - onBlur, size = 'medium', disabled = false, ...props }: InputProps) { - const { formContextOnChange, values, handleBlur } = useFormContext() - const __styles = styleHandler('checkbox') return ( @@ -143,12 +138,6 @@ export function Checkbox({ // if that fails, use the id const markupName = name ? name : markupId - // check if checkbox checked is true or false - // if neither true or false the checkbox will rely on native control - let active = checked ?? undefined - - // if (values && !value) value = values[id || name] - let containerClasses = [__styles.container] function onInputChange(e: React.ChangeEvent) { @@ -156,23 +145,10 @@ export function Checkbox({ if (parentCallback) parentCallback(e) // '`onChange` callback for this component if (onChange) onChange(e) - // update form - if (formContextOnChange) formContextOnChange(e) } if (className) containerClasses.push(className) - if (values && checked === undefined) active = values[id || name] - - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) { - setTimeout(() => { - handleBlur(e) - }, 100) - } - if (onBlur) onBlur(e) - } - return (
, Partial FormikConfig { -interface Props extends Omit, 'validateOnMount' | 'validateOnChange'> { - children: any - handleIsSubmitting?: any - handleIsValidating?: any - name?: string - id?: string - className?: string - style?: React.CSSProperties -} - -function errorReducer(state: any, action: any) { - if (!action.error) { - const payload = state - delete payload[action.key] - return payload - } - if (action) { - return { - ...state, - [action.key]: action.error, - } - } else { - throw new Error() - } -} - -/** - * @deprecated Use `import { Form_shadcn_ } from "ui"` instead - */ -export default function Form({ validate, ...props }: Props) { - const [fieldLevelErrors, dispatchErrors] = useReducer(errorReducer, null) - - function handleFieldLevelValidation(key: any, error: string) { - dispatchErrors({ key, error }) - } - - const formik = useFormik({ - validateOnBlur: true, - ...props, - validationSchema: props.validationSchema, - initialValues: props.initialValues, - onSubmit: props.onSubmit, - validate: - validate || - function () { - return fieldLevelErrors - }, - }) - - // console.log('values', formik.values) - // console.log('errors', formik.errors) - // console.log('touched', formik.touched) - - return ( -
- - {props.children({ - /** map of field names to specific error for that field */ - errors: formik.errors, // errors, - // /** map of field names to whether the field has been touched */ - touched: formik.touched, - /** whether the form is currently submitting */ - isSubmitting: formik.isSubmitting, - /** whether the form is currently validating (prior to submission) */ - isValidating: formik.isValidating, - /** Number of times user tried to submit the form */ - submitCount: formik.submitCount, - /** Initial values of form */ - initialValues: formik.initialValues, - /** Current values of form */ - values: formik.values, - /** Resets the form back to initialValues */ - handleReset: formik.handleReset, - /** Resets the form with custom values */ - resetForm: formik.resetForm, - /** Manually sets a fields value */ - setFieldValue: formik.setFieldValue, - })} - -
- ) -} diff --git a/packages/ui/src/components/Form/FormContext.tsx b/packages/ui/src/components/Form/FormContext.tsx deleted file mode 100644 index 3049bd3a598..00000000000 --- a/packages/ui/src/components/Form/FormContext.tsx +++ /dev/null @@ -1,51 +0,0 @@ -'use client' - -import React, { createContext, useContext } from 'react' - -interface ContextProps { - formContextOnChange: any - values: any - errors: any - handleBlur: ((e: React.FocusEvent) => void) | null - touched: any - fieldLevelValidation: any -} - -interface Provider extends ContextProps { - children?: React.ReactNode -} - -// Make sure the shape of the default value passed to -// createContext matches the shape that the consumers expect! -const FormContext = createContext({ - formContextOnChange: null, - values: null, - errors: null, - handleBlur: null, - touched: null, - fieldLevelValidation: null, -}) - -export const FormContextProvider = (props: Provider) => { - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = props - - const value = { - formContextOnChange: formContextOnChange, - values: values, - errors: errors, - handleBlur: handleBlur, - touched: touched, - fieldLevelValidation: fieldLevelValidation, - } - - return {props.children} -} - -// context helper to avoid using a consumer component -export const useFormContext = () => { - const context = useContext(FormContext) - if (context === undefined) { - throw new Error(`useFormContextOnChange must be used within a FormContextProvider.`) - } - return context -} diff --git a/packages/ui/src/components/Form/index.tsx b/packages/ui/src/components/Form/index.tsx deleted file mode 100644 index dda8db37e4a..00000000000 --- a/packages/ui/src/components/Form/index.tsx +++ /dev/null @@ -1 +0,0 @@ -export { default as Form } from './Form' diff --git a/packages/ui/src/components/Input/Input.tsx b/packages/ui/src/components/Input/Input.tsx index ec30cdcaf42..8323feab7ce 100644 --- a/packages/ui/src/components/Input/Input.tsx +++ b/packages/ui/src/components/Input/Input.tsx @@ -1,7 +1,7 @@ 'use client' import { Copy } from 'lucide-react' -import React, { useEffect, useState } from 'react' +import React, { useState } from 'react' import { HIDDEN_PLACEHOLDER } from '../../lib/constants' import { FormLayout } from '../../lib/Layout/FormLayout/FormLayout' @@ -11,7 +11,6 @@ import styleHandler from '../../lib/theme/styleHandler' import { copyToClipboard } from '../../lib/utils' import { cn } from '../../lib/utils/cn' import { Button } from '../Button' -import { useFormContext } from '../Form/FormContext' export interface Props extends Omit< React.InputHTMLAttributes, @@ -62,8 +61,6 @@ function Input({ beforeLabel, labelOptional, layout, - onChange, - onBlur, onCopy, placeholder, type = 'text', @@ -81,42 +78,6 @@ function Input({ const __styles = styleHandler('input') - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = - useFormContext() - - if (values && !value) value = values[id || name] - - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) { - setTimeout(() => { - handleBlur(e) - }, 100) - } - if (onBlur) onBlur(e) - } - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id] ? error : undefined - } - - function onInputChange(e: React.ChangeEvent) { - // console.log('input event', e) - if (onChange) onChange(e) - // update form - if (formContextOnChange) formContextOnChange(e) - // run field level validation - if (validation) fieldLevelValidation(id, validation(e.target.value)) - } - - useEffect(() => { - if (validation) fieldLevelValidation(id, validation(value)) - }, []) - - // useEffect(() => { - // error = touched && touched[id] ? error : undefined - // }, [errors, touched]) - function _onCopy(value: any) { copyToClipboard(value, () => { setCopyLabel('Copied') @@ -163,8 +124,6 @@ function Input({ disabled={disabled} id={id} name={name} - onChange={onInputChange} - onBlur={handleBlurEvent} onCopy={onCopy} placeholder={placeholder} ref={inputRef} @@ -235,8 +194,6 @@ function TextArea({ beforeLabel, labelOptional, layout, - onChange, - onBlur, placeholder, value, style, @@ -250,7 +207,6 @@ function TextArea({ actions, ...props }: TextAreaProps) { - const [charLength, setCharLength] = useState(0) const [copyLabel, setCopyLabel] = useState('Copy') function _onCopy(value: any) { @@ -264,38 +220,6 @@ function TextArea({ }) } - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = - useFormContext() - - if (values && !value) value = values[id || name] - - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) { - setTimeout(() => { - handleBlur(e) - }, 100) - } - if (onBlur) onBlur(e) - } - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id || name] ? error : undefined - } - - function onInputChange(e: React.ChangeEvent) { - setCharLength(e.target.value.length) - if (onChange) onChange(e) - // update form - if (formContextOnChange) formContextOnChange(e) - // run field level validation - if (validation) fieldLevelValidation(id, validation(e.target.value)) - } - - useEffect(() => { - if (validation) fieldLevelValidation(id, validation(value)) - }, []) - const __styles = styleHandler('input') let classes = [__styles.base] @@ -329,8 +253,6 @@ function TextArea({ rows={rows} cols={100} placeholder={placeholder} - onChange={onInputChange} - onBlur={handleBlurEvent} onCopy={onCopy} value={value} className={classes.join(' ')} diff --git a/packages/ui/src/components/InputNumber/InputNumber.module.css b/packages/ui/src/components/InputNumber/InputNumber.module.css deleted file mode 100644 index c9332c5c05a..00000000000 --- a/packages/ui/src/components/InputNumber/InputNumber.module.css +++ /dev/null @@ -1,134 +0,0 @@ -.sbui-inputnumber-container { - @apply relative; -} - -.sbui-inputnumber { - @apply block box-border pl-3 pr-3 py-2 w-full rounded-md shadow-sm text-sm border border-solid transition-all; - @apply bg-white text-input-value-light border-input-border-light; - @apply focus:ring-input-border-focus-light focus:border-input-border-focus-light focus:outline-none; - - @apply dark:bg-transparent dark:text-input-value-dark dark:border-input-border-dark; - @apply dark:focus:border-input-border-focus-dark dark:focus:ring-input-border-focus-dark; - - /* box-shadow: 0 0 0 2px rgba(255, 255, 255, 0); */ - font-family: inherit; - transition: box-shadow 0.3s ease-in-out; - - -moz-appearance: textfield; -} - -.sbui-inputnumber::-webkit-inner-spin-button, -.sbui-inputnumber::-webkit-outer-spin-button { - -webkit-appearance: none; - margin: 0; -} - -.sbui-inputnumber:focus { - box-shadow: 0 0 0 2px rgba(62, 207, 142, 0.1); - outline: 0; -} - -.sbui-inputnumber--error { - @apply border-red-500; -} - -.sbui-inputnumber--borderless { - @apply border-transparent shadow-none; -} - -.sbui-inputnumber-actions-container { - @apply absolute inset-y-0 right-0 pl-3 pr-1 flex items-center; -} - -.sbui-inputnumber-nav { - @apply hidden; -} - -.sbui-inputnumber:focus + .sbui-inputnumber-nav { - @apply block; -} - -.sbui-inputnumber-button { - @apply block box-border pl-3 pr-3 py-2 w-full rounded-md text-sm border border-solid; - @apply bg-transparent border-transparent; - @apply dark:text-white; - - position: relative; - cursor: pointer; - width: 21px; - text-align: center; - color: #333; - font-size: 13px; - line-height: 1.5; - padding: 0; - -webkit-transform: translateX(-100%); - transform: translateX(-100%); - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; -} - -.sbui-inputnumber-button:active { - background: #eaeaea; - background-clip: padding-box; -} - -.sbui-inputnumber-button-up { - position: absolute; - height: 50%; - top: 0; - border-radius: 0 0.375rem 0 0; - line-height: 1.6; -} - -.sbui-inputnumber-button-down { - position: absolute; - bottom: 0; - height: 50%; - border-radius: 0 0 0.375rem 0; -} - -/* - Input sizes - */ - -.sbui-inputnumber--tiny { - @apply px-2.5 py-1.5 text-xs; -} -.sbui-inputnumber--small { - @apply px-3 py-2 text-sm leading-4; -} -.sbui-inputnumber--medium { - @apply px-4 py-2 text-sm; -} -.sbui-inputnumber--large { - @apply px-4 py-2 text-base; -} -.sbui-inputnumber--xlarge { - @apply px-6 py-3 text-base; -} - -.sbui-inputnumber-nav--tiny { - height: 30px; -} -.sbui-inputnumber-nav--small { - height: 34px; -} -.sbui-inputnumber-nav--medium { - height: 38px; -} -.sbui-inputnumber-nav--large { - height: 42px; -} -.sbui-inputnumber-nav--xlarge { - height: 50px; -} -/* - Input icon - */ - -.sbui-inputnumber--with-icon { - @apply pl-7; -} diff --git a/packages/ui/src/components/InputNumber/InputNumber.tsx b/packages/ui/src/components/InputNumber/InputNumber.tsx deleted file mode 100644 index 8723e2226e5..00000000000 --- a/packages/ui/src/components/InputNumber/InputNumber.tsx +++ /dev/null @@ -1,194 +0,0 @@ -'use client' - -import React, { useEffect } from 'react' - -// import { IconChevronDown } from '../Icon/icons/IconChevronDown' -// import { IconChevronUp } from '../Icon/icons/IconChevronUp' -import { FormLayout } from '../../lib/Layout/FormLayout/FormLayout' -import InputErrorIcon from '../../lib/Layout/InputErrorIcon' -import InputIconContainer from '../../lib/Layout/InputIconContainer' -import styleHandler from '../../lib/theme/styleHandler' -import { useFormContext } from '../Form/FormContext' - -export interface Props extends Omit, 'size'> { - defaultValue?: string | number - descriptionText?: string | React.ReactNode - error?: string - icon?: any - inputRef?: React.RefObject - label?: string - afterLabel?: string - beforeLabel?: string - labelOptional?: string | React.ReactNode - actions?: React.ReactNode - layout?: 'horizontal' | 'vertical' - size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge' - validation?: (x: any) => void -} - -/** - * @deprecated Use `import { Input_shadcn_ } from "ui"` with `type="number"` instead or ./ui-patterns/data-inputs/input with `type="number"` - */ -function InputNumber({ - defaultValue, - descriptionText, - error, - icon, - inputRef, - label, - afterLabel, - beforeLabel, - labelOptional, - layout, - value = undefined, - actions, - size = 'medium', - validation, - id = '', - name = '', - ...props -}: Props) { - const __styles = styleHandler('inputNumber') - - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = - useFormContext() - - if (values && !value) value = values[id || name] - - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) handleBlur(e) - if (props.onBlur) props.onBlur(e) - } - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id || name] ? error : undefined - } - - function onInputChange(e: React.ChangeEvent) { - if (props.onChange) props.onChange(e) - // update form - if (formContextOnChange) formContextOnChange(e) - // run field level validation - if (validation) fieldLevelValidation(id, validation(e.target.value)) - } - - useEffect(() => { - if (validation) fieldLevelValidation(id, validation(value)) - }, []) - - // const inputClasses = [InputNumberStyles['sbui-inputnumber']] - let inputClasses = [__styles.base] - - // const iconUpClasses = [ - // InputNumberStyles['sbui-inputnumber-button'], - // InputNumberStyles['sbui-inputnumber-button-up'], - // ] - - // const inputRefCurrent = inputRef - // ? inputRef - // : React.createRef() - - // const iconDownClasses = [ - // InputNumberStyles['sbui-inputnumber-button'], - // InputNumberStyles['sbui-inputnumber-button-down'], - // ] - - // const iconNavClasses = [InputNumberStyles['sbui-inputnumber-nav']] - - // if (size) { - // inputClasses.push(InputNumberStyles[`sbui-inputnumber--${size}`]) - // iconNavClasses.push(InputNumberStyles[`sbui-inputnumber-nav--${size}`]) - // } - - if (error) inputClasses.push(__styles.variants.error) - if (!error) inputClasses.push(__styles.variants.standard) - if (icon) inputClasses.push(__styles.with_icon[size]) - if (size) inputClasses.push(__styles.size[size]) - if (props.disabled) inputClasses.push(__styles.disabled) - // if (borderless) - // inputClasses.push(InputNumberStyles['sbui-inputnumber--borderless']) - - // const onClickChevronUp = () => { - // inputRefCurrent.current?.stepUp() - // if (onChange) { - // inputRefCurrent.current?.dispatchEvent( - // new InputEvent('change', { - // view: window, - // bubbles: true, - // cancelable: false, - // }) - // ) - // } - // } - - // const onClickChevronDown = () => { - // inputRefCurrent.current?.stepDown() - // if (onChange) { - // inputRefCurrent.current?.dispatchEvent( - // new InputEvent('change', { - // view: window, - // bubbles: true, - // cancelable: false, - // }) - // ) - // } - // } - - return ( -
- -
- - {/*
- { - e.preventDefault() - }} - /> - { - e.preventDefault() - }} - /> -
*/} - {icon && } - {error || actions ? ( -
- {error && } - {actions && actions} -
- ) : null} -
-
-
- ) -} - -export default InputNumber diff --git a/packages/ui/src/components/InputNumber/index.ts b/packages/ui/src/components/InputNumber/index.ts deleted file mode 100644 index a3996279268..00000000000 --- a/packages/ui/src/components/InputNumber/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as InputNumber } from './InputNumber' diff --git a/packages/ui/src/components/Listbox/Listbox2.tsx b/packages/ui/src/components/Listbox/Listbox2.tsx index aa41d5ab808..f85f4ba5472 100644 --- a/packages/ui/src/components/Listbox/Listbox2.tsx +++ b/packages/ui/src/components/Listbox/Listbox2.tsx @@ -10,7 +10,6 @@ import InputErrorIcon from '../../lib/Layout/InputErrorIcon' import InputIconContainer from '../../lib/Layout/InputIconContainer' import styleHandler from '../../lib/theme/styleHandler' import { cn } from '../../lib/utils/cn' -import { useFormContext } from '../Form/FormContext' import { SelectContext } from './SelectContext' export interface Props extends Omit, 'size'> { @@ -70,24 +69,6 @@ function Listbox({ const triggerRef = useRef(null) - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = - useFormContext() - - if (values && !value) { - value = values[id || name] - defaultValue = values[id || name] - } - - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) handleBlur(e) - if (onBlur) onBlur(e) - } - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id || name] ? error : undefined - } - useEffect(() => { if (value !== undefined) { setSelected(value) @@ -146,7 +127,7 @@ function Listbox({ return } else if (defaultValue) { setSelected(defaultValue) - const node: any = findNode(selected) + const node: any = findNode(defaultValue) setSelectedNode(node?.props ? node.props : undefined) return } else { @@ -161,28 +142,6 @@ function Listbox({ function handleOnChange(value: any) { if (onChange) onChange(value) setSelected(value) - - /* - * Create change event for formik - * formik expects an input change event - */ - let event: any = {} - event.target = { - type: 'select', - name: name, - id: id, - value: value, - checked: undefined, - // outerHTML: undefined, - // options: undefined, - // multiple: undefined, - } - - // update form - // Create a new 'change' event - if (formContextOnChange) formContextOnChange(event) - // run field level validation - if (validation) fieldLevelValidation(id, validation(value)) } let selectClasses = [__styles.container, __styles.base, buttonClassName] @@ -215,7 +174,7 @@ function Listbox({ data-size={size} ref={triggerRef} className={cn(selectClasses)} - onBlur={handleBlurEvent} + onBlur={onBlur} onFocus={onFocus} name={name} id={id} diff --git a/packages/ui/src/components/Radio/Radio.tsx b/packages/ui/src/components/Radio/Radio.tsx index 19ecc83375c..c8f1842538d 100644 --- a/packages/ui/src/components/Radio/Radio.tsx +++ b/packages/ui/src/components/Radio/Radio.tsx @@ -4,7 +4,6 @@ import React, { useEffect, useState } from 'react' import { FormLayout } from '../../lib/Layout/FormLayout/FormLayout' import styleHandler from '../../lib/theme/styleHandler' -import { useFormContext } from '../Form/FormContext' import { generateUID } from './../../lib/utils/randomIdGenerator' import { RadioContext } from './RadioContext' @@ -61,40 +60,12 @@ function RadioGroup({ const __styles = styleHandler('radio') - const { - formContextOnChange, - values, - errors, - // handleBlur, - touched, - fieldLevelValidation, - } = useFormContext() - - if (values && !value) value = values[id || name] - // console.log('errors in. radio group', errors) - // console.log('values in radio group', values) - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id || name] ? error : undefined - } - - useEffect(() => { - if (validation) fieldLevelValidation(id, validation(value)) - }, []) - useEffect(() => { setActiveId(value) }, [value]) function parentCallback(e: React.ChangeEvent) { if (onChange) onChange(e) - // update form - if (formContextOnChange) { - formContextOnChange(e) - } - // run field level validation - if (validation) fieldLevelValidation(id, validation(e.target.value)) setActiveId(e.target.id) } @@ -176,13 +147,6 @@ function Radio({ const inputName = name - const { handleBlur } = useFormContext() - - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) handleBlur(e) - if (onBlur) onBlur(e) - } - return ( {({ parentCallback, type, name, activeId, parentSize }) => { @@ -251,7 +215,7 @@ function Radio({ disabled={disabled} value={value ? value : markupId} onChange={(e) => onInputChange(e)} - onBlur={handleBlurEvent} + onBlur={onBlur} /> {addOnBefore} {children || ( diff --git a/packages/ui/src/components/Select/Select.tsx b/packages/ui/src/components/Select/Select.tsx index e7ea3ad3905..8ce9d5cb1a1 100644 --- a/packages/ui/src/components/Select/Select.tsx +++ b/packages/ui/src/components/Select/Select.tsx @@ -1,12 +1,11 @@ 'use client' -import React, { useEffect } from 'react' +import React from 'react' import { FormLayout } from '../../lib/Layout/FormLayout/FormLayout' import InputErrorIcon from '../../lib/Layout/InputErrorIcon' import InputIconContainer from '../../lib/Layout/InputIconContainer' import styleHandler from '../../lib/theme/styleHandler' -import { useFormContext } from '../Form/FormContext' interface OptionProps { value: string @@ -60,8 +59,6 @@ function Select({ labelOptional, layout, name = '', - onChange, - onBlur, placeholder, required, value = undefined, @@ -72,32 +69,6 @@ function Select({ validation, ...props }: Props) { - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = - useFormContext() - - if (values && !value) value = values[id] - function handleBlurEvent(e: React.FocusEvent) { - if (handleBlur) handleBlur(e) - if (onBlur) onBlur(e) - } - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id || name] ? error : undefined - } - - function onInputChange(e: React.ChangeEvent) { - if (onChange) onChange(e) - // update form - if (formContextOnChange) formContextOnChange(e) - // run field level validation - if (validation) fieldLevelValidation(id, validation(e.target.value)) - } - - useEffect(() => { - if (validation) fieldLevelValidation(id, validation(value)) - }, []) - const __styles = styleHandler('select') let classesContainer = [__styles.container] @@ -133,8 +104,6 @@ function Select({ autoComplete={autoComplete} autoFocus={autofocus} className={classes.join(' ')} - onChange={onInputChange} - onBlur={handleBlurEvent} ref={inputRef} value={value} disabled={disabled} diff --git a/packages/ui/src/components/Toggle/Toggle.tsx b/packages/ui/src/components/Toggle/Toggle.tsx index 3093b267436..f1e9011394f 100644 --- a/packages/ui/src/components/Toggle/Toggle.tsx +++ b/packages/ui/src/components/Toggle/Toggle.tsx @@ -5,7 +5,6 @@ import React, { useEffect, useState } from 'react' import { FormLayout } from '../../lib/Layout/FormLayout/FormLayout' import styleHandler from '../../lib/theme/styleHandler' -import { useFormContext } from '../Form/FormContext' interface Props extends Omit, 'size'> { name?: string @@ -23,7 +22,6 @@ interface Props extends Omit, 'size'> { align?: 'right' | 'left' size?: 'tiny' | 'small' | 'medium' | 'large' | 'xlarge' labelLayout?: 'horizontal' | 'vertical' - validation?: (x: any) => void } /** @@ -41,23 +39,15 @@ function Toggle({ beforeLabel, labelOptional, onChange, - onBlur, defaultChecked, checked, className, align = 'left', size = 'medium', - validation, labelLayout, ...props }: Props) { const __styles = styleHandler('toggle') - - const { formContextOnChange, values, errors, handleBlur, touched, fieldLevelValidation } = - useFormContext() - - if (values && !checked) checked = values[id || name] - const [intChecked, setIntChecked] = useState((defaultChecked || checked) ?? false) // check if toggle checked is true or false @@ -68,18 +58,6 @@ function Toggle({ setIntChecked(active) }, []) - function handleBlurEvent(e: React.FocusEvent) { - setTimeout(() => { - if (handleBlur) handleBlur(e) - }, 100) - if (onBlur) onBlur(e) - } - - if (!error) { - if (errors && !error) error = errors[id || name] - error = touched && touched[id || name] ? error : undefined - } - function onClick() { // '`onChange` callback for this component @@ -87,27 +65,6 @@ function Toggle({ if (onChange) onChange(!active) setIntChecked(!intChecked) - - /* - * Create change event for formik - * formik expects an input change event - */ - let event: any = {} - event.target = { - type: 'checkbox', - name: name, - id: id, - value: !active, - checked: !active, - // outerHTML: undefined, - // options: undefined, - // multiple: undefined, - } - - // update form - if (formContextOnChange) formContextOnChange(event) - // run field level validation - if (validation) fieldLevelValidation(id, validation(!intChecked)) } let toggleClasses = [__styles.base, __styles.handle_container[size]] @@ -139,7 +96,6 @@ function Toggle({ className={clsx(...toggleClasses, disabled && 'opacity-50 cursor-default')} onClick={onClick} disabled={disabled} - onBlur={handleBlurEvent} {...props} > diff --git a/packages/ui/src/lib/theme/defaultTheme.ts b/packages/ui/src/lib/theme/defaultTheme.ts index f55ce2919bd..aecccbdc5a2 100644 --- a/packages/ui/src/lib/theme/defaultTheme.ts +++ b/packages/ui/src/lib/theme/defaultTheme.ts @@ -511,50 +511,6 @@ export default { chevron: 'h-5 w-5 text-foreground-lighter', }, - /* - * Input Number - */ - - inputNumber: { - base: ` - block - box-border - w-full - rounded-md - shadow-sm - transition-all - text-foreground - border - focus-visible:shadow-md - ${defaults.focus} - focus-visible:border-foreground-muted - focus-visible:ring-background-control - ${defaults.placeholder} - - appearance-none - bg-none - `, - variants: { - standard: ` - bg-control - border border-strong - `, - error: ` - bg-destructive-200 - border border-destructive-500 - focus:ring-destructive-400 - placeholder:text-destructive-400 - `, - }, - disabled: 'opacity-50', - container: 'relative', - with_icon: with_icon_spacing_sizes, - size: { - ...default__padding_and_text, - }, - actions_container: 'absolute inset-y-0 right-0 pl-3 pr-1 flex space-x-1 items-center', - }, - /* * Checkbox * diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ae01a7ba0e9..82e3f4a1f35 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1330,7 +1330,7 @@ importers: version: 2.11.3(@types/node@22.13.14)(typescript@6.0.2) next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) + version: 0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) node-mocks-http: specifier: ^1.17.2 version: 1.17.2(@types/node@22.13.14) @@ -2283,7 +2283,7 @@ importers: version: 18.3.0 next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) + version: 0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) tsconfig: specifier: workspace:* version: link:../tsconfig @@ -2542,9 +2542,6 @@ importers: date-fns: specifier: ^2.30.0 version: 2.30.0 - formik: - specifier: ^2.2.9 - version: 2.4.9(@types/react@18.3.3)(react@18.3.1) framer-motion: specifier: ^11.0.3 version: 11.11.17(@emotion/is-prop-valid@1.4.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -2846,7 +2843,7 @@ importers: version: link:../api-types next-router-mock: specifier: ^0.9.13 - version: 0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) + version: 0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1) tsx: specifier: 'catalog:' version: 4.20.3 @@ -9303,11 +9300,6 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} - '@types/hoist-non-react-statics@3.3.7': - resolution: {integrity: sha512-PQTyIulDkIDro8P+IHbKCsw7U2xxBYflVzW/FgWdCAePD9xGSidgA76/GeJ6lBKoblyhf9pBY763gbrN+1dI8g==} - peerDependencies: - '@types/react': '*' - '@types/js-cookie@2.2.7': resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==} @@ -11391,10 +11383,6 @@ packages: resolution: {integrity: sha512-RHd9ABw4Fvk+gYDWqwOftG849x0bYOySl/RgX0tLI9i27ZIeSO91mLZJEp7oPHOMFqHvpgu21YptmDt0FYD/0A==} engines: {node: '>=0.10.0'} - deepmerge@2.2.1: - resolution: {integrity: sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==} - engines: {node: '>=0.10.0'} - deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -12367,11 +12355,6 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} - formik@2.4.9: - resolution: {integrity: sha512-5nI94BMnlFDdQRBY4Sz39WkhxajZJ57Fzs8wVbtsQlm5ScKIR1QLYqv/ultBnobObtlUyxpxoLodpixrsf36Og==} - peerDependencies: - react: '>=16.8.0' - forwarded-parse@2.1.2: resolution: {integrity: sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==} @@ -16200,9 +16183,6 @@ packages: peerDependencies: react: '>=16.13.1' - react-fast-compare@2.0.4: - resolution: {integrity: sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==} - react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} @@ -26975,11 +26955,6 @@ snapshots: dependencies: '@types/unist': 2.0.8 - '@types/hoist-non-react-statics@3.3.7(@types/react@18.3.3)': - dependencies: - '@types/react': 18.3.3 - hoist-non-react-statics: 3.3.2 - '@types/js-cookie@2.2.7': {} '@types/js-yaml@4.0.6': {} @@ -29451,8 +29426,6 @@ snapshots: kind-of: 3.2.2 rename-keys: 1.2.0 - deepmerge@2.2.1: {} - deepmerge@4.3.1: {} default-browser-id@5.0.0: {} @@ -30603,20 +30576,6 @@ snapshots: dependencies: fetch-blob: 3.2.0 - formik@2.4.9(@types/react@18.3.3)(react@18.3.1): - dependencies: - '@types/hoist-non-react-statics': 3.3.7(@types/react@18.3.3) - deepmerge: 2.2.1 - hoist-non-react-statics: 3.3.2 - lodash: 4.18.1 - lodash-es: 4.18.1 - react: 18.3.1 - react-fast-compare: 2.0.4 - tiny-warning: 1.0.3 - tslib: 2.8.1 - transitivePeerDependencies: - - '@types/react' - forwarded-parse@2.1.2: {} forwarded@0.2.0: {} @@ -33763,7 +33722,7 @@ snapshots: dependencies: js-yaml-loader: 1.2.2 - next-router-mock@0.9.13(next@16.1.7(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1): + next-router-mock@0.9.13(next@16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4))(react@18.3.1): dependencies: next: 16.1.7(@babel/core@7.29.0(supports-color@8.1.1))(@opentelemetry/api@1.9.0)(@playwright/test@1.56.1)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.77.4) react: 18.3.1 @@ -35451,8 +35410,6 @@ snapshots: '@babel/runtime': 7.26.10 react: 18.3.1 - react-fast-compare@2.0.4: {} - react-fast-compare@3.2.2: {} react-from-dom@0.6.2(react@18.3.1):