diff --git a/.eslintrc.cjs b/.eslintrc.cjs index eaf9054..b3b5ced 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,20 +1,40 @@ /* eslint-env node */ -require('@rushstack/eslint-patch/modern-module-resolution') - module.exports = { root: true, extends: [ - 'plugin:vue/vue3-essential', 'eslint:recommended', - '@vue/eslint-config-typescript', - '@vue/eslint-config-prettier/skip-formatting', + 'plugin:@typescript-eslint/recommended', + 'plugin:react/recommended', + 'plugin:react-hooks/recommended', 'plugin:storybook/recommended' ], + parser: '@typescript-eslint/parser', parserOptions: { - ecmaVersion: 'latest' + ecmaVersion: 'latest', + sourceType: 'module', + ecmaFeatures: { + jsx: true + } + }, + plugins: ['@typescript-eslint'], + settings: { + react: { + version: 'detect' + } }, rules: { - 'vue/no-deprecated-slot-attribute': 0 + 'react/react-in-jsx-scope': 'off', // Not needed in React 17+ + 'react/prop-types': 'off', // Using TypeScript + 'react/display-name': 'off', // Allow anonymous components + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_' + }], + '@typescript-eslint/no-explicit-any': 'off', // Allow any type + '@typescript-eslint/no-namespace': 'off', // Allow namespaces for JSX augmentation + 'no-undef': 'off', // TypeScript handles this + 'no-console': 'warn', // Warn on console statements + 'storybook/no-renderer-packages': 'off' // Allow direct Storybook imports }, - ignorePatterns: ['src/components/examples/'] + ignorePatterns: ['src/components/examples/', 'dist/', 'node_modules/', 'src/stories/'] } diff --git a/package-lock.json b/package-lock.json index 825c700..aa8d264 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,8 @@ "@types/node": "^18.19.3", "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", + "@typescript-eslint/eslint-plugin": "^8.52.0", + "@typescript-eslint/parser": "^8.52.0", "@vitejs/plugin-react": "^4.2.1", "autoprefixer": "^10.4.16", "eslint": "^8.49.0", @@ -2255,6 +2257,70 @@ "license": "MIT", "peer": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.52.0.tgz", + "integrity": "sha512-okqtOgqu2qmZJ5iN4TWlgfF171dZmx2FzdOv2K/ixL2LZWDStL8+JgQerI2sa8eAEfoydG9+0V96m7V+P8yE1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.52.0", + "@typescript-eslint/type-utils": "8.52.0", + "@typescript-eslint/utils": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.52.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.52.0.tgz", + "integrity": "sha512-iIACsx8pxRnguSYhHiMn2PvhvfpopO9FXHyn1mG5txZIsAaB6F0KwbFnUQN3KCiG3Jcuad/Cao2FAs1Wp7vAyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.52.0", + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/visitor-keys": "8.52.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@typescript-eslint/project-service": { "version": "8.52.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.52.0.tgz", @@ -2312,6 +2378,31 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.52.0.tgz", + "integrity": "sha512-JD3wKBRWglYRQkAtsyGz1AewDu3mTc7NtRjR/ceTyGoPqmdS5oCdx/oZMWD5Zuqmo6/MpsYs0wp6axNt88/2EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.52.0", + "@typescript-eslint/typescript-estree": "8.52.0", + "@typescript-eslint/utils": "8.52.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@typescript-eslint/types": { "version": "8.52.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.52.0.tgz", diff --git a/package.json b/package.json index 6556767..6caeb8d 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,8 @@ "@types/node": "^18.19.3", "@types/react": "^18.2.0", "@types/react-dom": "^18.2.0", + "@typescript-eslint/eslint-plugin": "^8.52.0", + "@typescript-eslint/parser": "^8.52.0", "@vitejs/plugin-react": "^4.2.1", "autoprefixer": "^10.4.16", "eslint": "^8.49.0", diff --git a/src/components/RLAutocomplete/RLAutocomplete.tsx b/src/components/RLAutocomplete/RLAutocomplete.tsx index ba24f2e..f9ef2d7 100644 --- a/src/components/RLAutocomplete/RLAutocomplete.tsx +++ b/src/components/RLAutocomplete/RLAutocomplete.tsx @@ -36,7 +36,7 @@ export const RLAutocomplete = forwardRef ref ) => { const autocompleteRef = useRef(null) - const [inputModel, setInputModel] = useState(null) + const [inputModel, setInputModel] = useState(undefined) const { errorMessage, isValid, validate } = useValidation({ rules, externalError: error }) // Sync inputModel with value @@ -45,7 +45,7 @@ export const RLAutocomplete = forwardRef setInputModel({ value: '', text: '' }) } else { const found = options.find((option) => value === option.value) - setInputModel(found ?? (!forceSelection ? { value, text: value } : null)) + setInputModel(found ?? (!forceSelection ? { value, text: value } : undefined)) } }, [value, options, forceSelection]) @@ -60,9 +60,7 @@ export const RLAutocomplete = forwardRef validate: () => validate(value) })) - const handleChange = (evt: { value: RLSelectOptionType | string | null }) => { - console.log('handleChange evt.value:', evt.value) - + const handleChange = (evt: { value: RLSelectOptionType | string | undefined }) => { setInputModel(evt.value) if (!forceSelection) { @@ -79,8 +77,6 @@ export const RLAutocomplete = forwardRef } const handleItemSelect = (evt: { value: RLSelectOptionType }) => { - console.log('handleItemSelect evt.value:', evt.value) - setInputModel(evt.value) onChange?.(evt.value.value) onItemSelect?.(evt) @@ -143,7 +139,7 @@ export const RLAutocomplete = forwardRef completeMethod={handleComplete} onClick={handleClick} onFocus={handleFocus} - onDropdownClick={(evt) => onDropdownClick?.(evt.originalEvent)} + onDropdownClick={(evt) => onDropdownClick?.(evt.originalEvent.nativeEvent)} onClear={onClear} onShow={onShow} onHide={onHide} diff --git a/src/components/RLCheckbox/RLCheckbox.tsx b/src/components/RLCheckbox/RLCheckbox.tsx index 0a10435..f3f068e 100644 --- a/src/components/RLCheckbox/RLCheckbox.tsx +++ b/src/components/RLCheckbox/RLCheckbox.tsx @@ -18,6 +18,11 @@ declare global { form?: string required?: boolean class?: string + onSlInput?: (event: Event) => void + onSlChange?: (event: Event) => void + onSlBlur?: (event: Event) => void + onSlFocus?: (event: Event) => void + onSlInvalid?: (event: Event) => void } } } diff --git a/src/components/RLCrud/RLCrud.tsx b/src/components/RLCrud/RLCrud.tsx index d662ae5..c99835e 100644 --- a/src/components/RLCrud/RLCrud.tsx +++ b/src/components/RLCrud/RLCrud.tsx @@ -1,7 +1,8 @@ -import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react' +import { forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType } from 'react' import type { RLCrudProps, RLCrudRef, RLCrudActionType } from './types' import type { RLCrudFormFieldType } from '../RLCrudForm' import type { RLCrudFiltersRef } from '../RLCrudFilters' +import type { RLCrudInputValueType } from '../RLCrudInput' import { RLCrudAction } from '../RLCrudAction' import { RLPaginator } from '../RLPaginator' import { RLDialog } from '../RLDialog' @@ -43,7 +44,7 @@ export const RLCrud = forwardRef( highlightLastEdited = true, highlightLastEditedClass = '!bg-row-selected', persistActionDialog = true, - rowClass: externalRowClass, + rowClassName: externalRowClassName, getItems, addItem, editItem, @@ -55,7 +56,7 @@ export const RLCrud = forwardRef( }, ref ) => { - const [items, setItems] = useState([]) + const [items, setItems] = useState[]>([]) const [currentPage, setCurrentPage] = useState(0) const [rowsPerPage, setRowsPerPage] = useState( rowsPerPageOptions.includes(initialRowsPerPage) @@ -91,7 +92,10 @@ export const RLCrud = forwardRef( sortable: header.sortable, ...(header.columnProps ? { columnProps: header.columnProps } : {}), ...(header.type - ? { component: components?.[header.type], componentProps: header.componentProps } + ? { + component: components?.[header.type] as ComponentType<{ data: unknown; field: string; [key: string]: unknown }>, + componentProps: header.componentProps as Record + } : {}) })), [headers, translationFn, components] @@ -115,10 +119,11 @@ export const RLCrud = forwardRef( return } - setItems(response.result) + setItems(response.result as Record[]) setCurrentPage(response.page.currentPage) setTotalRows(response.page.totalRows) } catch (e) { + // eslint-disable-next-line no-console console.error(e) onFetchError?.() } @@ -171,29 +176,36 @@ export const RLCrud = forwardRef( await fetchData() }, [fetchData]) - const rowClass = useCallback( + const rowClassName = useCallback( (row: unknown) => { - const externalClasses = externalRowClass?.(row) || [] + const externalResult = externalRowClassName?.(row) + const externalClasses = Array.isArray(externalResult) + ? externalResult + : externalResult + ? [externalResult] + : [] + if ((row as Record)[primary_key] === lastSelectedItem && highlightLastEdited) { - return [...externalClasses, highlightLastEditedClass] + return [...externalClasses, highlightLastEditedClass].join(' ') } - return externalClasses + return externalClasses.join(' ') }, - [externalRowClass, primary_key, lastSelectedItem, highlightLastEdited, highlightLastEditedClass] + [externalRowClassName, primary_key, lastSelectedItem, highlightLastEdited, highlightLastEditedClass] ) const onAdd = useCallback( async (data: Record) => { const response = await addItem?.(data) + const responseRecord = response as Record const newId = - (response as Record)?.result?.[primary_key] ?? - (response as Record)?.[primary_key] + ((responseRecord?.result as Record)?.[primary_key]) ?? + responseRecord?.[primary_key] setLastSelectedItem(newId) if (goToInsertedRow) { skipWatchersRef.current = true - setFiltersApplied({ [primary_key]: newId }) - filtersRef.current?.setFilterModel({ [primary_key]: newId }) + setFiltersApplied({ [primary_key]: newId as RLCrudInputValueType }) + filtersRef.current?.setFilterModel({ [primary_key]: newId as RLCrudInputValueType }) filtersRef.current?.setOpen(true) setCurrentPage(1) await Promise.resolve() // Allow state to update @@ -291,7 +303,7 @@ export const RLCrud = forwardRef( actions={[]} paginator={false} actionHeaderLabel={translationFn(actionHeaderI18nKey)} - rowClass={rowClass} + rowClassName={rowClassName} actionsSlot={renderActions} emptySlot={
Empty
} /> @@ -348,7 +360,7 @@ export const RLCrud = forwardRef( requiredRuleMessage={translationFn(requiredI18nKey)} cancelLabel={translationFn(cancelI18nKey)} confirmLabel={translationFn(editI18nKey)} - value={selectedItem ?? undefined} + value={(selectedItem as { [key: string]: RLCrudInputValueType }) ?? undefined} primaryKey={primary_key} onClose={closeDialog} onCancel={closeDialog} diff --git a/src/components/RLCrud/types.ts b/src/components/RLCrud/types.ts index ec98f75..3685fe0 100644 --- a/src/components/RLCrud/types.ts +++ b/src/components/RLCrud/types.ts @@ -64,7 +64,7 @@ export interface RLCrudProps { highlightLastEdited?: boolean highlightLastEditedClass?: string persistActionDialog?: boolean - rowClass?: (data: unknown) => (string | object)[] | undefined + rowClassName?: (data: unknown) => string | string[] | undefined getItems: ( page: number, rowsPerPage: number, diff --git a/src/components/RLCrudFilters/RLCrudFilters.tsx b/src/components/RLCrudFilters/RLCrudFilters.tsx index f485582..c60940f 100644 --- a/src/components/RLCrudFilters/RLCrudFilters.tsx +++ b/src/components/RLCrudFilters/RLCrudFilters.tsx @@ -12,6 +12,7 @@ export const RLCrudFilters = forwardRef( filters, applyLabel = 'apply', resetLabel = 'reset', + className, onApply, onHide, onReset, @@ -105,6 +106,7 @@ export const RLCrudFilters = forwardRef( void onHide?: () => void onReset?: () => void diff --git a/src/components/RLCrudForm/RLCrudForm.tsx b/src/components/RLCrudForm/RLCrudForm.tsx index 0a047dd..3758baf 100644 --- a/src/components/RLCrudForm/RLCrudForm.tsx +++ b/src/components/RLCrudForm/RLCrudForm.tsx @@ -97,6 +97,10 @@ export const RLCrudForm = forwardRef( [fields] ) + const closeDialog = useCallback(() => { + onClose?.() + }, [onClose]) + const handleConfirm = useCallback( (e: React.FormEvent) => { e.preventDefault() @@ -117,17 +121,13 @@ export const RLCrudForm = forwardRef( closeDialog() } }, - [fields, isVisible, model, onConfirm, validateAll] + [fields, isVisible, model, onConfirm, validateAll, closeDialog] ) const handleCancel = useCallback(() => { onCancel?.() closeDialog() - }, [onCancel]) - - const closeDialog = useCallback(() => { - onClose?.() - }, [onClose]) + }, [onCancel, closeDialog]) useImperativeHandle(ref, () => ({ validate: () => { diff --git a/src/components/RLDataTableCrud/RLDataTableCrud.tsx b/src/components/RLDataTableCrud/RLDataTableCrud.tsx index 9adcb3b..dc5efec 100644 --- a/src/components/RLDataTableCrud/RLDataTableCrud.tsx +++ b/src/components/RLDataTableCrud/RLDataTableCrud.tsx @@ -3,7 +3,7 @@ import { DataTable, DataTablePageEvent, DataTableSelectionMultipleChangeEvent, D import { Column } from 'primereact/column' import type { RLDataTableCrudProps, RLColumn, RLAction } from './types' -export const RLDataTableCrud = forwardRef, RLDataTableCrudProps>( +export const RLDataTableCrud = forwardRef, RLDataTableCrudProps>( ( { columns, @@ -11,6 +11,7 @@ export const RLDataTableCrud = forwardRef, RLDataTableCrudP items, selection, onSelectionChange, + className, size, stripedRows = false, removableSort = false, @@ -18,8 +19,7 @@ export const RLDataTableCrud = forwardRef, RLDataTableCrudP lazy = false, defaultRows = 10, rowsPerPageOptions = [5, 10, 20], - rowClass, - rowStyle, + rowClassName, totalRecords, paginator = true, paginatorPosition, @@ -35,7 +35,7 @@ export const RLDataTableCrud = forwardRef, RLDataTableCrudP ref ) => { const handleSelectionChange = useCallback( - (e: DataTableSelectionMultipleChangeEvent | DataTableSelectionSingleChangeEvent) => { + (e: DataTableSelectionMultipleChangeEvent | DataTableSelectionSingleChangeEvent) => { if (Array.isArray(e.value)) { onSelectionChange?.(e.value) } else if (e.value) { @@ -93,6 +93,7 @@ export const RLDataTableCrud = forwardRef, RLDataTableCrudP return ( , RLDataTableCrudP lazy={lazy} rows={defaultRows} rowsPerPageOptions={rowsPerPageOptions} - rowClassName={rowClass} - rowStyle={rowStyle} + rowClassName={rowClassName} totalRecords={totalRecords ?? items.length} paginator={paginator} paginatorPosition={paginatorPosition} @@ -113,6 +113,7 @@ export const RLDataTableCrud = forwardRef, RLDataTableCrudP onPage={handlePage} emptyMessage={emptySlot} selectionMode={selectionMode as 'single' | 'multiple' | 'checkbox' | 'radiobutton' | null | undefined} + cellSelection={false} > {selectionMode && ( [] selection?: unknown[] onSelectionChange?: (selection: unknown[]) => void + className?: string size?: 'small' | 'large' stripedRows?: boolean removableSort?: boolean @@ -31,8 +32,7 @@ export interface RLDataTableCrudProps { lazy?: boolean defaultRows?: number rowsPerPageOptions?: number[] - rowClass?: (data: unknown) => string | object | (string | object)[] | undefined - rowStyle?: (data: unknown) => CSSProperties | undefined + rowClassName?: (data: unknown) => string | undefined totalRecords?: number paginator?: boolean paginatorPosition?: 'both' | 'top' | 'bottom' diff --git a/src/components/RLDatePicker/RLDatePicker.tsx b/src/components/RLDatePicker/RLDatePicker.tsx index 99c6521..79535e2 100644 --- a/src/components/RLDatePicker/RLDatePicker.tsx +++ b/src/components/RLDatePicker/RLDatePicker.tsx @@ -128,6 +128,7 @@ export const RLDatePicker = forwardRef( class={`date-input ${errorMessage ? 'error' : ''}`} onClick={handleInputClick} value={formattedValue} + name={name || undefined} label={label || undefined} disabled={disabled || undefined} required={required || undefined} diff --git a/src/components/RLDialog/RLDialog.tsx b/src/components/RLDialog/RLDialog.tsx index 6c9fbc0..2ed5e93 100644 --- a/src/components/RLDialog/RLDialog.tsx +++ b/src/components/RLDialog/RLDialog.tsx @@ -10,6 +10,12 @@ declare global { open?: boolean noHeader?: boolean class?: string + onSlShow?: (event: Event) => void + onSlAfterShow?: (event: Event) => void + onSlHide?: (event: Event) => void + onSlAfterHide?: (event: Event) => void + onSlInitialFocus?: (event: Event) => void + onSlRequestClose?: (event: Event) => void } } } @@ -23,6 +29,7 @@ export const RLDialog = forwardRef( label, noHeader, noCloseOnOutsideClick, + className, onShow, onAfterShow, onHide, @@ -33,7 +40,7 @@ export const RLDialog = forwardRef( }, ref ) => { - const dialogRef = useRef void; hide: () => void }>(null) + const dialogRef = useRef void; hide: () => void }>(null) useImperativeHandle(ref, () => ({ open: dialogRef.current?.open, @@ -93,7 +100,7 @@ export const RLDialog = forwardRef( return ( void onAfterShow?: (evt: SlAfterShowEvent) => void onHide?: (evt: SlHideEvent) => void diff --git a/src/components/RLExpansionCard/RLExpansionCard.tsx b/src/components/RLExpansionCard/RLExpansionCard.tsx index 6225629..2716cbb 100644 --- a/src/components/RLExpansionCard/RLExpansionCard.tsx +++ b/src/components/RLExpansionCard/RLExpansionCard.tsx @@ -8,6 +8,10 @@ declare global { interface IntrinsicElements { 'sl-details': React.DetailedHTMLProps, HTMLElement> & { open?: boolean + onSlShow?: (event: Event) => void + onSlHide?: (event: Event) => void + onSlAfterShow?: (event: Event) => void + onSlAfterHide?: (event: Event) => void } } } @@ -19,6 +23,7 @@ export const RLExpansionCard = forwardRef void + className?: string onShow?: (evt: SlShowEvent) => void onHide?: (evt: SlHideEvent) => void onAfterShow?: (evt: SlAfterShowEvent) => void diff --git a/src/components/RLImageUpload/RLImageUpload.tsx b/src/components/RLImageUpload/RLImageUpload.tsx index f5ad024..5bdcced 100644 --- a/src/components/RLImageUpload/RLImageUpload.tsx +++ b/src/components/RLImageUpload/RLImageUpload.tsx @@ -79,11 +79,13 @@ export const RLImageUpload = forwardRef( style={{ backgroundImage: `url(${value})` }} /> - + {clearable && ( + + )} {errorMessage && {errorMessage}} diff --git a/src/components/RLNumberInput/RLNumberInput.tsx b/src/components/RLNumberInput/RLNumberInput.tsx index d0f33fc..5af6b51 100644 --- a/src/components/RLNumberInput/RLNumberInput.tsx +++ b/src/components/RLNumberInput/RLNumberInput.tsx @@ -85,7 +85,7 @@ export const RLNumberInput = forwardRef( // Update input display if value was clamped if (inputRef.current && validValue !== null) { - ;(inputRef.current as unknown as HTMLInputElement).value = validValue.toString() + (inputRef.current as unknown as HTMLInputElement).value = validValue.toString() } }, [checkMinMax, onChange, onSlChange] diff --git a/src/context/ReactlaceProvider.tsx b/src/context/ReactlaceProvider.tsx index aa1ae61..6e74d31 100644 --- a/src/context/ReactlaceProvider.tsx +++ b/src/context/ReactlaceProvider.tsx @@ -1,5 +1,5 @@ import { createContext, useContext, useEffect, type ReactNode } from 'react' -import { useIcons } from '../shoelace' +import { initializeIcons } from '../shoelace' interface ReactlaceContextValue { initialized: boolean @@ -14,7 +14,7 @@ export interface ReactlaceProviderProps { export function ReactlaceProvider({ children, iconLibrary = 'mdi' }: ReactlaceProviderProps) { useEffect(() => { - useIcons(iconLibrary) + initializeIcons(iconLibrary) }, [iconLibrary]) return ( diff --git a/src/hooks/useValidation.ts b/src/hooks/useValidation.ts index c0742fb..85aa79c 100644 --- a/src/hooks/useValidation.ts +++ b/src/hooks/useValidation.ts @@ -1,9 +1,5 @@ import { useState, useCallback } from 'react' - -export interface RLInputRuleType { - validateFn: (value: unknown) => boolean - message: string -} +import type { RLInputRuleType } from '../components/utils/types' export interface UseValidationOptions { rules?: RLInputRuleType[] diff --git a/src/shoelace.ts b/src/shoelace.ts index e4fe935..85d7848 100644 --- a/src/shoelace.ts +++ b/src/shoelace.ts @@ -8,7 +8,7 @@ import type { const SHOELACE_ICONS_LIBRARY = 'shoelace' const MDI_ICONS_LIBRARY = 'mdi' -export const useIcons = (library: string = 'mdi') => { +export const initializeIcons = (library: string = 'mdi') => { if (library === SHOELACE_ICONS_LIBRARY) { shoelace.setBasePath('../node_modules/@shoelace-style/shoelace/dist') } else if (library === MDI_ICONS_LIBRARY) { @@ -17,6 +17,8 @@ export const useIcons = (library: string = 'mdi') => { } } +export const useIcons = initializeIcons + export const registerIconLibrary = ( library: string, resolver: IconLibraryResolver,