aboutsummaryrefslogtreecommitdiff
path: root/admin/src/components/CheckboxListEnumInput.tsx
blob: 0a1ac733203075c328eddeea7298460b6a03be6a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import type { ChangeEvent, ReactNode } from 'react';

import { Field, Textarea } from '@strapi/design-system';
import { useIntl } from 'react-intl';

type CheckboxListEnumInputProps = {
  name: string;
  value?: unknown;
  onChange: (eventOrPath: { target: { name: string; value: string[] } }, value?: unknown) => void;
  intlLabel: {
    id: string;
    defaultMessage: string;
    values?: Record<string, string | number | boolean | null | undefined>;
  };
  description?: {
    id: string;
    defaultMessage: string;
    values?: Record<string, string | number | boolean | null | undefined>;
  } | null;
  labelAction?: ReactNode;
  placeholder?: {
    id: string;
    defaultMessage: string;
    values?: Record<string, string | number | boolean | null | undefined>;
  } | null;
  disabled?: boolean;
  error?: string;
  modifiedData?: {
    enum?: string[];
    options?: {
      enum?: string[];
    };
  };
};

const normalizeEnum = (value: unknown): string[] => {
  if (Array.isArray(value)) {
    return value.filter((item): item is string => typeof item === 'string');
  }

  return [];
};

const CheckboxListEnumInput = ({
  description = null,
  disabled = false,
  error = '',
  intlLabel,
  labelAction,
  name,
  onChange,
  placeholder = null,
  value,
  modifiedData,
}: CheckboxListEnumInputProps) => {
  const { formatMessage } = useIntl();

  const fallbackEnum = normalizeEnum(modifiedData?.enum);
  const resolvedEnum = normalizeEnum(value).length > 0 ? normalizeEnum(value) : fallbackEnum;

  const errorMessage = error
    ? formatMessage({
        id: error,
        defaultMessage: error,
      })
    : '';

  const hint = description
    ? formatMessage(
        {
          id: description.id,
          defaultMessage: description.defaultMessage,
        },
        description.values
      )
    : '';

  const label = formatMessage(intlLabel, intlLabel.values ?? {});
  const formattedPlaceholder = placeholder
    ? formatMessage(
        {
          id: placeholder.id,
          defaultMessage: placeholder.defaultMessage,
        },
        placeholder.values
      )
    : '';

  const inputValue = resolvedEnum.join('\n');

  const handleChange = (event: ChangeEvent<HTMLTextAreaElement>) => {
    const arrayValue = event.target.value.split('\n');

    onChange({
      target: {
        name,
        value: arrayValue,
      },
    });

    if (name !== 'enum') {
      onChange({
        target: {
          name: 'enum',
          value: arrayValue,
        },
      });
    }
  };

  return (
    <Field.Root error={errorMessage} hint={hint} name={name}>
      <Field.Label action={labelAction}>{label}</Field.Label>
      <Textarea
        disabled={disabled}
        onChange={handleChange}
        placeholder={formattedPlaceholder}
        value={inputValue}
      />
      <Field.Error />
      <Field.Hint />
    </Field.Root>
  );
};

export { CheckboxListEnumInput };