Skip to content

Conversation

@WillemBarendKruger
Copy link

@WillemBarendKruger WillemBarendKruger commented Oct 27, 2025

Updated component according to request: #3898

Summary by CodeRabbit

  • Refactor

    • Consolidated phone input styling into a unified, inheritable style approach and added shared wrapper/validation styles.
    • Removed per-element style props and search-related options; arrow display is now off by default (migration preserves legacy behavior).
    • Configurable phone input now accepts initial values for form items.
  • Settings

    • Reorganized style editors into a single Style panel and removed separate search/placeholder fields.
  • Tests

    • Added a basic render test for the phone component.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 27, 2025

Walkthrough

Removed per-element style and search-related props from the phone number component API, introduced a consolidated styling hook and unified style prop, added a styles module and initialValue wiring, updated settings JSON to match consolidated styles, and added a simple component test.

Changes

Cohort / File(s) Summary
Interface
shesha-reactjs/src/designer-components/phoneNumber/interface.ts
Removed per-element style props (wrapperStyle, inputGroupWrapperStyle, inputWrapperStyle, inputGroupStyle, inputStyle) and search props (enableSearch, searchNotFound, searchPlaceholder) from IPhoneNumberInputComponentProps.
Component
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx
Replaced ad-hoc per-element CSS generation with a unified useStyles hook and a single componentStyle passed into PhoneInput; removed search-related logic; added initialValue propagation to ConfigurableFormItem; changed enableArrow default behavior and removed generation of unique CSS classes.
Styles module
shesha-reactjs/src/designer-components/phoneNumber/styles.ts
Added useStyles via createStyles, exposing shaPhoneNumberWrapper and shaPhoneNumberValidationMessage class tokens for the component.
Settings
shesha-reactjs/src/designer-components/phoneNumber/settingsForm.json
Removed the Enable Search block and search fields; consolidated multiple per-element style editors into a single Style editor that describes wrapper-based, inheritable styling; set phone_behavior defaultValue true.
Tests
shesha-reactjs/src/designer-components/phoneNumber/__tests__/index.test.tsx
Added a basic render test file that mounts a simple component using @testing-library/react.

Sequence Diagram(s)

sequenceDiagram
    participant Designer as Designer UI / Model
    participant PhoneComp as PhoneNumberInputComponent
    participant ConfigItem as ConfigurableFormItem
    participant PhoneInput as PhoneInput (ui)

    Designer->>PhoneComp: provide model (includes styles, initialValue, enableArrow)
    PhoneComp->>PhoneComp: useStyles() & compute componentStyle (useMemo)
    PhoneComp->>ConfigItem: render with model + initialValue
    ConfigItem->>PhoneInput: render child with style={componentStyle}
    PhoneInput-->>ConfigItem: user input / validation
    ConfigItem-->>PhoneComp: value/validation events
    PhoneComp-->>Designer: propagate changes
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to focus during review:
    • Correctness of the unified styling approach and useStyles tokens (styles.ts) and how they affect Ant Design children.
    • Memoization correctness for componentStyle and any removed per-element CSS generation.
    • API impact from removing search props and changing enableArrow default.
    • Settings JSON edits and exposed variables to ensure editor behavior matches runtime expectations.
    • New test file correctness and coverage intent.

Possibly related PRs

Suggested reviewers

  • IvanIlyichev

Poem

🐰 I hopped through props both near and far,

Gathered styles into one shining jar,
Arrow tucked, searches set aside,
Memoized calm where CSS used to hide.
Hop — the phone input prances with pride. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title "Updated component accordingly" is extremely vague and generic, using non-descriptive language that fails to convey any meaningful information about the changeset. While technically related to the fact that a component was updated, the title does not communicate the substantive nature of the changes: a major refactoring of the phone number component's styling system (consolidating per-element style props into a unified approach), removal of eight properties from the interface, addition of initialValue support, or updates to the configuration form. The phrase "accordingly" and "updated component" are placeholder-like terms that could apply to virtually any PR making changes. A reviewer scanning history would gain no insight into whether this is a bugfix, refactoring, feature addition, or styling improvement. Consider revising the title to be specific and descriptive of the primary change. For example: "Refactor phone number component styling to use unified approach" or "Consolidate phone number component styling system and remove per-element style props" would clearly communicate the main objective of refactoring the styling implementation from granular per-element editors to a consolidated, inheritable-wrapper-centric approach.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ff6775 and 2d43329.

