Skip to content

Commit

Permalink
Add Currency form field
Browse files Browse the repository at this point in the history
  • Loading branch information
martmull committed Jan 6, 2025
1 parent 059c4ab commit a35332f
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ import { FormRawJsonFieldInput } from '@/object-record/record-field/form-types/c
import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput';
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
import { FormUuidFieldInput } from '@/object-record/record-field/form-types/components/FormUuidFieldInput';
import { FormCurrencyFieldInput } from '@/object-record/record-field/form-types/components/FormCurrencyFieldInput';
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinition';
import {
FieldAddressValue,
FieldCurrencyValue,
FieldEmailsValue,
FieldFullNameValue,
FieldLinksValue,
Expand All @@ -37,6 +39,7 @@ import { isFieldRawJson } from '@/object-record/record-field/types/guards/isFiel
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
import { isFieldUuid } from '@/object-record/record-field/types/guards/isFieldUuid';
import { isFieldCurrency } from '@/object-record/record-field/types/guards/isFieldCurrency';
import { JsonValue } from 'type-fest';

type FormFieldInputProps = {
Expand Down Expand Up @@ -157,5 +160,12 @@ export const FormFieldInput = ({
placeholder={field.label}
VariablePicker={VariablePicker}
/>
) : isFieldCurrency(field) ? (
<FormCurrencyFieldInput
label={field.label}
defaultValue={defaultValue as FieldCurrencyValue | null}
onPersist={onPersist}
VariablePicker={VariablePicker}
/>
) : null;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useMemo } from 'react';
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata';
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
import { InputLabel } from '@/ui/input/components/InputLabel';
import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer';
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput';
import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes';

type FormCurrencyFieldInputProps = {
label?: string;
defaultValue?: FieldCurrencyValue | null;
onPersist: (value: {
currencyCode: CurrencyCode;
amountMicros: number | string | null;
}) => void;
VariablePicker?: VariablePickerComponent;
};

export const FormCurrencyFieldInput = ({
label,
defaultValue,
onPersist,
VariablePicker,
}: FormCurrencyFieldInputProps) => {
const currencies = useMemo(() => {
return Object.entries(SETTINGS_FIELD_CURRENCY_CODES).map(
([key, { Icon, label }]) => ({
value: key,
icon: Icon,
label: `${label} (${key})`,
}),
);
}, []);

const handleAmountMicrosChange = (
newAmountMicros: string | number | null,
) => {
onPersist({
currencyCode: (defaultValue?.currencyCode ?? '') as CurrencyCode,
amountMicros: newAmountMicros ?? '',
});
};

const handleCurrencyCodeChange = (newCurrencyCode: string | null) => {
onPersist({
currencyCode: (newCurrencyCode ?? '') as CurrencyCode,
amountMicros: defaultValue?.amountMicros ?? null,
});
};

return (
<FormFieldInputContainer>
{label ? <InputLabel>{label}</InputLabel> : null}
<FormNestedFieldInputContainer>
<FormSelectFieldInput
label="Currency Code"
defaultValue={defaultValue?.currencyCode ?? ''}
onPersist={handleCurrencyCodeChange}
options={currencies}
clearLabel={'Currency Code'}
VariablePicker={VariablePicker}
/>
<FormNumberFieldInput
label="Amount Micros"
defaultValue={defaultValue?.amountMicros ?? ''}
onPersist={handleAmountMicrosChange}
VariablePicker={VariablePicker}
placeholder="Set 3210000 for 3.21$"
/>
</FormNestedFieldInputContainer>
</FormFieldInputContainer>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { FormCurrencyFieldInput } from '../FormCurrencyFieldInput';
import { Meta, StoryObj } from '@storybook/react';
import { FieldCurrencyValue } from '@/object-record/record-field/types/FieldMetadata';
import { CurrencyCode } from '@/object-record/record-field/types/CurrencyCode';
import { within } from '@storybook/test';

const meta: Meta<typeof FormCurrencyFieldInput> = {
title: 'UI/Data/Field/Form/Input/FormCurrencyFieldInput',
component: FormCurrencyFieldInput,
args: {},
argTypes: {},
};

export default meta;

type Story = StoryObj<typeof FormCurrencyFieldInput>;

const defaultSalaryValue: FieldCurrencyValue = {
currencyCode: CurrencyCode.USD,
amountMicros: 44000000,
};

export const Default: Story = {
args: {
label: 'Salary',
defaultValue: defaultSalaryValue,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
await canvas.findByText('Currency Code');
await canvas.findByText('Amount Micros');
},
};

0 comments on commit a35332f

Please sign in to comment.