diff --git a/src/components/Pega_Extensions_JsonEditor/demo.stories.tsx b/src/components/Pega_Extensions_JsonEditor/demo.stories.tsx index 3bff141b..60deb33f 100644 --- a/src/components/Pega_Extensions_JsonEditor/demo.stories.tsx +++ b/src/components/Pega_Extensions_JsonEditor/demo.stories.tsx @@ -1,31 +1,12 @@ import { useState } from 'react'; -import type { Meta, StoryFn } from '@storybook/react-webpack5'; +import type { Meta, StoryObj } from '@storybook/react-webpack5'; import { configProps, stateProps } from './mock'; -import { PegaExtensionsJsonEditor } from './index'; +import { PegaExtensionsJsonEditor, type PegaExtensionsJsonEditorProps } from './index'; -const meta: Meta = { - title: 'Fields/JSON editor', - component: PegaExtensionsJsonEditor, - excludeStories: /.*Data$/, - argTypes: { - getPConnect: { - table: { - disable: true, - }, - }, - displayMode: { - options: ['', 'DISPLAY_ONLY', 'LABELS_LEFT'], - control: { - type: 'select', - }, - }, - }, -}; - -export default meta; +type StoryArgs = Omit; -export const BaseJsonEditor: StoryFn = (args) => { +const JsonEditorStory = (args: StoryArgs) => { const [value, setValue] = useState(configProps.value); const props = { @@ -43,17 +24,59 @@ export const BaseJsonEditor: StoryFn = (args) = return ; }; -BaseJsonEditor.args = { - label: configProps.label, - value: configProps.value, - helperText: configProps.helperText, - placeholder: configProps.placeholder, - testId: configProps.testId, - readOnly: configProps.readOnly, - disabled: configProps.disabled, - required: configProps.required, - status: configProps.status, - hideLabel: configProps.hideLabel, - displayMode: configProps.displayMode, - validatemessage: configProps.validatemessage, +const meta = { + title: 'Fields/JSON editor', + component: JsonEditorStory, + excludeStories: /.*Data$/, + argTypes: { + displayMode: { + options: ['', 'DISPLAY_ONLY', 'LABELS_LEFT'], + control: { + type: 'select', + }, + }, + status: { + options: [undefined, 'error', 'success', 'warning', 'pending'], + control: { + type: 'select', + }, + }, + indent: { + control: { + type: 'number', + min: 0, + step: 1, + }, + }, + }, +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const BaseJsonEditor: Story = { + render: (args) => , + args: { + label: configProps.label, + value: configProps.value, + helperText: configProps.helperText, + placeholder: configProps.placeholder, + testId: configProps.testId, + readOnly: configProps.readOnly, + disabled: configProps.disabled, + required: configProps.required, + status: configProps.status, + hideLabel: configProps.hideLabel, + displayMode: configProps.displayMode, + validatemessage: configProps.validatemessage, + indent: 2, + showValidate: true, + showFormat: true, + showMinify: true, + showCopy: true, + showClear: true, + showCharacterCount: true, + showLineCount: true, + }, }; diff --git a/src/components/Pega_Extensions_JsonEditor/demo.test.tsx b/src/components/Pega_Extensions_JsonEditor/demo.test.tsx index 4d974b67..078ddbbb 100644 --- a/src/components/Pega_Extensions_JsonEditor/demo.test.tsx +++ b/src/components/Pega_Extensions_JsonEditor/demo.test.tsx @@ -11,6 +11,7 @@ test('renders JsonEditor', async () => { render(); expect(await screen.findByRole('textbox', { name: 'JSON value' })).toHaveValue(configProps.value); + expect(screen.getByRole('textbox', { name: 'JSON value' })).toHaveAttribute('spellcheck', 'false'); expect(screen.getByRole('button', { name: 'Format JSON' })).toBeVisible(); expect(screen.getByRole('button', { name: 'Validate JSON' })).toContainElement( screen.getByTestId('JsonEditor-12345678:action:validate').querySelector('[data-icon-name="check"]'), diff --git a/src/components/Pega_Extensions_JsonEditor/index.tsx b/src/components/Pega_Extensions_JsonEditor/index.tsx index 618f748a..7db1100b 100644 --- a/src/components/Pega_Extensions_JsonEditor/index.tsx +++ b/src/components/Pega_Extensions_JsonEditor/index.tsx @@ -106,6 +106,7 @@ export function PegaExtensionsJsonEditor(props: PegaExtensionsJsonEditorProps) { const [scrollOffset, setScrollOffset] = useState({ top: 0, left: 0 }); const copyStateTimeoutRef = useRef>(); const lineCount = useMemo(() => getLineCount(draft), [draft]); + const lineNumberWidth = Math.max(3.5, String(lineCount).length + 2); const highlightedDraft = useMemo(() => highlightJson(draft), [draft]); const lineNumbers = useMemo( () => Array.from({ length: Math.max(1, lineCount) }, (_, index) => index + 1), @@ -185,6 +186,7 @@ export function PegaExtensionsJsonEditor(props: PegaExtensionsJsonEditorProps) { }; const errorMessage = validation.message ? localize(validation.message) : validatemessage; + const hasInfo = Boolean(errorMessage || helperText); const errorLocation = validation.errorLine && validation.errorColumn ? `${localize('Line')} ${validation.errorLine}, ${localize('column')} ${validation.errorColumn}` @@ -284,14 +286,27 @@ export function PegaExtensionsJsonEditor(props: PegaExtensionsJsonEditorProps) { )} )} - -