📒 Files selected for processing (3)
  • shesha-reactjs/src/designer-components/phoneNumber/interface.ts (1 hunks)
  • shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (7 hunks)
  • shesha-reactjs/src/designer-components/phoneNumber/settingsForm.json (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (1)
shesha-reactjs/src/providers/form/utils.ts (1)
  • getStyle (1527-1536)
🔇 Additional comments (7)
shesha-reactjs/src/designer-components/phoneNumber/interface.ts (1)

27-27: LGTM! Consolidation of style props.

The unified styles prop effectively replaces multiple individual style properties, simplifying the interface and aligning with the consolidated styling approach implemented in the component.

shesha-reactjs/src/designer-components/phoneNumber/settingsForm.json (2)

221-221: LGTM! Improved UX with expanded behavior panel.

Setting defaultValue: true ensures the behavior panel is expanded by default, improving discoverability of configuration options.


615-664: LGTM! Well-documented unified styles configuration.

The refactored styles editor provides clear documentation through exposed variables and helpful placeholder examples. The consolidation from individual style props to a unified styles object with element-specific keys improves maintainability.

shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (4)

153-156: LGTM! Good use of memoization.

The memoization of componentStyle with proper dependencies prevents unnecessary re-evaluations and improves performance.


376-396: LGTM! Well-implemented unified styles evaluation.

The evaluatedStyles memoization correctly handles both unified style objects (applied to all elements) and element-specific style objects. The fallback logic ensures consistent styling behavior.


493-493: LGTM! Proper initialValue propagation.

Passing initialValue={model.initialValue} to ConfigurableFormItem ensures the component correctly initializes with default values from the form configuration.


21-28: CSS sanitization may be too aggressive.

Removing all braces {} will break valid CSS values that use parentheses in different contexts. For example:

  • rgb(255, 0, 0) would become rgb255, 0, 0
  • calc(100% - 20px) would become calc100% - 20px
  • url(...) patterns would be broken

Consider a more targeted approach that validates against a whitelist of safe CSS properties/values or uses a CSS sanitization library:

 const sanitizeCssValue = (value: any): string => {
     if (typeof value !== 'string') return String(value);
-    // Remove potentially dangerous characters: braces, comments, semicolons outside of expected contexts
     return value
-        .replace(/[{}]/g, '') // Remove braces
         .replace(/\/\*[\s\S]*?\*\//g, '') // Remove comments
         .replace(/<!--[\s\S]*?-->/g, '') // Remove HTML comments
+        .replace(/[{}]/g, '') // Remove curly braces only (keep parentheses)
         .trim();
 };

Or better yet, consider using a dedicated CSS sanitization library like sanitize-css or implementing a whitelist-based approach.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (1)

103-103: Fix inconsistent enableArrow defaults (reminder).

The enableArrow property still has conflicting defaults:

  • Line 103: Defaults to false in the component destructuring
  • Line 506: Set to true in initModel
  • Line 515: Set to true in the migrator

This inconsistency will cause unpredictable behavior depending on whether a component is newly created or migrated. As discussed in previous review, line 506 (initModel) should be updated to false for consistency.

Apply this diff to fix the inconsistency:

 initModel: (model) => ({
     ...model,
     valueFormat: model.valueFormat || 'string',
     stripCountryCode: model.stripCountryCode !== undefined ? model.stripCountryCode : false,
     defaultCountry: model.defaultCountry || 'za',
-    enableArrow: model.enableArrow !== undefined ? model.enableArrow : true,
+    enableArrow: model.enableArrow !== undefined ? model.enableArrow : false,
     labelAlign: model.labelAlign || 'left',
 }),

Also applies to: 506-506, 515-515

🧹 Nitpick comments (1)
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (1)

18-29: Consider additional CSS sanitization patterns.

The current sanitization covers common attack vectors effectively. For comprehensive protection, consider also filtering:

  • behavior: and -moz-binding: (browser-specific script execution)
  • vbscript: protocol
  • data: protocol (can contain encoded malicious content)

Apply this diff to enhance sanitization:

 const sanitizeCssValue = (value: any): string => {
     if (typeof value !== 'string') return String(value);
     return value
         .replace(/[{}]/g, '') // Remove braces
         .replace(/\/\*[\s\S]*?\*\//g, '') // Remove comments
         .replace(/<!--[\s\S]*?-->/g, '') // Remove HTML comments
         .replace(/url\s*\(/gi, '') // Remove url() functions
         .replace(/@import/gi, '') // Remove @import
         .replace(/expression\s*\(/gi, '') // Remove expression()
         .replace(/javascript:/gi, '') // Remove javascript: protocol
+        .replace(/vbscript:/gi, '') // Remove vbscript: protocol
+        .replace(/data:/gi, '') // Remove data: protocol
+        .replace(/behavior\s*:/gi, '') // Remove behavior:
+        .replace(/-moz-binding\s*:/gi, '') // Remove -moz-binding:
         .trim();
 };
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2d43329 and 14354ff.

📒 Files selected for processing (1)
  • shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (6 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-12T16:55:57.638Z
Learnt from: teboho
PR: shesha-io/shesha-framework#3397
File: shesha-reactjs/src/designer-components/charts/bar.tsx:49-52
Timestamp: 2025-06-12T16:55:57.638Z
Learning: For the chart components’ migrators (e.g., BarChartComponent in shesha-reactjs/src/designer-components/charts/bar.tsx), the version 5 step intentionally spreads `{ ...prev, ...defaultConfigFiller }` so that values from `defaultConfigFiller` override any existing properties in `prev`. This reset to new defaults is by design and should not be flagged as an issue.

Applied to files:

  • shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx
🧬 Code graph analysis (1)
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (1)
shesha-reactjs/src/providers/form/utils.ts (1)
  • getStyle (1527-1536)
🔇 Additional comments (2)
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (2)

152-155: Excellent unified styling approach with proper memoization.

The refactoring consolidates per-element style props into a unified styles object with intelligent handling:

  • componentStyle serves as base styles applied to all elements (lines 152-155)
  • evaluatedStyles smartly detects whether the styles prop contains element-specific keys or should be applied universally (lines 374-395)
  • Proper memoization prevents unnecessary recalculations (dependencies correctly specified at lines 154, 395, 435)
  • CSS generation efficiently combines base and override styles

This is a clean architectural improvement that enhances both maintainability and performance.

Also applies to: 374-395, 400-435


492-492: Good addition of initialValue propagation.

Passing initialValue={model.initialValue} to ConfigurableFormItem ensures proper form initialization and aligns with the component's updated public API.

Copy link
Contributor

@IvanIlyichev IvanIlyichev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @WillemBarendKruger. During the initial review of PR #4012, I overlooked an important architectural guideline. We should avoid creating component-level CSS tools and manually generating <style> tags. Instead, please refactor this to use antd-style, our standard library for styling.

For reference, please follow the implementation patterns used in other components.

@WillemBarendKruger
Copy link
Author

WillemBarendKruger commented Oct 28, 2025

@IvanIlyichev , The problem is that when I don't target the specific classnames, it doesn't style correctly, only certain parts of the component are styled, as you can see in the image. If there is an alternative way please do share.
Screenshot 2025-10-28 082548

I did find a way around when I made the 2 nested components transparent, which gives the idea that the styling is applied to all components

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
shesha-reactjs/src/designer-components/phoneNumber/__tests__/index.test.tsx (1)

1-14: Test file doesn't cover the phone number component.

This test renders a SimpleComponent with "Hello React" but doesn't test any functionality of the phone number component that was modified in this PR. Consider adding meaningful tests for the new unified styling approach, initialValue support, or validation behavior.

Example test structure:

import React from 'react';
import { render, screen } from '@testing-library/react';
import PhoneNumberInputComponent from '../phoneNumber';

describe('PhoneNumberInputComponent', () => {
  test('renders with unified styling classes', () => {
    const model = {
      id: 'test-phone',
      type: 'phoneNumberInput',
      propertyName: 'phone',
      label: 'Phone Number',
    };
    
    const { container } = render(
      <PhoneNumberInputComponent.Factory model={model} />
    );
    
    expect(container.querySelector('.sha-phone-number-wrapper')).toBeInTheDocument();
  });
});
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 14354ff and 66e4156.

📒 Files selected for processing (5)
  • shesha-reactjs/src/designer-components/phoneNumber/__tests__/index.test.tsx (1 hunks)
  • shesha-reactjs/src/designer-components/phoneNumber/interface.ts (0 hunks)
  • shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (6 hunks)
  • shesha-reactjs/src/designer-components/phoneNumber/settingsForm.json (4 hunks)
  • shesha-reactjs/src/designer-components/phoneNumber/styles.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • shesha-reactjs/src/designer-components/phoneNumber/interface.ts
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-12T16:55:57.638Z
Learnt from: teboho
PR: shesha-io/shesha-framework#3397
File: shesha-reactjs/src/designer-components/charts/bar.tsx:49-52
Timestamp: 2025-06-12T16:55:57.638Z
Learning: For the chart components’ migrators (e.g., BarChartComponent in shesha-reactjs/src/designer-components/charts/bar.tsx), the version 5 step intentionally spreads `{ ...prev, ...defaultConfigFiller }` so that values from `defaultConfigFiller` override any existing properties in `prev`. This reset to new defaults is by design and should not be flagged as an issue.

Applied to files:

  • shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx
🧬 Code graph analysis (2)
shesha-reactjs/src/designer-components/phoneNumber/styles.ts (1)
shesha-reactjs/src/styles/index.ts (2)
  • createStyles (61-61)
  • css (61-61)
shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (2)
shesha-reactjs/src/designer-components/phoneNumber/styles.ts (1)
  • useStyles (3-54)
shesha-reactjs/src/providers/form/utils.ts (1)
  • getStyle (1527-1536)
🔇 Additional comments (8)
shesha-reactjs/src/designer-components/phoneNumber/settingsForm.json (2)

221-221: Clarify the purpose of defaultValue: true on the Behavior panel.

Setting defaultValue: true on the phone_behavior_panel (line 221) appears to expand the panel by default. Verify this is intentional and consistent with the UX design for the settings form.


592-607: LGTM: Unified style editor aligns with the new styling approach.

The consolidation from per-element style editors to a single unified style editor is consistent with the new styling architecture introduced in styles.ts. The updated description and placeholder clearly communicate that inheritable properties cascade to all child elements.

shesha-reactjs/src/designer-components/phoneNumber/phoneNumber.tsx (5)

14-14: LGTM: Unified styling hook imported.

The import of useStyles from the new styles module supports the transition to consolidated styling.


96-96: LGTM: Style classes hook usage.

The useStyles hook is correctly invoked to obtain the style classes for the wrapper and validation message.


124-127: LGTM: Memoized style computation.

The componentStyle is properly memoized with dependencies on style, formData, and globalState, preventing unnecessary recalculations.


349-376: LGTM: Unified styling implementation.

The rendering now uses the consolidated styling approach:

  • Wrapper div with shaPhoneNumberWrapper class provides full-width layout and transparent backgrounds
  • Single style prop passed to PhoneInput for dynamic styling
  • Validation message styled with shaPhoneNumberValidationMessage class

This implementation aligns with the PR objectives and removes the previous per-element styling complexity.


391-391: LGTM: Initial value support added.

The initialValue={model.initialValue} prop correctly wires up default value support for the phone number component.

shesha-reactjs/src/designer-components/phoneNumber/styles.ts (1)

43-48: Add theme token to phoneNumber validation message styles.

The useStyles function in shesha-reactjs/src/designer-components/phoneNumber/styles.ts must destructure the token parameter and replace the hardcoded error color with Ant Design's theme token. Update line 2:

export const useStyles = createStyles(({ css, cx, token }) => {

Then update line 44:

color: ${token.colorError};

This aligns with the codebase pattern used in other components (e.g., imageAnnotation/styles.ts, text/styles/styles.ts) and ensures the validation message respects theme customization.

⛔ Skipped due to learnings
Learnt from: teboho
PR: shesha-io/shesha-framework#3926
File: shesha-reactjs/src/designer-components/dataTable/tableContext/styles.ts:138-166
Timestamp: 2025-10-02T11:25:33.370Z
Learning: In the shesha-framework repository, the hint popover components (sha-quick-search-hint-popover, sha-table-view-selector-hint-popover, sha-table-pager-hint-popover) in shesha-reactjs/src/designer-components/dataTable/tableContext/styles.ts intentionally use hard-coded color `rgb(214, 214, 214)` with `!important` to impose a specific consistent color across themes, overriding theme tokens by design.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants