Skip to content

Instantly share code, notes, and snippets.

@Evanion
Created November 19, 2024 08:05
Show Gist options
  • Save Evanion/edee156e2e9423e67ee8edfec77dc730 to your computer and use it in GitHub Desktop.
Save Evanion/edee156e2e9423e67ee8edfec77dc730 to your computer and use it in GitHub Desktop.
Input decorator
import 'reflect-metadata';
import { InputHTMLAttributes } from 'react';
import { ClassConstructor } from 'class-transformer';
export type InputOptions = Omit<
InputHTMLAttributes<HTMLInputElement>,
'name'
> & {
label?: string;
};
const defaultOptions: InputOptions = {
type: 'text',
};
/**
* Property decorator for input fields
* @param props
* @returns
*/
export function Input(props: InputOptions): PropertyDecorator {
return (target: Object, propertyKey: string | symbol) => {
// First we need to register the property as a field on the class
// This is done by adding a metadata key to the class prototype
// The metadata key is `fields` and the value is an array of field names
const fields = Reflect.getMetadata('fields', target) || [];
Reflect.defineMetadata('fields', [...fields, propertyKey], target);
// Get the fieldType for the property
const propertyType = Reflect.getMetadata(
'design:type',
target,
propertyKey
);
if (!propertyType) {
console.warn(
`Property type metadata is undefined for ${String(propertyKey)}`
);
}
// Determine the type (string, number, boolean, etc.)
const dataType = typeof propertyType;
// set some default values
const defaultProps = { ...defaultOptions, dataType, ...props };
// Next we need to store the field metadata on the property itself
Reflect.defineMetadata('field', defaultProps, target, propertyKey);
};
}
export function getFields<Schema extends ClassConstructor<Object>>(
schema: Schema
) {
const fields = Reflect.getMetadata('fields', schema.prototype);
const fieldsData = fields.map((name: string) => {
const fieldData = Reflect.getMetadata('field', schema.prototype, name);
return { name, ...fieldData };
});
return fieldsData;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment