diff --git a/src/components/form/components/field_groups/svg_text_style.schema.ts b/src/components/form/components/field_groups/svg_text_style.schema.ts index 358b8085..f6692297 100644 --- a/src/components/form/components/field_groups/svg_text_style.schema.ts +++ b/src/components/form/components/field_groups/svg_text_style.schema.ts @@ -5,7 +5,7 @@ import { stringToNumberOptional } from '../../utils/validators.ts'; export const svgTextStyleFieldsSchema = z.object({ fill: z.string().optional(), fontSize: stringToNumberOptional({ - numSchema: z.int().min(0), + numSchema: z.int().min(1), parse: (str) => Number.parseInt(str, 10), }), fontStyle: z.enum(['normal', 'italic']).optional(), diff --git a/src/components/form/components/field_groups/svg_text_style.tsx b/src/components/form/components/field_groups/svg_text_style.tsx index 39630aaf..93365372 100644 --- a/src/components/form/components/field_groups/svg_text_style.tsx +++ b/src/components/form/components/field_groups/svg_text_style.tsx @@ -1,7 +1,6 @@ -import { Checkbox } from '@blueprintjs/core'; +import { Callout, Checkbox } from '@blueprintjs/core'; import styled from '@emotion/styled'; import type { ReactNode } from 'react'; -import { memo } from 'react'; import type { z } from 'zod'; import { SVGStyledText } from '../../../svg/index.js'; @@ -47,7 +46,7 @@ export const FieldGroupSVGTextStyleFields = withFieldGroup({ {(field) => } - {(field) => } + {(field) => } @@ -94,6 +93,13 @@ export const FieldGroupSVGTextStyleFields = withFieldGroup({ }, }); +const TextStyleFieldPreviewErrorContainer = styled.ul` + & > li { + margin-left: 15px; + list-style: disc; + } +`; + const TextStyleFieldPreviewContainer = styled.div` display: flex; align-items: center; @@ -104,11 +110,27 @@ interface TextStyleFieldPreviewProps extends SvgTextStyleFields { children?: ReactNode; } -const TextStyleFieldPreview = memo(function TextStyleFieldPreview( - props: TextStyleFieldPreviewProps, -) { - const parsedValues = svgTextStyleFieldsSchema.parse(props); - const fontSize = parsedValues.fontSize ?? 16; +function TextStyleFieldPreview(props: TextStyleFieldPreviewProps) { + const safeResult = svgTextStyleFieldsSchema.safeParse(props); + + if (!safeResult.success) { + return ( + + + {safeResult.error.issues.map((error) => ( +
  • + {error.path.join('.')}: ${error.message} +
  • + ))} +
    +
    + ); + } + + const fontSize = safeResult.data.fontSize ?? 16; const svgHeight = Math.round(fontSize * 1.5); const textY = Math.round(svgHeight / 4); @@ -119,18 +141,19 @@ const TextStyleFieldPreview = memo(function TextStyleFieldPreview( dominantBaseline="hanging" x={0} y={textY} - {...parsedValues} + {...safeResult.data} > {props.children} ); -}); +} const BoldLabel = styled.span` font-weight: bold; `; + const ItalicLabel = styled.span` font-style: italic; `;