diff --git a/bun.lock b/bun.lock index 086ed5a7..0b3d59ae 100644 --- a/bun.lock +++ b/bun.lock @@ -304,6 +304,7 @@ "@tanstack/react-query": "catalog:", "@workspace/db": "workspace:*", "@workspace/db-react": "workspace:*", + "@workspace/i18n": "workspace:*", "@workspace/keypair": "workspace:*", "@workspace/portfolio": "workspace:*", "@workspace/settings": "workspace:*", diff --git a/packages/dev/package.json b/packages/dev/package.json index 48c988bd..1c714324 100644 --- a/packages/dev/package.json +++ b/packages/dev/package.json @@ -4,6 +4,7 @@ "@tanstack/react-query": "catalog:", "@workspace/db": "workspace:*", "@workspace/db-react": "workspace:*", + "@workspace/i18n": "workspace:*", "@workspace/keypair": "workspace:*", "@workspace/portfolio": "workspace:*", "@workspace/settings": "workspace:*", diff --git a/packages/dev/src/dev-feature-ui-inputs-solana-address.tsx b/packages/dev/src/dev-feature-ui-inputs-solana-address.tsx new file mode 100644 index 00000000..b52b7b9d --- /dev/null +++ b/packages/dev/src/dev-feature-ui-inputs-solana-address.tsx @@ -0,0 +1,62 @@ +import { zodResolver } from '@hookform/resolvers/zod' +import { solanaAddressSchema } from '@workspace/db/solana/solana-address-schema' +import { Button } from '@workspace/ui/components/button' +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@workspace/ui/components/form' +import { InputGroup, InputGroupAddon, InputGroupInput } from '@workspace/ui/components/input-group' +import { UiDebug } from '@workspace/ui/components/ui-debug' +import { UiIcon } from '@workspace/ui/components/ui-icon' +import { cn } from '@workspace/ui/lib/utils' +import { useState } from 'react' +import { useForm } from 'react-hook-form' +import { z } from 'zod' + +const formSchema = z.object({ + address: solanaAddressSchema, +}) + +type FormSchemaType = z.infer +export function DevFeatureUiInputsSolanaAddress() { + const [result, setResult] = useState(null) + + const form = useForm({ + defaultValues: { + address: '', + }, + mode: 'all', + resolver: zodResolver(formSchema), + }) + function onSubmit(values: z.infer) { + setResult(values) + } + + return ( +
+ + ( + + Address + + + + + + + + + + + )} + /> +
+ +
+ {result ? : null} + + + ) +} diff --git a/packages/dev/src/dev-feature-ui-inputs-solana-addresses.tsx b/packages/dev/src/dev-feature-ui-inputs-solana-addresses.tsx new file mode 100644 index 00000000..b2eea9ad --- /dev/null +++ b/packages/dev/src/dev-feature-ui-inputs-solana-addresses.tsx @@ -0,0 +1,88 @@ +import { zodResolver } from '@hookform/resolvers/zod' +import { solanaAddressSchema } from '@workspace/db/solana/solana-address-schema' +import { useTranslation } from '@workspace/i18n' +import { Button } from '@workspace/ui/components/button' +import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@workspace/ui/components/form' +import { InputGroup, InputGroupAddon, InputGroupInput } from '@workspace/ui/components/input-group' +import { UiDebug } from '@workspace/ui/components/ui-debug' +import { UiIcon } from '@workspace/ui/components/ui-icon' +import { useState } from 'react' +import { useFieldArray, useForm } from 'react-hook-form' +import { z } from 'zod' + +const formSchema = z.object({ + addresses: z.array(z.object({ value: solanaAddressSchema })), +}) + +type FormSchemaType = z.infer +export function DevFeatureUiInputsSolanaAddresses() { + const { t } = useTranslation('ui') + const [result, setResult] = useState(null) + + const form = useForm({ + defaultValues: { + addresses: [{ value: '' }], + }, + mode: 'all', + resolver: zodResolver(formSchema), + }) + const { fields, append, remove } = useFieldArray({ + control: form.control, + name: 'addresses', + }) + + function onSubmit(values: z.infer) { + setResult(values) + } + + return ( +
+ + {fields.map((field, index) => ( + ( + + Address {index + 1} + + + + + + + + + + + )} + /> + ))} +
+ + +
+ {result ? : null} + + + ) +} diff --git a/packages/dev/src/dev-feature-ui-inputs.tsx b/packages/dev/src/dev-feature-ui-inputs.tsx new file mode 100644 index 00000000..55f40d5d --- /dev/null +++ b/packages/dev/src/dev-feature-ui-inputs.tsx @@ -0,0 +1,14 @@ +import { UiCard } from '@workspace/ui/components/ui-card' +import { DevFeatureUiInputsSolanaAddress } from './dev-feature-ui-inputs-solana-address.tsx' +import { DevFeatureUiInputsSolanaAddresses } from './dev-feature-ui-inputs-solana-addresses.tsx' + +export function DevFeatureUiInputs() { + return ( + +
+ + +
+
+ ) +} diff --git a/packages/dev/src/dev-feature-ui.tsx b/packages/dev/src/dev-feature-ui.tsx index ebced85d..1942d236 100644 --- a/packages/dev/src/dev-feature-ui.tsx +++ b/packages/dev/src/dev-feature-ui.tsx @@ -1,10 +1,12 @@ import { DevFeatureUiAvatars } from './dev-feature-ui-avatars.tsx' import { DevFeatureUiColors } from './dev-feature-ui-colors.tsx' import { DevFeatureUiIcons } from './dev-feature-ui-icons.tsx' +import { DevFeatureUiInputs } from './dev-feature-ui-inputs.tsx' export default function DevFeatureUi() { return (
+ diff --git a/packages/i18n/locales/en/ui.json b/packages/i18n/locales/en/ui.json index cce1b1fd..8e1039b0 100644 --- a/packages/i18n/locales/en/ui.json +++ b/packages/i18n/locales/en/ui.json @@ -1,4 +1,7 @@ { + "actionAdd": "Add", + "actionRemove": "Remove", + "actionSave": "Save", "errorTitle": "Oops, an error occurred", "experimentalWarningDescription": "Use this wallet at your own risk. Do not use any real funds.", "experimentalWarningTitle": "This is experimental software.", diff --git a/packages/i18n/locales/es/ui.json b/packages/i18n/locales/es/ui.json index cb754ac9..c668e9d8 100644 --- a/packages/i18n/locales/es/ui.json +++ b/packages/i18n/locales/es/ui.json @@ -1,4 +1,7 @@ { + "actionAdd": "Agregar", + "actionRemove": "Eliminar", + "actionSave": "Guardar", "errorTitle": "Uy, ocurrió un error", "experimentalWarningDescription": "Utilice esta billetera bajo su propio riesgo. No use fondos reales.", "experimentalWarningTitle": "Este es un software experimental.", diff --git a/packages/i18n/src/resources.d.ts b/packages/i18n/src/resources.d.ts index 0fc77165..cb32c506 100644 --- a/packages/i18n/src/resources.d.ts +++ b/packages/i18n/src/resources.d.ts @@ -218,6 +218,9 @@ interface Resources { languageSpanish: 'Spanish' } ui: { + actionAdd: 'Add' + actionRemove: 'Remove' + actionSave: 'Save' errorTitle: 'Oops, an error occurred' experimentalWarningDescription: 'Use this wallet at your own risk. Do not use any real funds.' experimentalWarningTitle: 'This is experimental software.' diff --git a/packages/ui/src/components/ui-icon-map.tsx b/packages/ui/src/components/ui-icon-map.tsx index 9712a722..5428b65b 100644 --- a/packages/ui/src/components/ui-icon-map.tsx +++ b/packages/ui/src/components/ui-icon-map.tsx @@ -42,6 +42,7 @@ import { LucideUmbrella, LucideUploadCloud, LucideWallet2, + LucideX, } from 'lucide-react' import type * as react from 'react' import type { ForwardRefExoticComponent } from 'react' @@ -93,6 +94,7 @@ export type UiIconName = | 'upload' | 'wallet' | 'watch' + | 'x' const uiIconMap = new Map() .set('add', LucidePlus) @@ -139,6 +141,7 @@ const uiIconMap = new Map() .set('upload', LucideUploadCloud) .set('wallet', LucideWallet2) .set('watch', LucideEye) + .set('x', LucideX) export function getIcon(type: UiIconName) { if (!uiIconMap.has(type)) {