-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #44 from getpingback/feat/variable-input-custom-fi…
…elds feat(variable-input): add custom fields and combobox
- Loading branch information
Showing
5 changed files
with
380 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,55 @@ | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
|
||
import { VariableInput } from "./variable-input"; | ||
import { VariableInput } from './variable-input'; | ||
|
||
const meta = { | ||
title: "Components/VariableInput", | ||
title: 'Components/VariableInput', | ||
component: VariableInput, | ||
parameters: {}, | ||
|
||
tags: ["autodocs"], | ||
tags: ['autodocs'], | ||
|
||
argTypes: {}, | ||
argTypes: {} | ||
} satisfies Meta<typeof VariableInput>; | ||
|
||
export default meta; | ||
type Story = StoryObj<typeof meta>; | ||
|
||
const options = [ | ||
{ label: "Email", value: "email" }, | ||
{ label: "Name", value: "name" }, | ||
{ label: "Phone", value: "phone" }, | ||
{ | ||
heading: 'Common Variables', | ||
items: [ | ||
{ label: 'Email', value: 'email' }, | ||
{ label: 'Name', value: 'name' }, | ||
{ label: 'Phone', value: 'phone' } | ||
] | ||
}, | ||
{ | ||
heading: 'Custom Variables', | ||
items: [{ label: 'Custom Variable', value: 'customVariable' }] | ||
} | ||
]; | ||
|
||
export const Default: Story = { | ||
args: { | ||
options, | ||
}, | ||
options | ||
} | ||
}; | ||
|
||
export const WithInputProps: Story = { | ||
args: { | ||
label: "URL", | ||
placeholder: "https://www.example.com", | ||
helperText: "Enter the URL of the page you want to redirect to", | ||
options, | ||
}, | ||
label: 'URL', | ||
placeholder: 'https://www.example.com', | ||
helperText: 'Enter the URL of the page you want to redirect to', | ||
options | ||
} | ||
}; | ||
|
||
export const WithInitialContent: Story = { | ||
args: { | ||
initialContent: "Hello {{name}}! How are you?", | ||
options, | ||
}, | ||
label: 'Expression', | ||
placeholder: 'Enter the expression', | ||
initialContent: 'Hello {{name}}! How are you?', | ||
options | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,114 @@ | ||
import React from "react"; | ||
import { render, fireEvent } from "@testing-library/react"; | ||
import { VariableInput } from "./variable-input"; | ||
import React from 'react'; | ||
import { render, fireEvent } from '@testing-library/react'; | ||
import { VariableInput } from './variable-input'; | ||
|
||
describe("VariableInput Component", () => { | ||
describe('VariableInput Component', () => { | ||
const options = [ | ||
{ label: "Variable 1", value: "var1" }, | ||
{ label: "Variable 2", value: "var2" }, | ||
{ | ||
heading: 'Common Variables', | ||
items: [ | ||
{ label: 'Email', value: 'email' }, | ||
{ label: 'Name', value: 'name' }, | ||
{ label: 'Phone', value: 'phone' } | ||
] | ||
}, | ||
{ | ||
heading: 'Custom Variables', | ||
items: [{ label: 'Custom Variable', value: 'customVariable' }] | ||
} | ||
]; | ||
|
||
it("should render with default props and open dropdown on trigger click", () => { | ||
it('should render with default props and open dropdown on trigger click', () => { | ||
const { getByTestId, getByText } = render(<VariableInput options={options} />); | ||
|
||
const triggerButton = getByTestId("variable-input-trigger"); | ||
const triggerButton = getByTestId('variable-input-trigger'); | ||
fireEvent.click(triggerButton); | ||
|
||
expect(getByText("Variable 1")).toBeInTheDocument(); | ||
expect(getByText("Variable 2")).toBeInTheDocument(); | ||
expect(getByText('Email')).toBeInTheDocument(); | ||
expect(getByText('Name')).toBeInTheDocument(); | ||
expect(getByText('Phone')).toBeInTheDocument(); | ||
expect(getByText('Custom Variable')).toBeInTheDocument(); | ||
}); | ||
|
||
it("should call onChangeContent when text is input", () => { | ||
it('should call onChangeContent when text is input', () => { | ||
const handleChangeContent = jest.fn(); | ||
const { container } = render(<VariableInput options={options} onChangeContent={handleChangeContent} />); | ||
|
||
const editor = container.querySelector("[contenteditable='true']"); | ||
if (editor) { | ||
fireEvent.input(editor, { target: { textContent: "Hello" } }); | ||
expect(handleChangeContent).toHaveBeenCalledWith("Hello"); | ||
fireEvent.input(editor, { target: { textContent: 'Hello' } }); | ||
expect(handleChangeContent).toHaveBeenCalledWith('Hello'); | ||
} | ||
}); | ||
|
||
it("should call onSelect when a variable is selected", () => { | ||
it('should call onSelect when a variable is selected', () => { | ||
const handleSelect = jest.fn(); | ||
const { getByText, getByTestId } = render(<VariableInput options={options} onSelect={handleSelect} />); | ||
const { getByText, getByTestId } = render(<VariableInput options={options} onSelectVariable={handleSelect} />); | ||
|
||
const triggerButton = getByTestId("variable-input-trigger"); | ||
const triggerButton = getByTestId('variable-input-trigger'); | ||
fireEvent.click(triggerButton); | ||
|
||
fireEvent.click(getByText("Variable 1")); | ||
expect(handleSelect).toHaveBeenCalledWith("var1"); | ||
fireEvent.click(getByText('Email')); | ||
expect(handleSelect).toHaveBeenCalledWith('email'); | ||
}); | ||
|
||
it("should display placeholder when not focused and empty", () => { | ||
const { container } = render(<VariableInput options={options} placeholder='Enter text' />); | ||
it('should display placeholder when not focused and empty', () => { | ||
const { container } = render(<VariableInput options={options} placeholder="Enter text" />); | ||
|
||
const editor = container.querySelector("[contenteditable='true']"); | ||
if (editor) { | ||
expect(editor.innerHTML).toContain("Enter text"); | ||
expect(editor.innerHTML).toContain('Enter text'); | ||
} | ||
}); | ||
|
||
it("should prevent editing of variable spans", () => { | ||
it('should prevent editing of variable spans', () => { | ||
const { container } = render(<VariableInput options={options} />); | ||
const editor = container.querySelector("[contenteditable='true']"); | ||
|
||
if (editor) { | ||
fireEvent.input(editor, { target: { innerHTML: '<span data-variable="var1">Variable 1</span>' } }); | ||
|
||
fireEvent.keyDown(editor, { key: "Backspace" }); | ||
fireEvent.keyDown(editor, { key: 'Backspace' }); | ||
|
||
expect(editor.innerHTML).toContain('Variable 1'); | ||
} | ||
}); | ||
|
||
it('should filter variables when text is typed in the search input', () => { | ||
const { getByTestId, queryByText } = render(<VariableInput options={options} />); | ||
|
||
const triggerButton = getByTestId('variable-input-trigger'); | ||
fireEvent.click(triggerButton); | ||
|
||
const searchInput = getByTestId('variable-input-search-input'); | ||
fireEvent.change(searchInput, { target: { value: 'email' } }); | ||
|
||
expect(queryByText('Email')).toBeInTheDocument(); | ||
expect(queryByText('Name')).not.toBeInTheDocument(); | ||
expect(queryByText('Phone')).not.toBeInTheDocument(); | ||
expect(queryByText('Custom Variable')).not.toBeInTheDocument(); | ||
}); | ||
|
||
it('should show message when no variables are found in the search', () => { | ||
const { getByTestId, getByText } = render(<VariableInput options={options} />); | ||
|
||
const triggerButton = getByTestId('variable-input-trigger'); | ||
fireEvent.click(triggerButton); | ||
|
||
const searchInput = getByTestId('variable-input-search-input'); | ||
fireEvent.change(searchInput, { target: { value: 'xyz' } }); | ||
|
||
expect(editor.innerHTML).toContain("Variable 1"); | ||
expect(getByText('No results found')).toBeInTheDocument(); | ||
}); | ||
|
||
it('should prioritize initialContent over placeholder', () => { | ||
const initialContent = 'Initial content'; | ||
const { container } = render(<VariableInput options={options} initialContent={initialContent} placeholder="Placeholder" />); | ||
|
||
const editor = container.querySelector("[contenteditable='true']"); | ||
if (editor) { | ||
expect(editor.innerHTML).toBe(initialContent); | ||
expect(editor.innerHTML).not.toBe('Placeholder'); | ||
} | ||
}); | ||
}); |
Oops, something went wrong.