Browse Source

Update derived element types

Use HTMLElementTagNameMap to unify both rendering and typing.
master
TheoryOfNekomata 1 year ago
parent
commit
2258466d86
28 changed files with 288 additions and 152 deletions
  1. +7
    -3
      categories/web/action/react/src/components/ActionButton/index.tsx
  2. +88
    -74
      categories/web/blob/react/src/components/FileSelectBox/index.tsx
  3. +6
    -2
      categories/web/choice/react/src/components/ComboBox/index.tsx
  4. +7
    -3
      categories/web/choice/react/src/components/DropdownSelect/index.tsx
  5. +6
    -2
      categories/web/choice/react/src/components/MenuSelect/index.tsx
  6. +8
    -4
      categories/web/choice/react/src/components/RadioButton/index.tsx
  7. +6
    -2
      categories/web/choice/react/src/components/RadioTickBox/index.tsx
  8. +6
    -2
      categories/web/color/react/src/components/ColorPicker/index.tsx
  9. +6
    -2
      categories/web/color/react/src/components/Swatch/index.tsx
  10. +6
    -2
      categories/web/formatted/react/src/components/EmailInput/index.tsx
  11. +6
    -2
      categories/web/formatted/react/src/components/PatternTextInput/index.tsx
  12. +6
    -2
      categories/web/formatted/react/src/components/PhoneNumberInput/index.tsx
  13. +6
    -2
      categories/web/formatted/react/src/components/UrlInput/index.tsx
  14. +6
    -2
      categories/web/freeform/react/src/components/MaskedTextInput/index.tsx
  15. +6
    -2
      categories/web/freeform/react/src/components/MultilineTextInput/index.tsx
  16. +6
    -2
      categories/web/freeform/react/src/components/TextInput/index.tsx
  17. +7
    -3
      categories/web/information/react/src/components/Badge/index.tsx
  18. +19
    -9
      categories/web/information/react/src/components/KeyValueTable/index.tsx
  19. +6
    -2
      categories/web/multichoice/react/src/components/MenuMultiSelect/index.tsx
  20. +12
    -6
      categories/web/multichoice/react/src/components/TagInput/index.tsx
  21. +6
    -2
      categories/web/multichoice/react/src/components/ToggleButton/index.tsx
  22. +6
    -2
      categories/web/multichoice/react/src/components/ToggleSwitch/index.tsx
  23. +6
    -2
      categories/web/multichoice/react/src/components/ToggleTickBox/index.tsx
  24. +9
    -5
      categories/web/navigation/react/src/components/LinkButton/index.tsx
  25. +15
    -5
      categories/web/number/react/src/components/NumberSpinner/index.tsx
  26. +8
    -4
      categories/web/number/react/src/components/Slider/index.tsx
  27. +6
    -2
      categories/web/temporal/react/src/components/DateDropdown/index.tsx
  28. +6
    -2
      categories/web/temporal/react/src/components/TimeSpinner/index.tsx

+ 7
- 3
categories/web/action/react/src/components/ActionButton/index.tsx View File

@@ -2,10 +2,14 @@ import * as React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
import { Button } from '@tesseract-design/web-base'; import { Button } from '@tesseract-design/web-base';


const ActionButtonDerivedElementComponent = 'button' as const;

/** /**
* Derived HTML element of the {@link ActionButton} component. * Derived HTML element of the {@link ActionButton} component.
*/ */
export type ActionButtonDerivedElement = HTMLButtonElement;
export type ActionButtonDerivedElement = HTMLElementTagNameMap[
typeof ActionButtonDerivedElementComponent
];


/** /**
* Props of the {@link ActionButton} component. * Props of the {@link ActionButton} component.
@@ -76,7 +80,7 @@ export const ActionButton = React.forwardRef<ActionButtonDerivedElement, ActionB
}, },
forwardedRef, forwardedRef,
) => ( ) => (
<button
<ActionButtonDerivedElementComponent
{...etcProps} {...etcProps}
data-testid="button" data-testid="button"
type={type} type={type}
@@ -184,7 +188,7 @@ export const ActionButton = React.forwardRef<ActionButtonDerivedElement, ActionB
</svg> </svg>
</span> </span>
)} )}
</button>
</ActionButtonDerivedElementComponent>
)); ));


ActionButton.displayName = 'ActionButton' as const; ActionButton.displayName = 'ActionButton' as const;


+ 88
- 74
categories/web/blob/react/src/components/FileSelectBox/index.tsx View File

@@ -2,9 +2,7 @@ import * as React from 'react';
import { useClientSide, useFallbackId, useProxyInput } from '@modal-sh/react-utils'; import { useClientSide, useFallbackId, useProxyInput } from '@modal-sh/react-utils';
import clsx from 'clsx'; import clsx from 'clsx';


const DEFAULT_ENHANCED_HEIGHT_PX = 64 as const;

const DEFAULT_NON_ENHANCED_SIDE_HEIGHT_PX = 256 as const;
const FileSelectBoxDefaultPreviewComponentDerivedElementComponent = 'div' as const;


/** /**
* Common props for the {@link FileSelectBoxProps.previewComponent|previewComponent prop} of the * Common props for the {@link FileSelectBoxProps.previewComponent|previewComponent prop} of the
@@ -29,57 +27,9 @@ export interface CommonPreviewComponentProps<F extends Partial<File> = Partial<F
mini?: boolean; mini?: boolean;
} }


/**
* Derived HTML element of the {@link FileSelectBox} component.
*/
export type FileSelectBoxDerivedElement = HTMLInputElement;

