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 { Button } from '@tesseract-design/web-base';

const ActionButtonDerivedElementComponent = 'button' as const;

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

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

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 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
@@ -29,57 +27,9 @@ export interface CommonPreviewComponentProps<F extends Partial<File> = Partial<F
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}
@@ -94,7 +44,7 @@ export const FileSelectBoxDefaultPreviewComponent = React.forwardRef<
enhanced,
disabled,
}, forwardedRef) => (
<div
<FileSelectBoxDefaultPreviewComponentDerivedElementComponent
data-enhanced={enhanced}
className={clsx({
'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';

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

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

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

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

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

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

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

return (
<div
<FileSelectBoxRootElementComponent
className={clsx(
'relative rounded ring-secondary/50 group file-select-box',
'focus-within:ring-4',
@@ -401,7 +415,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
</label>
)}
{clientSide && (
<button
<FileSelectBoxActionElementComponent
type="button"
disabled={disabled}
tabIndex={-1}
@@ -414,9 +428,9 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
onMouseUp={handleReselectMouseUp}
>
{placeholder}
</button>
</FileSelectBoxActionElementComponent>
)}
<input
<FileSelectBoxDerivedElementComponent
{...etcProps}
id={id}
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"
>
<div className="w-0 flex-auto flex flex-col items-center justify-center h-full">
<button
<FileSelectBoxActionElementComponent
type="button"
data-testid="reselect"
disabled={disabled}
@@ -533,10 +547,10 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
>
{reselectLabel}
</span>
</button>
</FileSelectBoxActionElementComponent>
</div>
<div className="w-0 flex-auto flex flex-col items-center justify-center h-full">
<button
<FileSelectBoxActionElementComponent
disabled={disabled}
data-testid="clear"
type="button"
@@ -558,7 +572,7 @@ export const FileSelectBox = React.forwardRef<FileSelectBoxDerivedElement, FileS
>
{clearLabel}
</span>
</button>
</FileSelectBoxActionElementComponent>
</div>
</div>
</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"
/>
)}
</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 clsx from 'clsx';

const ComboBoxDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link ComboBox} component.
@@ -143,7 +147,7 @@ export const ComboBox = React.forwardRef<ComboBoxDerivedElement, ComboBoxProps>(
{' '}
</>
)}
<input
<ComboBoxDerivedElementComponent
{...etcProps}
size={length}
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 { PluginCreator } from 'tailwindcss/types/config';

const DropdownSelectDerivedElementComponent = 'select' as const;

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

/**
* Props of the {@link DropdownSelect} component.
@@ -127,7 +131,7 @@ export const DropdownSelect = React.forwardRef<DropdownSelectDerivedElement, Dro
{' '}
</>
)}
<select
<DropdownSelectDerivedElementComponent
{...etcProps}
ref={forwardedRef}
id={id}
@@ -150,7 +154,7 @@ export const DropdownSelect = React.forwardRef<DropdownSelectDerivedElement, Dro
)}
>
{children}
</select>
</DropdownSelectDerivedElementComponent>
{hint && (
<div
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 { PluginCreator } from 'tailwindcss/types/config';

const MenuSelectDerivedElementComponent = 'select' as const;

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

/**
* Props of the {@link MenuSelect} component.
@@ -137,7 +141,7 @@ export const MenuSelect = React.forwardRef<MenuSelectDerivedElement, MenuSelectP
{' '}
</>
)}
<select
<MenuSelectDerivedElementComponent
{...etcProps}
ref={forwardedRef}
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 { PluginCreator } from 'tailwindcss/types/config';

const RadioButtonDerivedElementComponent = 'input' as const;

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

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

return (
<span
className="contents"
>
<input
className="contents"
>
<RadioButtonDerivedElementComponent
{...etcProps}
ref={forwardedRef}
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 { PluginCreator } from 'tailwindcss/types/config';

const RadioTickBoxDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link RadioTickBox} component.
@@ -65,7 +69,7 @@ export const RadioTickBox = React.forwardRef<RadioTickBoxDerivedElement, RadioTi
style={style}
data-testid="base"
>
<input
<RadioTickBoxDerivedElementComponent
{...etcProps}
ref={forwardedRef}
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 { PluginCreator } from 'tailwindcss/types/config';

const ColorPickerDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link ColorPicker} component.
@@ -75,7 +79,7 @@ export const ColorPicker = React.forwardRef<
},
)}
>
<input
<ColorPickerDerivedElementComponent
{...etcProps}
className={clsx(
'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 * as convert from 'color-convert';

const SwatchDerivedElementComponent = 'input' as const;

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

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

@@ -56,7 +60,7 @@ export const Swatch = React.forwardRef<SwatchDerivedElement, SwatchProps>(({
)}
style={style}
>
<input
<SwatchDerivedElementComponent
{...etcProps}
ref={forwardedRef}
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 { useFallbackId } from '@modal-sh/react-utils';

const EmailInputDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link EmailInput} component.
@@ -124,7 +128,7 @@ export const EmailInput = React.forwardRef<EmailInputDerivedElement, EmailInputP
{' '}
</>
)}
<input
<EmailInputDerivedElementComponent
{...etcProps}
size={length}
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 { useFallbackId } from '@modal-sh/react-utils';

const PatternTextInputDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link PatternTextInput} component.
@@ -138,7 +142,7 @@ export const PatternTextInput = React.forwardRef<
{' '}
</>
)}
<input
<PatternTextInputDerivedElementComponent
{...etcProps}
size={length}
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 clsx from 'clsx';

const PhoneNumberInputDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link PhoneNumberInput} component.
@@ -155,7 +159,7 @@ export const PhoneNumberInput = React.forwardRef<
{' '}
</>
)}
<input
<PhoneNumberInputDerivedElementComponent
{...etcProps}
size={length}
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 { useFallbackId } from '@modal-sh/react-utils';

const UrlInputDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link UrlInput} component.
@@ -108,7 +112,7 @@ export const UrlInput = React.forwardRef<UrlInputDerivedElement, UrlInputProps>(
{' '}
</>
)}
<input
<UrlInputDerivedElementComponent
{...etcProps}
size={length}
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 { useClientSide, useFallbackId } from '@modal-sh/react-utils';

const MaskedTextInputDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link MaskedTextInput} component.
@@ -191,7 +195,7 @@ export const MaskedTextInput = React.forwardRef<
{' '}
</>
)}
<input
<MaskedTextInputDerivedElementComponent
{...etcProps}
size={length}
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 { useFallbackId } from '@modal-sh/react-utils';

const MultilineTextInputDerivedElementComponent = 'textarea' as const;

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

/**
* Props of the {@link MultilineTextInput} component.
@@ -116,7 +120,7 @@ export const MultilineTextInput = React.forwardRef<
{' '}
</>
)}
<textarea
<MultilineTextInputDerivedElementComponent
{...etcProps}
ref={forwardedRef}
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 { useFallbackId } from '@modal-sh/react-utils';

const TextInputDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link TextInput} component.
@@ -135,7 +139,7 @@ export const TextInput = React.forwardRef<TextInputDerivedElement, TextInputProp
{' '}
</>
)}
<input
<TextInputDerivedElementComponent
{...etcProps}
size={length}
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 clsx from 'clsx';

const BadgeDerivedElementComponent = 'span' as const;

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

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

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 clsx from 'clsx';

const KeyValueTableDerivedElementComponent = 'dl' as const;

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

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 { useFallbackId } from '@modal-sh/react-utils';

const MenuMultiSelectDerivedElementComponent = 'select' as const;

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

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

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

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

const ToggleButtonDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link ToggleButton} component.
@@ -101,7 +105,7 @@ export const ToggleButton = React.forwardRef<ToggleButtonDerivedElement, ToggleB
<span
className="contents"
>
<input
<ToggleButtonDerivedElementComponent
{...etcProps}
ref={typeof ref === 'function' ? defaultRef : ref}
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 { useFallbackId } from '@modal-sh/react-utils';

const ToggleSwitchDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link ToggleSwitch} component.
@@ -198,7 +202,7 @@ export const ToggleSwitch = React.forwardRef<ToggleSwitchDerivedElement, ToggleS
style={style}
data-testid="base"
>
<input
<ToggleSwitchDerivedElementComponent
{...etcProps}
ref={typeof ref === 'function' ? defaultRef : ref}
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 { useFallbackId } from '@modal-sh/react-utils';

const ToggleTickBoxDerivedElementComponent = 'input' as const;

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

/**
* Props of the {@link ToggleTickBox} component.
@@ -87,7 +91,7 @@ export const ToggleTickBox = React.forwardRef<ToggleTickBoxDerivedElement, Toggl
style={style}
data-testid="base"
>
<input
<ToggleTickBoxDerivedElementComponent
{...etcProps}
ref={typeof ref === 'function' ? defaultRef : ref}
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 { Button } from '@tesseract-design/web-base';

const LinkButtonDerivedElementComponent = 'a' as const;

/**
* 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'> {
/**
@@ -51,7 +55,7 @@ interface LinkButtonCommonProps extends Omit<React.HTMLProps<LinkButtonDerivedEl
}

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

interface LinkButtonComponentType {
@@ -92,7 +96,7 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP
compact = false,
className,
block = false,
component: EnabledComponent = 'a' as const,
component: EnabledComponent = LinkButtonDerivedElementComponent,
disabled = false,
href,
style,
@@ -102,7 +106,7 @@ export const LinkButton = React.forwardRef<LinkButtonDerivedElement, LinkButtonP
},
forwardedRef,
) => {
const Component = (disabled ? 'button' : EnabledComponent) as 'a';
const Component = (disabled ? 'button' : EnabledComponent) as typeof LinkButtonDerivedElementComponent;
const extraProps = {
disabled: disabled || undefined,
};
@@ -237,7 +241,7 @@ LinkButton.defaultProps = {
icon: undefined,
iconAfterChildren: false as const,
// 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
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 { useBrowser, useClientSide, useFallbackId } from '@modal-sh/react-utils';

const NumberSpinnerDerivedElementComponent = 'input' as const;

/**
* 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.
@@ -151,7 +161,7 @@ export const NumberSpinner = React.forwardRef<NumberSpinnerDerivedElement, Numbe
return clickYRef.current < spinnerYRef.current;
};

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

const SliderDerivedElementComponent = 'input';

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

/**
* 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.
*/
@@ -245,7 +249,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>((
forwardedRef,
) => {
const browser = useBrowser();
const defaultRef = React.useRef<HTMLInputElement>(null);
const defaultRef = React.useRef<SliderDerivedElement>(null);
const ref = forwardedRef ?? defaultRef;
const tickMarkId = React.useId();

@@ -454,7 +458,7 @@ export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>((
className="flex slider"
data-orient={orient}
>
<input
<SliderDerivedElementComponent
{...etcProps}
ref={ref}
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 { useFallbackId } from '@modal-sh/react-utils';

const DateDropdownDerivedElementComponent = 'input';

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

/**
* Props of the {@link DateDropdown} component.
@@ -139,7 +143,7 @@ export const DateDropdown = React.forwardRef<
{' '}
</>
)}
<input
<DateDropdownDerivedElementComponent
{...etcProps}
size={length}
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 { useFallbackId } from '@modal-sh/react-utils';

const TimeSpinnerDerivedElementComponent = 'input';

/**
* 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);

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


Loading…
Cancel
Save