@homefile/components-v2 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
1
  import { DynamicFormI } from '../../../interfaces';
2
- export declare const DynamicForm: ({ callback, displayImages, form: fields, menuItems, onRemoveImage, onUpload, showTitle, title, uploadingFieldId, ...props }: DynamicFormI) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const DynamicForm: ({ callback, displayImages, form: fields, menuItems, onAISend, onRemoveImage, onUpload, showTitle, title, uploadingFieldId, ...props }: DynamicFormI) => import("react/jsx-runtime").JSX.Element;
@@ -14,11 +14,11 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
14
14
  import { FormProvider } from 'react-hook-form';
15
15
  import { t } from 'i18next';
16
16
  import { Box, Stack, Text } from '@chakra-ui/react';
17
- import { HiddenFieldSection, GroupField, TextField, TextAreaField, SelectField, RatingField, GridField, FieldWithDelete, FileField, SwitchField, DateField, NumberField, CurrencyField, TileBody, CheckboxGroupField, CheckboxAgreement, } from '../..';
17
+ import { HiddenFieldSection, GroupField, TextField, TextAreaField, SelectField, RatingField, GridField, FieldWithDelete, FileField, SwitchField, DateField, NumberField, CurrencyField, TileBody, CheckboxGroupField, CheckboxAgreement, AIGridField, } from '../..';
18
18
  import { useDynamicForm } from '../../../hooks';
19
19
  import { fieldIcons } from '../../../helpers';