/**
* Props of the {@link FileSelectBox} component.
*/
export interface FileSelectBoxProps<
F extends Partial<File> = Partial<File>,
P extends CommonPreviewComponentProps<F> = CommonPreviewComponentProps<F>
> extends Omit<React.HTMLProps<FileSelectBoxDerivedElement>, 'size' | 'type' | 'label' | 'list'> {
/**
* Should the component display a border?
*/
border?: boolean,
/**
* Should the component occupy the whole width of its parent?
*/
block?: boolean,
/**
* Short textual description indicating the nature of the component's value.
*/
label?: React.ReactNode,
/**
* Short textual description as guidelines for valid input values.
*/
hint?: React.ReactNode,
/**
* Should the component be enhanced?
*/
enhanced?: boolean,
/**
* Is the label hidden?
*/
hiddenLabel?: boolean,
/**
* Preview component for the selected file(s).
*/
previewComponent?: React.ElementType<P>,
/**
* Reselect label.
*/
reselectLabel?: string,
/**
* Clear label.
*/
clearLabel?: string,
}

export type FileSelectBoxDefaultPreviewComponentDerivedElement = HTMLDivElement;
export type FileSelectBoxDefaultPreviewComponentDerivedElement = HTMLElementTagNameMap[
typeof FileSelectBoxDefaultPreviewComponentDerivedElementComponent
];


/** /**
* Default component for the {@link FileSelectBoxProps.previewComponent|previewComponent prop} * Default component for the {@link FileSelectBoxProps.previewComponent|previewComponent prop}
@@ -94,7 +44,7 @@ export const FileSelectBoxDefaultPreviewComponent = React.forwardRef<
enhanced, enhanced,
disabled, disabled,
}, forwardedRef) => ( }, forwardedRef) => (
<div
<FileSelectBoxDefaultPreviewComponentDerivedElementComponent
data-enhanced={enhanced} data-enhanced={enhanced}
className={clsx({ className={clsx({
'opacity-50': disabled, 'opacity-50': disabled,
@@ -138,12 +88,76 @@ export const FileSelectBoxDefaultPreviewComponent = React.forwardRef<
)} )}
</> </>
)} )}
</div>
</FileSelectBoxDefaultPreviewComponentDerivedElementComponent>
)); ));


const isButtonElement = (el: HTMLElement): el is HTMLButtonElement => el.tagName === 'BUTTON';
const DEFAULT_ENHANCED_HEIGHT_PX = 64 as const;

const DEFAULT_NON_ENHANCED_SIDE_HEIGHT_PX = 256 as const;

const FileSelectBoxRootElementComponent = 'div' as const;


const isInputElement = (el: HTMLElement): el is HTMLInputElement => el.tagName === 'INPUT';
type FileSelectBoxRootElement = HTMLElementTagNameMap[typeof FileSelectBoxRootElementComponent];

const FileSelectBoxActionElementComponent = 'button' as const;

type FileSelectBoxActionElement = HTMLElementTagNameMap[typeof FileSelectBoxActionElementComponent];

const FileSelectBoxDerivedElementComponent = 'input' as const;

/**
* Derived HTML element of the {@link FileSelectBox} component.
*/
export type FileSelectBoxDerivedElement = HTMLElementTagNameMap[typeof FileSelectBoxDerivedElementComponent];

/**
* Props of the {@link FileSelectBox} component.
*/
export interface FileSelectBoxProps<
F extends Partial<File> = Partial<File>,
P extends CommonPreviewComponentProps<F> = CommonPreviewComponentProps<F>
> extends Omit<React.HTMLProps<FileSelectBoxDerivedElement>, 'size' | 'type' | 'label' | 'list'> {
/**
* Should the component display a border?
*/
border?: boolean,
/**
* Should the component occupy the whole width of its parent?
*/
block?: boolean,
/**
* Short textual description indicating the nature of the component's value.
*/
label?: React.ReactNode,
/**
* Short textual description as guidelines for valid input values.
*/
hint?: React.ReactNode,
/**
* Should the component be enhanced?
*/
enhanced?: boolean,
/**
* Is the label hidden?
*/
hiddenLabel?: boolean,
/**
* Preview component for the selected file(s).
*/
previewComponent?: React.ElementType<P>,
/**
* Reselect label.
*/
reselectLabel?: string,
/**
* Clear label.
*/
clearLabel?: string,
}

const isButtonElement = (el: HTMLElement): el is FileSelectBoxActionElement => el.tagName === 'BUTTON';

const isInputElement = (el: HTMLElement): el is FileSelectBoxDerivedElement => el.tagName === 'INPUT';


const isKeyUpEvent = (e: React.SyntheticEvent): e is React.KeyboardEvent => e.type === 'keyup'; const isKeyUpEvent = (e: React.SyntheticEvent): e is React.KeyboardEvent => e.type === 'keyup';


@@ -211,8 +225,8 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS


const { defaultRef, handleChange: doSetFileList } = useProxyInput< const { defaultRef, handleChange: doSetFileList } = useProxyInput<
React.ChangeEvent<FileSelectBoxDerivedElement> React.ChangeEvent<FileSelectBoxDerivedElement>
| React.MouseEvent<HTMLButtonElement>
| React.DragEvent<HTMLDivElement>
| React.MouseEvent<FileSelectBoxActionElement>
| React.DragEvent<FileSelectBoxRootElement>
| React.KeyboardEvent<FileSelectBoxDerivedElement> | React.KeyboardEvent<FileSelectBoxDerivedElement>
| React.ClipboardEvent<FileSelectBoxDerivedElement>, | React.ClipboardEvent<FileSelectBoxDerivedElement>,
FileSelectBoxDerivedElement FileSelectBoxDerivedElement
@@ -270,12 +284,12 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
const labelId = React.useId(); const labelId = React.useId();
const id = useFallbackId(idProp); const id = useFallbackId(idProp);


const cancelEvent: React.DragEventHandler<HTMLDivElement> = React.useCallback((e) => {
const cancelEvent: React.DragEventHandler<FileSelectBoxRootElement> = React.useCallback((e) => {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
}, []); }, []);


const handleDrop: React.DragEventHandler<HTMLDivElement> = React.useCallback((e) => {
const handleDrop: React.DragEventHandler<FileSelectBoxRootElement> = React.useCallback((e) => {
cancelEvent(e); cancelEvent(e);
doSetFileList(e); doSetFileList(e);
}, [cancelEvent, doSetFileList]); }, [cancelEvent, doSetFileList]);
@@ -312,7 +326,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
}, []); }, []);


const handleReselectMouseDown: React.MouseEventHandler< const handleReselectMouseDown: React.MouseEventHandler<
HTMLButtonElement
FileSelectBoxActionElement
> = React.useCallback(() => { > = React.useCallback(() => {
setAboutToSelect(true); setAboutToSelect(true);
setTimeout(() => { setTimeout(() => {
@@ -322,7 +336,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
}, [defaultRef]); }, [defaultRef]);


const handleReselectMouseUp: React.MouseEventHandler< const handleReselectMouseUp: React.MouseEventHandler<
HTMLButtonElement
FileSelectBoxActionElement
> = React.useCallback(() => { > = React.useCallback(() => {
const fileInput = defaultRef.current as FileSelectBoxDerivedElement; const fileInput = defaultRef.current as FileSelectBoxDerivedElement;
if (typeof fileInput.showPicker !== 'function') { if (typeof fileInput.showPicker !== 'function') {
@@ -333,7 +347,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
}, [defaultRef]); }, [defaultRef]);


const handleDeleteMouseDown: React.MouseEventHandler< const handleDeleteMouseDown: React.MouseEventHandler<
HTMLButtonElement
FileSelectBoxActionElement
> = React.useCallback(() => { > = React.useCallback(() => {
setAboutToClear(true); setAboutToClear(true);
setTimeout(() => { setTimeout(() => {
@@ -366,7 +380,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
const fileListArray = Array.from(fileList ?? []); const fileListArray = Array.from(fileList ?? []);


return ( return (
<div
<FileSelectBoxRootElementComponent
className={clsx( className={clsx(
'relative rounded ring-secondary/50 group file-select-box', 'relative rounded ring-secondary/50 group file-select-box',
'focus-within:ring-4', 'focus-within:ring-4',
@@ -401,7 +415,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
</label> </label>
)} )}
{clientSide && ( {clientSide && (
<button
<FileSelectBoxActionElementComponent
type="button" type="button"
disabled={disabled} disabled={disabled}
tabIndex={-1} tabIndex={-1}
@@ -414,9 +428,9 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
onMouseUp={handleReselectMouseUp} onMouseUp={handleReselectMouseUp}
> >
{placeholder} {placeholder}
</button>
</FileSelectBoxActionElementComponent>
)} )}
<input
<FileSelectBoxDerivedElementComponent
{...etcProps} {...etcProps}
id={id} id={id}
disabled={disabled} disabled={disabled}
@@ -513,7 +527,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
className="absolute bottom-0 left-0 w-full text-center h-12 box-border flex" className="absolute bottom-0 left-0 w-full text-center h-12 box-border flex"
> >
<div className="w-0 flex-auto flex flex-col items-center justify-center h-full"> <div className="w-0 flex-auto flex flex-col items-center justify-center h-full">
<button
<FileSelectBoxActionElementComponent
type="button" type="button"
data-testid="reselect" data-testid="reselect"
disabled={disabled} disabled={disabled}
@@ -533,10 +547,10 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
> >
{reselectLabel} {reselectLabel}
</span> </span>
</button>
</FileSelectBoxActionElementComponent>
</div> </div>
<div className="w-0 flex-auto flex flex-col items-center justify-center h-full"> <div className="w-0 flex-auto flex flex-col items-center justify-center h-full">
<button
<FileSelectBoxActionElementComponent
disabled={disabled} disabled={disabled}
data-testid="clear" data-testid="clear"
type="button" type="button"
@@ -558,7 +572,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
> >
{clearLabel} {clearLabel}
</span> </span>
</button>
</FileSelectBoxActionElementComponent>
</div> </div>
</div> </div>
</React.Fragment> </React.Fragment>
@@ -569,7 +583,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
className="absolute z-[1] peer-disabled:opacity-50 inset-0 rounded-inherit border-2 border-primary pointer-events-none group-focus-within:border-secondary" className="absolute z-[1] peer-disabled:opacity-50 inset-0 rounded-inherit border-2 border-primary pointer-events-none group-focus-within:border-secondary"
/> />
)} )}
</div>
</FileSelectBoxRootElementComponent>
); );
}); });




+ 6
- 2
categories/web/choice/react/src/components/ComboBox/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';
import clsx from 'clsx'; import clsx from 'clsx';


const ComboBoxDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link ComboBox} component. * Derived HTML element of the {@link ComboBox} component.
*/ */
export type ComboBoxDerivedElement = HTMLInputElement;
export type ComboBoxDerivedElement = HTMLElementTagNameMap[
typeof ComboBoxDerivedElementComponent
];


/** /**
* Props of the {@link ComboBox} component. * Props of the {@link ComboBox} component.
@@ -143,7 +147,7 @@ export const ComboBox = React.forwardRef<ComboBoxDerivedElement, ComboBoxProps>(
{' '} {' '}
</> </>
)} )}
<input
<ComboBoxDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={forwardedRef} ref={forwardedRef}


+ 7
- 3
categories/web/choice/react/src/components/DropdownSelect/index.tsx View File

@@ -4,10 +4,14 @@ import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';


const DropdownSelectDerivedElementComponent = 'select' as const;

/** /**
* Derived HTML element of the {@link DropdownSelect} component. * Derived HTML element of the {@link DropdownSelect} component.
*/ */
export type DropdownSelectDerivedElement = HTMLSelectElement;
export type DropdownSelectDerivedElement = HTMLElementTagNameMap[
typeof DropdownSelectDerivedElementComponent
];


/** /**
* Props of the {@link DropdownSelect} component. * Props of the {@link DropdownSelect} component.
@@ -127,7 +131,7 @@ export const DropdownSelect = React.forwardRef<DropdownSelectDerivedElement, Dro
{' '} {' '}
</> </>
)} )}
<select
<DropdownSelectDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
id={id} id={id}
@@ -150,7 +154,7 @@ export const DropdownSelect = React.forwardRef<DropdownSelectDerivedElement, Dro
)} )}
> >
{children} {children}
</select>
</DropdownSelectDerivedElementComponent>
{hint && ( {hint && (
<div <div
data-testid="hint" data-testid="hint"


+ 6
- 2
categories/web/choice/react/src/components/MenuSelect/index.tsx View File

@@ -4,10 +4,14 @@ import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';


const MenuSelectDerivedElementComponent = 'select' as const;

/** /**
* Derived HTML element of the {@link MenuSelect} component. * Derived HTML element of the {@link MenuSelect} component.
*/ */
export type MenuSelectDerivedElement = HTMLSelectElement;
export type MenuSelectDerivedElement = HTMLElementTagNameMap[
typeof MenuSelectDerivedElementComponent
];


/** /**
* Props of the {@link MenuSelect} component. * Props of the {@link MenuSelect} component.
@@ -137,7 +141,7 @@ export const MenuSelect = React.forwardRef<MenuSelectDerivedElement, MenuSelectP
{' '} {' '}
</> </>
)} )}
<select
<MenuSelectDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
id={id} id={id}


+ 8
- 4
categories/web/choice/react/src/components/RadioButton/index.tsx View File

@@ -4,10 +4,14 @@ import { Button } from '@tesseract-design/web-base';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';


const RadioButtonDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link RadioButton} component. * Derived HTML element of the {@link RadioButton} component.
*/ */
export type RadioButtonDerivedElement = HTMLInputElement;
export type RadioButtonDerivedElement = HTMLElementTagNameMap[
typeof RadioButtonDerivedElementComponent
];


/** /**
* Props of the {@link RadioButton} component. * Props of the {@link RadioButton} component.
@@ -77,9 +81,9 @@ export const RadioButton = React.forwardRef<RadioButtonDerivedElement, RadioButt


return ( return (
<span <span
className="contents"
>
<input
className="contents"
>
<RadioButtonDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
type="radio" type="radio"


+ 6
- 2
categories/web/choice/react/src/components/RadioTickBox/index.tsx View File

@@ -3,10 +3,14 @@ import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';


const RadioTickBoxDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link RadioTickBox} component. * Derived HTML element of the {@link RadioTickBox} component.
*/ */
export type RadioTickBoxDerivedElement = HTMLInputElement;
export type RadioTickBoxDerivedElement = HTMLElementTagNameMap[
typeof RadioTickBoxDerivedElementComponent
];


/** /**
* Props of the {@link RadioTickBox} component. * Props of the {@link RadioTickBox} component.
@@ -65,7 +69,7 @@ export const RadioTickBox = React.forwardRef<RadioTickBoxDerivedElement, RadioTi
style={style} style={style}
data-testid="base" data-testid="base"
> >
<input
<RadioTickBoxDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
type="radio" type="radio"


+ 6
- 2
categories/web/color/react/src/components/ColorPicker/index.tsx View File

@@ -2,10 +2,14 @@ import * as React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';


const ColorPickerDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link ColorPicker} component. * Derived HTML element of the {@link ColorPicker} component.
*/ */
export type ColorPickerDerivedElement = HTMLInputElement;
export type ColorPickerDerivedElement = HTMLElementTagNameMap[
typeof ColorPickerDerivedElementComponent
];


/** /**
* Props of the {@link ColorPicker} component. * Props of the {@link ColorPicker} component.
@@ -75,7 +79,7 @@ export const ColorPicker = React.forwardRef<
}, },
)} )}
> >
<input
<ColorPickerDerivedElementComponent
{...etcProps} {...etcProps}
className={clsx( className={clsx(
'color-picker absolute top-0 left-0 w-full h-full overflow-hidden cursor-pointer disabled:cursor-not-allowed', 'color-picker absolute top-0 left-0 w-full h-full overflow-hidden cursor-pointer disabled:cursor-not-allowed',


+ 6
- 2
categories/web/color/react/src/components/Swatch/index.tsx View File

@@ -3,10 +3,14 @@ import clsx from 'clsx';
import Color from 'color'; import Color from 'color';
import * as convert from 'color-convert'; import * as convert from 'color-convert';


const SwatchDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link Swatch} component. * Derived HTML element of the {@link Swatch} component.
*/ */
export type SwatchDerivedElement = HTMLInputElement;
export type SwatchDerivedElement = HTMLElementTagNameMap[
typeof SwatchDerivedElementComponent
];


type ColorValue = ConstructorParameters<typeof Color>[0]; type ColorValue = ConstructorParameters<typeof Color>[0];


@@ -56,7 +60,7 @@ export const Swatch = React.forwardRef<SwatchDerivedElement, SwatchProps>(({
)} )}
style={style} style={style}
> >
<input
<SwatchDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
type="text" type="text"


+ 6
- 2
categories/web/formatted/react/src/components/EmailInput/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import clsx from 'clsx'; import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const EmailInputDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link EmailInput} component. * Derived HTML element of the {@link EmailInput} component.
*/ */
export type EmailInputDerivedElement = HTMLInputElement;
export type EmailInputDerivedElement = HTMLElementTagNameMap[
typeof EmailInputDerivedElementComponent
];


/** /**
* Props of the {@link EmailInput} component. * Props of the {@link EmailInput} component.
@@ -124,7 +128,7 @@ export const EmailInput = React.forwardRef<EmailInputDerivedElement, EmailInputP
{' '} {' '}
</> </>
)} )}
<input
<EmailInputDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={forwardedRef} ref={forwardedRef}


+ 6
- 2
categories/web/formatted/react/src/components/PatternTextInput/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import clsx from 'clsx'; import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const PatternTextInputDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link PatternTextInput} component. * Derived HTML element of the {@link PatternTextInput} component.
*/ */
export type PatternTextInputDerivedElement = HTMLInputElement;
export type PatternTextInputDerivedElement = HTMLElementTagNameMap[
typeof PatternTextInputDerivedElementComponent
];


/** /**
* Props of the {@link PatternTextInput} component. * Props of the {@link PatternTextInput} component.
@@ -138,7 +142,7 @@ export const PatternTextInput = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<input
<PatternTextInputDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={forwardedRef} ref={forwardedRef}


+ 6
- 2
categories/web/formatted/react/src/components/PhoneNumberInput/index.tsx View File

@@ -4,10 +4,14 @@ import { useClientSide, useFallbackId, useProxyInput } from '@modal-sh/react-uti
import PhoneInput, { Country, Value } from 'react-phone-number-input/input'; import PhoneInput, { Country, Value } from 'react-phone-number-input/input';
import clsx from 'clsx'; import clsx from 'clsx';


const PhoneNumberInputDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link PhoneNumberInput} component. * Derived HTML element of the {@link PhoneNumberInput} component.
*/ */
export type PhoneNumberInputDerivedElement = HTMLInputElement;
export type PhoneNumberInputDerivedElement = HTMLElementTagNameMap[
typeof PhoneNumberInputDerivedElementComponent
];


/** /**
* Props of the {@link PhoneNumberInput} component. * Props of the {@link PhoneNumberInput} component.
@@ -155,7 +159,7 @@ export const PhoneNumberInput = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<input
<PhoneNumberInputDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
value={value} value={value}


+ 6
- 2
categories/web/formatted/react/src/components/UrlInput/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import clsx from 'clsx'; import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const UrlInputDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link UrlInput} component. * Derived HTML element of the {@link UrlInput} component.
*/ */
export type UrlInputDerivedElement = HTMLInputElement;
export type UrlInputDerivedElement = HTMLElementTagNameMap[
typeof UrlInputDerivedElementComponent
];


/** /**
* Props of the {@link UrlInput} component. * Props of the {@link UrlInput} component.
@@ -108,7 +112,7 @@ export const UrlInput = React.forwardRef<UrlInputDerivedElement, UrlInputProps>(
{' '} {' '}
</> </>
)} )}
<input
<UrlInputDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={forwardedRef} ref={forwardedRef}


+ 6
- 2
categories/web/freeform/react/src/components/MaskedTextInput/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import clsx from 'clsx'; import clsx from 'clsx';
import { useClientSide, useFallbackId } from '@modal-sh/react-utils'; import { useClientSide, useFallbackId } from '@modal-sh/react-utils';


const MaskedTextInputDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link MaskedTextInput} component. * Derived HTML element of the {@link MaskedTextInput} component.
*/ */
export type MaskedTextInputDerivedElement = HTMLInputElement;
export type MaskedTextInputDerivedElement = HTMLElementTagNameMap[
typeof MaskedTextInputDerivedElementComponent
];


/** /**
* Props of the {@link MaskedTextInput} component. * Props of the {@link MaskedTextInput} component.
@@ -191,7 +195,7 @@ export const MaskedTextInput = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<input
<MaskedTextInputDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={typeof ref === 'function' ? defaultRef : ref} ref={typeof ref === 'function' ? defaultRef : ref}


+ 6
- 2
categories/web/freeform/react/src/components/MultilineTextInput/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import clsx from 'clsx'; import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const MultilineTextInputDerivedElementComponent = 'textarea' as const;

/** /**
* Derived HTML element of the {@link MultilineTextInput} component. * Derived HTML element of the {@link MultilineTextInput} component.
*/ */
export type MultilineTextInputDerivedElement = HTMLTextAreaElement;
export type MultilineTextInputDerivedElement = HTMLElementTagNameMap[
typeof MultilineTextInputDerivedElementComponent
];


/** /**
* Props of the {@link MultilineTextInput} component. * Props of the {@link MultilineTextInput} component.
@@ -116,7 +120,7 @@ export const MultilineTextInput = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<textarea
<MultilineTextInputDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
aria-labelledby={labelId} aria-labelledby={labelId}


+ 6
- 2
categories/web/freeform/react/src/components/TextInput/index.tsx View File

@@ -3,10 +3,14 @@ import { TextControl } from '@tesseract-design/web-base';
import clsx from 'clsx'; import clsx from 'clsx';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const TextInputDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link TextInput} component. * Derived HTML element of the {@link TextInput} component.
*/ */
export type TextInputDerivedElement = HTMLInputElement;
export type TextInputDerivedElement = HTMLElementTagNameMap[
typeof TextInputDerivedElementComponent
];


/** /**
* Props of the {@link TextInput} component. * Props of the {@link TextInput} component.
@@ -135,7 +139,7 @@ export const TextInput = React.forwardRef<TextInputDerivedElement, TextInputProp
{' '} {' '}
</> </>
)} )}
<input
<TextInputDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={forwardedRef} ref={forwardedRef}


+ 7
- 3
categories/web/information/react/src/components/Badge/index.tsx View File

@@ -1,10 +1,14 @@
import * as React from 'react'; import * as React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';


const BadgeDerivedElementComponent = 'span' as const;

/** /**
* Derived HTML element of the {@link Badge} component. * Derived HTML element of the {@link Badge} component.
*/ */
export type BadgeDerivedElement = HTMLSpanElement;
export type BadgeDerivedElement = HTMLElementTagNameMap[
typeof BadgeDerivedElementComponent
];


/** /**
* Props of the {@link Badge} component. * Props of the {@link Badge} component.
@@ -29,7 +33,7 @@ export const Badge = React.forwardRef<BadgeDerivedElement, BadgeProps>((
}, },
forwardedRef, forwardedRef,
) => ( ) => (
<span
<BadgeDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
className={clsx( className={clsx(
@@ -47,7 +51,7 @@ export const Badge = React.forwardRef<BadgeDerivedElement, BadgeProps>((
<span className="relative w-full"> <span className="relative w-full">
{children} {children}
</span> </span>
</span>
</BadgeDerivedElementComponent>
)); ));


Badge.displayName = 'Badge'; Badge.displayName = 'Badge';


+ 19
- 9
categories/web/information/react/src/components/KeyValueTable/index.tsx View File

@@ -1,10 +1,20 @@
import * as React from 'react'; import * as React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';


const KeyValueTableDerivedElementComponent = 'dl' as const;

/** /**
* Derived HTML element of the {@link KeyValueTable} component. * Derived HTML element of the {@link KeyValueTable} component.
*/ */
export type KeyValueTableDerivedElement = HTMLDListElement;
export type KeyValueTableDerivedElement = HTMLElementTagNameMap[
typeof KeyValueTableDerivedElementComponent
];

const KeyValueTablePropertyElementComponent = 'div' as const;

const KeyValueTableKeyElementComponent = 'dt' as const;

const KeyValueTableValueElementComponent = 'dd' as const;


/** /**
* Individual property of the {@link KeyValueTable} component. * Individual property of the {@link KeyValueTable} component.
@@ -51,7 +61,7 @@ export const KeyValueTable = React.forwardRef<KeyValueTableDerivedElement, KeyVa
}, },
forwardedRef, forwardedRef,
) => ( ) => (
<dl
<KeyValueTableDerivedElementComponent
{...etcProps} {...etcProps}
className={clsx( className={clsx(
'grid gap-y-1 grid-cols-3', 'grid gap-y-1 grid-cols-3',
@@ -61,16 +71,16 @@ export const KeyValueTable = React.forwardRef<KeyValueTableDerivedElement, KeyVa
style={style} style={style}
> >
{properties.map((property) => typeof property === 'object' && property && ( {properties.map((property) => typeof property === 'object' && property && (
<div
<KeyValueTablePropertyElementComponent
key={property.key} key={property.key}
className={clsx('contents', property.className)} className={clsx('contents', property.className)}
> >
<dt
<KeyValueTableKeyElementComponent
className={clsx(hiddenKeys && 'sr-only', 'pr-4')} className={clsx(hiddenKeys && 'sr-only', 'pr-4')}
> >
{property.key} {property.key}
</dt>
<dd
</KeyValueTableKeyElementComponent>
<KeyValueTableValueElementComponent
{...(property.valueProps ?? {})} {...(property.valueProps ?? {})}
className={clsx( className={clsx(
'm-0 text-ellipsis overflow-hidden', 'm-0 text-ellipsis overflow-hidden',
@@ -80,10 +90,10 @@ export const KeyValueTable = React.forwardRef<KeyValueTableDerivedElement, KeyVa
)} )}
> >
{property.valueProps?.children} {property.valueProps?.children}
</dd>
</div>
</KeyValueTableValueElementComponent>
</KeyValueTablePropertyElementComponent>
))} ))}
</dl>
</KeyValueTableDerivedElementComponent>
)); ));


KeyValueTable.displayName = 'KeyValueTable'; KeyValueTable.displayName = 'KeyValueTable';


+ 6
- 2
categories/web/multichoice/react/src/components/MenuMultiSelect/index.tsx View File

@@ -4,10 +4,14 @@ import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const MenuMultiSelectDerivedElementComponent = 'select' as const;

/** /**
* Derived HTML element of the {@link MenuMultiSelect} component. * Derived HTML element of the {@link MenuMultiSelect} component.
*/ */
export type MenuMultiSelectDerivedElement = HTMLSelectElement;
export type MenuMultiSelectDerivedElement = HTMLElementTagNameMap[
typeof MenuMultiSelectDerivedElementComponent
];


/** /**
* Props of the {@link MenuMultiSelect} component. * Props of the {@link MenuMultiSelect} component.
@@ -144,7 +148,7 @@ export const MenuMultiSelect = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<select
<MenuMultiSelectDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
id={id} id={id}


+ 12
- 6
categories/web/multichoice/react/src/components/TagInput/index.tsx View File

@@ -24,10 +24,14 @@ const TAG_INPUT_VALUE_SEPARATOR_MAP: Record<TagInputSeparator, string> = {
'semicolon': ';', 'semicolon': ';',
} as const; } as const;


const TagInputDerivedElementComponent = ['textarea', 'input'] as const;

/** /**
* Derived HTML element of the {@link TagInput} component. * Derived HTML element of the {@link TagInput} component.
*/ */
export type TagInputDerivedElement = HTMLTextAreaElement | HTMLInputElement;
export type TagInputDerivedElement = HTMLElementTagNameMap[
typeof TagInputDerivedElementComponent[number]
];


/** /**
* Proxied HTML element of the {@link TagInput} component. * Proxied HTML element of the {@link TagInput} component.
@@ -85,7 +89,7 @@ export interface TagInputProps extends Omit<React.HTMLProps<TagInputDerivedEleme
/** /**
* Fallback element for non-enhanced mode. * Fallback element for non-enhanced mode.
*/ */
fallbackElement?: 'textarea' | 'input',
fallbackElement?: typeof TagInputDerivedElementComponent[number],
/** /**
* Separator used on the value of the input. * Separator used on the value of the input.
*/ */
@@ -236,12 +240,14 @@ export const TagInput = React.forwardRef<TagInputDerivedElement, TagInputProps>(
onBlur, onBlur,
editOnRemove = false as const, editOnRemove = false as const,
placeholder, placeholder,
fallbackElement: FallbackElement = 'textarea' as const,
fallbackElement: FallbackElement = TagInputDerivedElementComponent[0],
...etcProps ...etcProps
}, },
forwardedRef, forwardedRef,
) => { ) => {
const EffectiveFallbackElement = valueSeparator === 'newline' ? 'textarea' : FallbackElement;
const EffectiveFallbackElement = valueSeparator === 'newline'
? TagInputDerivedElementComponent[0]
: FallbackElement;
const { clientSide } = useClientSide({ clientSide: enhancedProp }); const { clientSide } = useClientSide({ clientSide: enhancedProp });
const [tags, setTags] = React.useState<string[]>(() => { const [tags, setTags] = React.useState<string[]>(() => {
const effectiveValue = value ?? defaultValue; const effectiveValue = value ?? defaultValue;
@@ -537,12 +543,12 @@ TagInput.defaultProps = {
indicator: undefined, indicator: undefined,
size: 'medium' as const, size: 'medium' as const,
variant: 'default' as const, variant: 'default' as const,
separator: ['newline'],
separator: ['newline' as const],
border: false as const, border: false as const,
block: false as const, block: false as const,
hiddenLabel: false as const, hiddenLabel: false as const,
enhanced: false as const, enhanced: false as const,
editOnRemove: false as const, editOnRemove: false as const,
fallbackElement: 'textarea' as const,
fallbackElement: TagInputDerivedElementComponent[0],
valueSeparator: 'newline' as const, valueSeparator: 'newline' as const,
}; };

+ 6
- 2
categories/web/multichoice/react/src/components/ToggleButton/index.tsx View File

@@ -4,10 +4,14 @@ import { Button } from '@tesseract-design/web-base';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const ToggleButtonDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link ToggleButton} component. * Derived HTML element of the {@link ToggleButton} component.
*/ */
export type ToggleButtonDerivedElement = HTMLInputElement;
export type ToggleButtonDerivedElement = HTMLElementTagNameMap[
typeof ToggleButtonDerivedElementComponent
];


/** /**
* Props of the {@link ToggleButton} component. * Props of the {@link ToggleButton} component.
@@ -101,7 +105,7 @@ export const ToggleButton = React.forwardRef<ToggleButtonDerivedElement, ToggleB
<span <span
className="contents" className="contents"
> >
<input
<ToggleButtonDerivedElementComponent
{...etcProps} {...etcProps}
ref={typeof ref === 'function' ? defaultRef : ref} ref={typeof ref === 'function' ? defaultRef : ref}
type="checkbox" type="checkbox"


+ 6
- 2
categories/web/multichoice/react/src/components/ToggleSwitch/index.tsx View File

@@ -3,10 +3,14 @@ import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const ToggleSwitchDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link ToggleSwitch} component. * Derived HTML element of the {@link ToggleSwitch} component.
*/ */
export type ToggleSwitchDerivedElement = HTMLInputElement;
export type ToggleSwitchDerivedElement = HTMLElementTagNameMap[
typeof ToggleSwitchDerivedElementComponent
];


/** /**
* Props of the {@link ToggleSwitch} component. * Props of the {@link ToggleSwitch} component.
@@ -198,7 +202,7 @@ export const ToggleSwitch = React.forwardRef<ToggleSwitchDerivedElement, ToggleS
style={style} style={style}
data-testid="base" data-testid="base"
> >
<input
<ToggleSwitchDerivedElementComponent
{...etcProps} {...etcProps}
ref={typeof ref === 'function' ? defaultRef : ref} ref={typeof ref === 'function' ? defaultRef : ref}
type="checkbox" type="checkbox"


+ 6
- 2
categories/web/multichoice/react/src/components/ToggleTickBox/index.tsx View File

@@ -3,10 +3,14 @@ import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const ToggleTickBoxDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link ToggleTickBox} component. * Derived HTML element of the {@link ToggleTickBox} component.
*/ */
export type ToggleTickBoxDerivedElement = HTMLInputElement;
export type ToggleTickBoxDerivedElement = HTMLElementTagNameMap[
typeof ToggleTickBoxDerivedElementComponent
];


/** /**
* Props of the {@link ToggleTickBox} component. * Props of the {@link ToggleTickBox} component.
@@ -87,7 +91,7 @@ export const ToggleTickBox = React.forwardRef<ToggleTickBoxDerivedElement, Toggl
style={style} style={style}
data-testid="base" data-testid="base"
> >
<input
<ToggleTickBoxDerivedElementComponent
{...etcProps} {...etcProps}
ref={typeof ref === 'function' ? defaultRef : ref} ref={typeof ref === 'function' ? defaultRef : ref}
type="checkbox" type="checkbox"


+ 9
- 5
categories/web/navigation/react/src/components/LinkButton/index.tsx View File

@@ -2,10 +2,14 @@ import * as React from 'react';
import clsx from 'clsx'; import clsx from 'clsx';
import { Button } from '@tesseract-design/web-base'; import { Button } from '@tesseract-design/web-base';


const LinkButtonDerivedElementComponent = 'a' as const;

/** /**
* Derived HTML element of the {@link LinkButton} component. * Derived HTML element of the {@link LinkButton} component.
*/ */
export type LinkButtonDerivedElement = HTMLAnchorElement;
export type LinkButtonDerivedElement = HTMLElementTagNameMap[
typeof LinkButtonDerivedElementComponent
];


interface LinkButtonCommonProps extends Omit<React.HTMLProps<LinkButtonDerivedElement>, 'href' | 'size'> { interface LinkButtonCommonProps extends Omit<React.HTMLProps<LinkButtonDerivedElement>, 'href' | 'size'> {
/** /**
@@ -51,7 +55,7 @@ interface LinkButtonCommonProps extends Omit<React.HTMLProps<LinkButtonDerivedEl
} }


interface LinkButtonAnchorProps extends Pick<React.HTMLProps<LinkButtonDerivedElement>, 'href'> { interface LinkButtonAnchorProps extends Pick<React.HTMLProps<LinkButtonDerivedElement>, 'href'> {
component: 'a';
component: typeof LinkButtonDerivedElementComponent;
} }


interface LinkButtonComponentType { interface LinkButtonComponentType {
@@ -92,7 +96,7 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP
compact = false, compact = false,
className, className,
block = false, block = false,
component: EnabledComponent = 'a' as const,
component: EnabledComponent = LinkButtonDerivedElementComponent,
disabled = false, disabled = false,
href, href,
style, style,
@@ -102,7 +106,7 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP
}, },
forwardedRef, forwardedRef,
) => { ) => {
const Component = (disabled ? 'button' : EnabledComponent) as 'a';
const Component = (disabled ? 'button' : EnabledComponent) as typeof LinkButtonDerivedElementComponent;
const extraProps = { const extraProps = {
disabled: disabled || undefined, disabled: disabled || undefined,
}; };
@@ -237,7 +241,7 @@ LinkButton.defaultProps = {
icon: undefined, icon: undefined,
iconAfterChildren: false as const, iconAfterChildren: false as const,
// eslint-disable-next-line react/default-props-match-prop-types // eslint-disable-next-line react/default-props-match-prop-types
component: 'a' as const,
component: LinkButtonDerivedElementComponent,
// eslint-disable-next-line react/default-props-match-prop-types // eslint-disable-next-line react/default-props-match-prop-types
href: undefined, href: undefined,
}; };


+ 15
- 5
categories/web/number/react/src/components/NumberSpinner/index.tsx View File

@@ -4,10 +4,20 @@ import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useBrowser, useClientSide, useFallbackId } from '@modal-sh/react-utils'; import { useBrowser, useClientSide, useFallbackId } from '@modal-sh/react-utils';


const NumberSpinnerDerivedElementComponent = 'input' as const;

/** /**
* Derived HTML element of the {@link NumberSpinner} component. * Derived HTML element of the {@link NumberSpinner} component.
*/ */
export type NumberSpinnerDerivedElement = HTMLInputElement;
export type NumberSpinnerDerivedElement = HTMLElementTagNameMap[
typeof NumberSpinnerDerivedElementComponent
];

const NumberSpinnerActionElementComponent = 'button' as const;

type NumberSpinnerActionElement = HTMLElementTagNameMap[
typeof NumberSpinnerActionElementComponent
];


/** /**
* Props of the {@link NumberSpinner} component. * Props of the {@link NumberSpinner} component.
@@ -151,7 +161,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe
return clickYRef.current < spinnerYRef.current; return clickYRef.current < spinnerYRef.current;
}; };


const doStepMouse: React.MouseEventHandler<HTMLButtonElement> = (e) => {
const doStepMouse: React.MouseEventHandler<NumberSpinnerActionElement> = (e) => {
if (spinEventSource.current === 'keyboard') { if (spinEventSource.current === 'keyboard') {
return; return;
} }
@@ -285,7 +295,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe
{' '} {' '}
</> </>
)} )}
<input
<NumberSpinnerDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={typeof ref === 'function' ? defaultRef : ref} ref={typeof ref === 'function' ? defaultRef : ref}
@@ -357,7 +367,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe
</div> </div>
)} )}
{indicator && ( {indicator && (
<button
<NumberSpinnerActionElementComponent
data-testid="indicator" data-testid="indicator"
type="button" type="button"
className={clsx( className={clsx(
@@ -413,7 +423,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe
Step Down Step Down
</span> </span>
</span> </span>
</button>
</NumberSpinnerActionElementComponent>
)} )}
{border && ( {border && (
<span <span


+ 8
- 4
categories/web/number/react/src/components/Slider/index.tsx View File

@@ -43,15 +43,19 @@ export const AVAILABLE_SLIDER_ORIENTATIONS = ['horizontal', 'vertical'] as const
*/ */
export type SliderOrientation = typeof AVAILABLE_SLIDER_ORIENTATIONS[number]; export type SliderOrientation = typeof AVAILABLE_SLIDER_ORIENTATIONS[number];


const SliderDerivedElementComponent = 'input';

/** /**
* Derived HTML element of the {@link Slider} component. * Derived HTML element of the {@link Slider} component.
*/ */
export type SliderDerivedElement = HTMLInputElement;
export type SliderDerivedElement = HTMLElementTagNameMap[
typeof SliderDerivedElementComponent
];


/** /**
* Props of the {@link Slider} component. * Props of the {@link Slider} component.
*/ */
export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type'> {
export interface SliderProps extends Omit<React.HTMLProps<SliderDerivedElement>, 'type'> {
/** /**
* Orientation of the component. * Orientation of the component.
*/ */
@@ -245,7 +249,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>((
forwardedRef, forwardedRef,
) => { ) => {
const browser = useBrowser(); const browser = useBrowser();
const defaultRef = React.useRef<HTMLInputElement>(null);
const defaultRef = React.useRef<SliderDerivedElement>(null);
const ref = forwardedRef ?? defaultRef; const ref = forwardedRef ?? defaultRef;
const tickMarkId = React.useId(); const tickMarkId = React.useId();


@@ -454,7 +458,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>((
className="flex slider" className="flex slider"
data-orient={orient} data-orient={orient}
> >
<input
<SliderDerivedElementComponent
{...etcProps} {...etcProps}
ref={ref} ref={ref}
min={minValue} min={minValue}


+ 6
- 2
categories/web/temporal/react/src/components/DateDropdown/index.tsx View File

@@ -4,10 +4,14 @@ import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const DateDropdownDerivedElementComponent = 'input';

/** /**
* Derived HTML element of the {@link DateDropdown} component. * Derived HTML element of the {@link DateDropdown} component.
*/ */
export type DateDropdownDerivedElement = HTMLInputElement;
export type DateDropdownDerivedElement = HTMLElementTagNameMap[
typeof DateDropdownDerivedElementComponent
];


/** /**
* Props of the {@link DateDropdown} component. * Props of the {@link DateDropdown} component.
@@ -139,7 +143,7 @@ export const DateDropdown = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<input
<DateDropdownDerivedElementComponent
{...etcProps} {...etcProps}
size={length} size={length}
ref={forwardedRef} ref={forwardedRef}


+ 6
- 2
categories/web/temporal/react/src/components/TimeSpinner/index.tsx View File

@@ -4,10 +4,14 @@ import clsx from 'clsx';
import { PluginCreator } from 'tailwindcss/types/config'; import { PluginCreator } from 'tailwindcss/types/config';
import { useFallbackId } from '@modal-sh/react-utils'; import { useFallbackId } from '@modal-sh/react-utils';


const TimeSpinnerDerivedElementComponent = 'input';

/** /**
* Derived HTML element of the {@link TimeSpinner} component. * Derived HTML element of the {@link TimeSpinner} component.
*/ */
export type TimeSpinnerDerivedElement = HTMLInputElement;
export type TimeSpinnerDerivedElement = HTMLElementTagNameMap[
typeof TimeSpinnerDerivedElementComponent
];


type Digit = (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9); type Digit = (0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9);


@@ -161,7 +165,7 @@ export const TimeSpinner = React.forwardRef<
{' '} {' '}
</> </>
)} )}
<input
<TimeSpinnerDerivedElementComponent
{...etcProps} {...etcProps}
ref={forwardedRef} ref={forwardedRef}
id={id} id={id}


Loading…
Cancel
Save