20
20
  export const DynamicForm = (_a) => {
21
- var { callback, displayImages, form: fields, menuItems, onRemoveImage, onUpload, showTitle = true, title, uploadingFieldId } = _a, props = __rest(_a, ["callback", "displayImages", "form", "menuItems", "onRemoveImage", "onUpload", "showTitle", "title", "uploadingFieldId"]);
21
+ var { callback, displayImages, form: fields, menuItems, onAISend, onRemoveImage, onUpload, showTitle = true, title, uploadingFieldId } = _a, props = __rest(_a, ["callback", "displayImages", "form", "menuItems", "onAISend", "onRemoveImage", "onUpload", "showTitle", "title", "uploadingFieldId"]);
22
22
  const { form, visibleFields, hiddenFields, handleAddAll, handleAdd, handleFilesUpload, handleRemove, } = useDynamicForm({ fields, onUpload });
23
23
  return (_jsxs(Stack, { bg: "lightBlue.1", spacing: "0", h: "full", overflowX: "hidden", children: [showTitle && (_jsx(Box, { px: "base", pt: "4", pb: "2", borderBottom: "1px dashed", borderColor: "lightBlue.6", children: _jsx(Text, { fontFamily: "secondary", children: title !== null && title !== void 0 ? title : t('forms.itemDetails') }) })), _jsx(FormProvider, Object.assign({}, form, { children: _jsx(_Fragment, { children: visibleFields === null || visibleFields === void 0 ? void 0 : visibleFields.map((field) => {
24
24
  const { canBeHidden, children, description, icon, id, name, options, type, value, } = field;
@@ -63,7 +63,7 @@ export const DynamicForm = (_a) => {
63
63
  return (_createElement(FieldWithDelete, Object.assign({}, fieldWithDeleteBaseProps, { key: id }),
64
64
  _jsx(RatingField, Object.assign({}, baseProps))));
65
65
  case 'ai-grid':
66
- return (_jsxs(Stack, { p: "base", spacing: "base", bg: "lightBlue.2", children: [_jsx(Text, { fontFamily: "secondary", children: description }), _jsx(GridField, Object.assign({}, baseProps, { onRemove: onRemoveImage, onUpload: (files) => handleFilesUpload({ id, files }), children: children }))] }, id));
66
+ return (_jsxs(Stack, { p: "base", spacing: "base", bg: "lightBlue.2", children: [description && (_jsx(Text, { fontFamily: "secondary", children: description })), _jsx(AIGridField, Object.assign({}, baseProps, { onRemove: onRemoveImage, onUpload: (files) => handleFilesUpload({ id, files }), onAISend: onAISend, children: children }))] }, id));
67
67
  case 'grid':
68
68
  return (_createElement(FieldWithDelete, Object.assign({}, fieldWithDeleteBaseProps, { key: id }),
69
69
  _jsx(GridField, Object.assign({}, baseProps, { children: children }))));
@@ -0,0 +1,2 @@
1
+ import { AIGridFieldI } from '../../../../interfaces';
2
+ export declare const AIGridField: ({ children, onAISend, onRemove, onUpload, }: AIGridFieldI) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useFormContext } from 'react-hook-form';
3
+ import { Flex, IconButton, Text } from '@chakra-ui/react';
4
+ import { TextField, SingleImage, Plus } from '../../..';
5
+ import { fieldIcons } from '../../../../helpers';
6
+ import { colors } from '../../../../theme/colors';
7
+ export const AIGridField = ({ children, onAISend, onRemove, onUpload, }) => {
8
+ var _a, _b, _c, _d, _e, _f;
9
+ const { watch } = useFormContext();
10
+ const textChild = children === null || children === void 0 ? void 0 : children.find(({ type }) => type === 'text' || type === 'string');
11
+ const textProps = {
12
+ id: (_a = textChild === null || textChild === void 0 ? void 0 : textChild.id) !== null && _a !== void 0 ? _a : '',
13
+ value: (_b = textChild === null || textChild === void 0 ? void 0 : textChild.value) !== null && _b !== void 0 ? _b : '',
14
+ placeholder: (_c = textChild === null || textChild === void 0 ? void 0 : textChild.name) !== null && _c !== void 0 ? _c : textChild === null || textChild === void 0 ? void 0 : textChild.description,
15
+ icon: (textChild === null || textChild === void 0 ? void 0 : textChild.icon)
16
+ ? fieldIcons[textChild.icon]
17
+ : undefined,
18
+ };
19
+ const imageField = children === null || children === void 0 ? void 0 : children.find(({ type }) => type === 'ai-image');
20
+ const imageProps = {
21
+ id: (_d = imageField === null || imageField === void 0 ? void 0 : imageField.id) !== null && _d !== void 0 ? _d : '',
22
+ value: (_e = imageField === null || imageField === void 0 ? void 0 : imageField.value) !== null && _e !== void 0 ? _e : '',
23
+ placeholder: (_f = imageField === null || imageField === void 0 ? void 0 : imageField.name) !== null && _f !== void 0 ? _f : imageField === null || imageField === void 0 ? void 0 : imageField.description,
24
+ icon: (imageField === null || imageField === void 0 ? void 0 : imageField.icon)
25
+ ? fieldIcons[imageField.icon]
26
+ : undefined,
27
+ };
28
+ const code = watch(String(textChild === null || textChild === void 0 ? void 0 : textChild.id));
29
+ const handleAISend = () => {
30
+ const form = {
31
+ code,
32
+ image: imageField === null || imageField === void 0 ? void 0 : imageField.value,
33
+ };
34
+ onAISend === null || onAISend === void 0 ? void 0 : onAISend(form);
35
+ };
36
+ return (_jsxs(Flex, { align: "center", gap: "base", children: [_jsx(SingleImage, Object.assign({}, imageProps, { onUpload: onUpload, onRemove: onRemove, value: imageField === null || imageField === void 0 ? void 0 : imageField.value })), _jsx(Text, { fontFamily: "secondary", textAlign: "center", children: "OR" }), _jsx(TextField, Object.assign({}, textProps)), _jsx(IconButton, { "aria-label": "Add new address line", variant: "iconOutlined", icon: _jsx(Plus, { size: 28, stroke: colors.blue[3] }), onClick: handleAISend, h: "input.md", disabled: !(code === null || code === void 0 ? void 0 : code.length) && !(imageField === null || imageField === void 0 ? void 0 : imageField.value) })] }));
37
+ };
@@ -13,5 +13,5 @@ export const SingleImage = ({ onRemove, onUpload, uploading = false, value, }) =
13
13
  onUpload === null || onUpload === void 0 ? void 0 : onUpload(selectedFiles);
14
14
  }
15
15
  };
16
- return (_jsxs(Flex, { gap: "1", align: "center", flex: "auto1", children: [_jsx(MobileFileUploader, { handleInputChange: handleInputChange, "aria-label": "upload image" }), value && (_jsxs(Box, { position: "relative", w: "66px", children: [_jsx(IconButton, { variant: "ghost", "aria-label": "close", maxW: "fit-content", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(value), icon: _jsx(Close, { size: 11, stroke: colors.error['2'] }), disabled: uploading, position: "absolute", bg: "neutral.white", p: "0.5", borderRadius: "full", top: "-2", right: "-2", zIndex: "1" }), _jsx(AspectRatio, { maxW: "100%", ratio: 1, children: _jsx(Image, { src: value, objectFit: "cover", alt: "image" }) })] }))] }));
16
+ return (_jsxs(Flex, { gap: "2", align: "center", h: "input.md", children: [_jsx(MobileFileUploader, { handleInputChange: handleInputChange, "aria-label": "upload image", minW: "72px" }), value && (_jsxs(Box, { position: "relative", minW: "30px", children: [_jsx(IconButton, { variant: "ghost", "aria-label": "close", maxW: "fit-content", onClick: () => onRemove === null || onRemove === void 0 ? void 0 : onRemove(value), icon: _jsx(Close, { size: 11, stroke: colors.error['2'] }), disabled: uploading, position: "absolute", bg: "neutral.white", p: "0.5", borderRadius: "full", top: "-2", right: "-2", zIndex: "1" }), _jsx(AspectRatio, { maxW: "100%", ratio: 1, children: _jsx(Image, { src: value, objectFit: "cover", alt: "image" }) })] }))] }));
17
17
  };
@@ -1,3 +1,4 @@
1
+ export * from './AIGridField';
1
2
  export * from './CheckboxAgreement';
2
3
  export * from './CheckboxGroupField';
3
4
  export * from './CurrencyField';
@@ -1,3 +1,4 @@
1
+ export * from './AIGridField';
1
2
  export * from './CheckboxAgreement';
2
3
  export * from './CheckboxGroupField';
3
4
  export * from './CurrencyField';
@@ -1,4 +1,4 @@
1
- import { FolderFileI, MenuItemI, PartnerFooterI, TileCtaI } from '../..';
1
+ import { AIGridFieldI, FolderFileI, MenuItemI, PartnerFooterI, TileCtaI } from '../..';
2
2
  export type KindTypes = 'ai-image' | 'ai-grid' | 'checkbox' | 'checkbox-agreement' | 'checkbox-group' | 'currency' | 'date' | 'email' | 'file' | 'grid' | 'group' | 'hidden' | 'notes' | 'number' | 'radio' | 'rating' | 'select' | 'string' | 'switch' | 'telephone' | 'text' | 'textarea' | 'default' | UIKindTypes | HomeItemTypes;
3
3
  export type UIKindTypes = 'tile-body' | 'tile-body-logo' | 'tile-body-header' | 'tile-body-section' | 'tile-body-section-grid' | 'tile-form' | 'tile-body-action' | 'vertical-icon' | 'primary-cta' | 'secondary-cta';
4
4
  export type HomeItemTypes = 'appliances' | 'images' | 'guidelines' | 'item-related' | 'item-icon-btn';
@@ -25,6 +25,7 @@ export interface DynamicFormI extends Partial<PartnerFooterI> {
25
25
  displayImages?: string[];
26
26
  form: ReportI[];
27
27
  menuItems?: MenuItemI[];
28
+ onAISend?: AIGridFieldI['onAISend'];
28
29
  onRemoveImage?: (file: string) => void;
29
30
  onUpload?: (filesByFieldId: Record<string, FolderFileI[]>) => void;
30
31
  showTitle?: boolean;
@@ -4,3 +4,11 @@ export interface GridFieldI {
4
4
  onRemove?: (file: string) => void;
5
5
  onUpload?: (files: FolderFileI[]) => void;
6
6
  }
7
+ export interface AIGridFieldI extends GridFieldI {
8
+ onAISend?: (form?: AIFormI) => void;
9
+ }
10
+ interface AIFormI {
11
+ code?: string;
12
+ image?: string;
13
+ }
14
+ export {};
@@ -19,6 +19,7 @@ export default {
19
19
  faker.image.urlPicsumPhotos(),
20
20
  faker.image.urlPicsumPhotos(),
21
21
  ],
22
+ onAiSend: action('onAiSend'),
22
23
  onUpload: action('onUpload'),
23
24
  menuItems: menuMock,
24
25
  socialLinks: socialLinksMock,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homefile/components-v2",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "author": "Homefile",
5
5
  "license": "UNLICENSED",
6
6
  "typings": "dist/index.d.ts",
@@ -19,6 +19,7 @@ import {
19
19
  TileBody,
20
20
  CheckboxGroupField,
21
21
  CheckboxAgreement,
22
+ AIGridField,
22
23
  } from '@/components'
23
24
  import { useDynamicForm } from '@/hooks'
24
25
  import { fieldIcons } from '@/helpers'
@@ -28,6 +29,7 @@ export const DynamicForm = ({
28
29
  displayImages,
29
30
  form: fields,
30
31
  menuItems,
32
+ onAISend,
31
33
  onRemoveImage,
32
34
  onUpload,
33
35
  showTitle = true,
@@ -143,14 +145,17 @@ export const DynamicForm = ({
143
145
  case 'ai-grid':
144
146
  return (
145
147
  <Stack key={id} p="base" spacing="base" bg="lightBlue.2">
146
- <Text fontFamily="secondary">{description}</Text>
147
- <GridField
148
+ {description && (
149
+ <Text fontFamily="secondary">{description}</Text>
150
+ )}
151
+ <AIGridField
148
152
  {...baseProps}
149
153
  onRemove={onRemoveImage}
150
154
  onUpload={(files) => handleFilesUpload({ id, files })}
155
+ onAISend={onAISend}
151
156
  >
152
157
  {children}
153
- </GridField>
158
+ </AIGridField>
154
159
  </Stack>
155
160
  )
156
161
  case 'grid':
@@ -0,0 +1,72 @@
1
+ import { useFormContext } from 'react-hook-form'
2
+ import { Flex, IconButton, Text } from '@chakra-ui/react'
3
+ import { IconTypes, AIGridFieldI } from '@/interfaces'
4
+ import { TextField, SingleImage, Plus } from '@/components'
5
+ import { fieldIcons } from '@/helpers'
6
+ import { colors } from '@/theme/colors'
7
+
8
+ export const AIGridField = ({
9
+ children,
10
+ onAISend,
11
+ onRemove,
12
+ onUpload,
13
+ }: AIGridFieldI) => {
14
+ const { watch } = useFormContext()
15
+
16
+ const textChild = children?.find(
17
+ ({ type }) => type === 'text' || type === 'string'
18
+ )
19
+
20
+ const textProps = {
21
+ id: textChild?.id ?? '',
22
+ value: textChild?.value ?? '',
23
+ placeholder: textChild?.name ?? textChild?.description,
24
+ icon: textChild?.icon
25
+ ? (fieldIcons[textChild.icon] as IconTypes)
26
+ : undefined,
27
+ }
28
+
29
+ const imageField = children?.find(({ type }) => type === 'ai-image')
30
+
31
+ const imageProps = {
32
+ id: imageField?.id ?? '',
33
+ value: imageField?.value ?? '',
34
+ placeholder: imageField?.name ?? imageField?.description,
35
+ icon: imageField?.icon
36
+ ? (fieldIcons[imageField.icon] as IconTypes)
37
+ : undefined,
38
+ }
39
+
40
+ const code = watch(String(textChild?.id))
41
+
42
+ const handleAISend = () => {
43
+ const form = {
44
+ code,
45
+ image: imageField?.value as string,
46
+ }
47
+ onAISend?.(form)
48
+ }
49
+
50
+ return (
51
+ <Flex align="center" gap="base">
52
+ <SingleImage
53
+ {...imageProps}
54
+ onUpload={onUpload}
55
+ onRemove={onRemove}
56
+ value={imageField?.value as string}
57
+ />
58
+ <Text fontFamily="secondary" textAlign="center">
59
+ OR
60
+ </Text>
61
+ <TextField {...textProps} />
62
+ <IconButton
63
+ aria-label="Add new address line"
64
+ variant="iconOutlined"
65
+ icon={<Plus size={28} stroke={colors.blue[3]} />}
66
+ onClick={handleAISend}
67
+ h="input.md"
68
+ disabled={!code?.length && !imageField?.value}
69
+ />
70
+ </Flex>
71
+ )
72
+ }
@@ -21,13 +21,14 @@ export const SingleImage = ({
21
21
  }
22
22
 
23
23
  return (
24
- <Flex gap="1" align="center" flex="auto1">
24
+ <Flex gap="2" align="center" h="input.md">
25
25
  <MobileFileUploader
26
26
  handleInputChange={handleInputChange}
27
27
  aria-label="upload image"
28
+ minW="72px"
28
29
  />
29
30
  {value && (
30
- <Box position="relative" w="66px">
31
+ <Box position="relative" minW="30px">
31
32
  <IconButton
32
33
  variant="ghost"
33
34
  aria-label="close"
@@ -1,3 +1,4 @@
1
+ export * from './AIGridField'
1
2
  export * from './CheckboxAgreement'
2
3
  export * from './CheckboxGroupField'
3
4
  export * from './CurrencyField'
@@ -1,4 +1,10 @@
1
- import { FolderFileI, MenuItemI, PartnerFooterI, TileCtaI } from '@/interfaces'
1
+ import {
2
+ AIGridFieldI,
3
+ FolderFileI,
4
+ MenuItemI,
5
+ PartnerFooterI,
6
+ TileCtaI,
7
+ } from '@/interfaces'
2
8
 
3
9
  export type KindTypes =
4
10
  | 'ai-image'
@@ -127,6 +133,7 @@ export interface DynamicFormI extends Partial<PartnerFooterI> {
127
133
  displayImages?: string[]
128
134
  form: ReportI[]
129
135
  menuItems?: MenuItemI[]
136
+ onAISend?: AIGridFieldI['onAISend']
130
137
  onRemoveImage?: (file: string) => void
131
138
  onUpload?: (filesByFieldId: Record<string, FolderFileI[]>) => void
132
139
  showTitle?: boolean
@@ -5,3 +5,12 @@ export interface GridFieldI {
5
5
  onRemove?: (file: string) => void
6
6
  onUpload?: (files: FolderFileI[]) => void
7
7
  }
8
+
9
+ export interface AIGridFieldI extends GridFieldI {
10
+ onAISend?: (form?: AIFormI) => void
11
+ }
12
+
13
+ interface AIFormI {
14
+ code?: string
15
+ image?: string
16
+ }
@@ -21,6 +21,7 @@ export default {
21
21
  faker.image.urlPicsumPhotos(),
22
22
  faker.image.urlPicsumPhotos(),
23
23
  ],
24
+ onAiSend: action('onAiSend'),
24
25
  onUpload: action('onUpload'),
25
26
  menuItems: menuMock,
26
27
  socialLinks: socialLinksMock,