Skip to content

feat(custom): implement SubscriptionTable scaffolding and register global module exports#1660

Open
abhinavkdeval08-design wants to merge 2 commits into
layer5io:masterfrom
abhinavkdeval08-design:feature/subscription-comparison-table
Open

feat(custom): implement SubscriptionTable scaffolding and register global module exports#1660
abhinavkdeval08-design wants to merge 2 commits into
layer5io:masterfrom
abhinavkdeval08-design:feature/subscription-comparison-table

Conversation

@abhinavkdeval08-design

Copy link
Copy Markdown

Description

This PR addresses issue #606 by implementing the missing structural baseline scaffolding for the new SubscriptionTable component pattern wrapper matrix within the Sistent design system (src/custom).

Changes Proposed

  • Created a dedicated src/custom/SubscriptionTable/ directory module.
  • Engineered the core table blueprint inside SubscriptionTable.tsx utilizing strict type definitions (PlanFeature props) to dynamically map features.
  • Injected custom layout extensions inside style.tsx utilizing specialized MUI styled engines and Figma typography token overrides (Qanelas Soft and Open Sans).
  • Registered local endpoints globally via both root module index files (src/custom/index.ts and src/custom/index.tsx) to expose the API interface.

Notes for Reviewers

  • The setup is verified locally and ready for seamless integration. I have already initiated a query on the main tracker thread to obtain the explicit production code reference link from the Meshery Cloud UI repository to finalize concrete subscription tier matrices.

Signed commits

  • Yes, I signed my commits. (DCO check passes)

cc @KhushamBansal @leecalcote @Bhumikagarggg

…ule exports

Signed-off-by: Abhinav Deval <abhinavkdeval08@gmail.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new SubscriptionTable component to compare free, team, and enterprise subscription plans, along with its custom styled components. The feedback suggests integrating the newly defined custom styled components from style.tsx into the main table component to clean up unused Material-UI imports, and exposing hardcoded UI strings as configurable props to support internationalization (i18n).

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +1 to +15
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import {
Box,
Button,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography
} from '@mui/material';
import React from 'react';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Import the custom styled components from ./style and clean up the unused MUI imports (Paper, TableCell, TableContainer, TableRow) to keep the code clean and leverage the custom styling defined for this component.

Suggested change
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import {
Box,
Button,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography
} from '@mui/material';
import React from 'react';
import CheckIcon from '@mui/icons-material/Check';
import CloseIcon from '@mui/icons-material/Close';
import {
Box,
Button,
Table,
TableBody,
TableHead,
Typography
} from '@mui/material';
import React from 'react';
import {
StyledTableContainer,
StyledHeaderRow,
StyledTableCell,
FeatureHeaderCell
} from './style';

Comment on lines +25 to +35
export interface SubscriptionTableProps {
title?: string;
features: PlanFeature[];
onPlanSelect?: (planType: 'free' | 'team' | 'enterprise') => void;
}

export const SubscriptionTable: React.FC<SubscriptionTableProps> = ({
title = 'Subscription Plans Comparison',
features,
onPlanSelect
}) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

To support internationalization (i18n) and localization, avoid hardcoding UI strings (such as table headers and button labels) in shared components. Expose these strings as configurable props with default values to maintain backward compatibility. Additionally, default the features prop to an empty array [] to prevent runtime errors if it is not provided.

export interface SubscriptionTableProps {
  title?: string;
  features?: PlanFeature[];
  onPlanSelect?: (planType: 'free' | 'team' | 'enterprise') => void;
  featuresLabel?: string;
  freePlanLabel?: string;
  freePlanButtonLabel?: string;
  teamPlanLabel?: string;
  teamPlanButtonLabel?: string;
  enterprisePlanLabel?: string;
  enterprisePlanButtonLabel?: string;
}

export const SubscriptionTable: React.FC<SubscriptionTableProps> = ({
  title = 'Subscription Plans Comparison',
  features = [],
  onPlanSelect,
  featuresLabel = 'Features',
  freePlanLabel = 'Free Plan',
  freePlanButtonLabel = 'Get Started',
  teamPlanLabel = 'Team Plan',
  teamPlanButtonLabel = 'Upgrade',
  enterprisePlanLabel = 'Enterprise Plan',
  enterprisePlanButtonLabel = 'Contact Us'
}) => {
References
  1. Avoid hardcoding UI strings (such as button labels) in shared components. Expose these strings as configurable props to support internationalization (i18n) and localization.
  2. When exposing UI strings as configurable props in shared components to support localization, provide a default value to maintain backward compatibility.

Comment on lines +68 to +133
<TableContainer component={Paper} elevation={2} sx={{ borderRadius: 2, overflow: 'hidden' }}>
<Table sx={{ minWidth: 650 }} aria-label="subscription comparison table">
<TableHead sx={{ backgroundColor: 'action.hover' }}>
<TableRow>
<TableCell sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>Features</TableCell>
<TableCell align="center" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>
Free Plan
<Box sx={{ mt: 1 }}>
<Button size="small" variant="outlined" onClick={() => onPlanSelect?.('free')}>
Get Started
</Button>
</Box>
</TableCell>
<TableCell align="center" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>
Team Plan
<Box sx={{ mt: 1 }}>
<Button
size="small"
variant="contained"
color="primary"
onClick={() => onPlanSelect?.('team')}
>
Upgrade
</Button>
</Box>
</TableCell>
<TableCell align="center" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>
Enterprise Plan
<Box sx={{ mt: 1 }}>
<Button
size="small"
variant="contained"
color="secondary"
onClick={() => onPlanSelect?.('enterprise')}
>
Contact Us
</Button>
</Box>
</TableCell>
</TableRow>
</TableHead>

<TableBody>
{features.map((row, index) => (
<TableRow
key={index}
sx={{
'&:last-child td, &:last-child th': { border: 0 },
'&:hover': { backgroundColor: 'action.hover' }
}}
>
<TableCell
component="th"
scope="row"
sx={{ fontWeight: 600, color: 'text.primary' }}
>
{row.featureName}
</TableCell>
<TableCell align="center">{renderValue(row.freePlan)}</TableCell>
<TableCell align="center">{renderValue(row.teamPlan)}</TableCell>
<TableCell align="center">{renderValue(row.enterprisePlan)}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Update the table rendering to use the imported custom styled components (StyledTableContainer, StyledHeaderRow, StyledTableCell, FeatureHeaderCell) and the configurable localization props instead of hardcoded strings and standard MUI components with inline styles.

      <StyledTableContainer>
        <Table sx={{ minWidth: 650 }} aria-label="subscription comparison table">
          <TableHead>
            <StyledHeaderRow>
              <StyledTableCell sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>{featuresLabel}</StyledTableCell>
              <StyledTableCell align="center" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>
                {freePlanLabel}
                <Box sx={{ mt: 1 }}>
                  <Button size="small" variant="outlined" onClick={() => onPlanSelect?.('free')}>
                    {freePlanButtonLabel}
                  </Button>
                </Box>
              </StyledTableCell>
              <StyledTableCell align="center" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>
                {teamPlanLabel}
                <Box sx={{ mt: 1 }}>
                  <Button
                    size="small"
                    variant="contained"
                    color="primary"
                    onClick={() => onPlanSelect?.('team')}
                  >
                    {teamPlanButtonLabel}
                  </Button>
                </Box>
              </StyledTableCell>
              <StyledTableCell align="center" sx={{ fontWeight: 'bold', fontSize: '1.1rem' }}>
                {enterprisePlanLabel}
                <Box sx={{ mt: 1 }}>
                  <Button
                    size="small"
                    variant="contained"
                    color="secondary"
                    onClick={() => onPlanSelect?.('enterprise')}
                  >
                    {enterprisePlanButtonLabel}
                  </Button>
                </Box>
              </StyledTableCell>
            </StyledHeaderRow>
          </TableHead>

          <TableBody>
            {features.map((row, index) => (
              <TableRow
                key={index}
                sx={{
                  '&:last-child td, &:last-child th': { border: 0 },
                  '&:hover': { backgroundColor: 'action.hover' }
                }}
              >
                <FeatureHeaderCell component="th" scope="row">
                  {row.featureName}
                </FeatureHeaderCell>
                <StyledTableCell align="center">{renderValue(row.freePlan)}</StyledTableCell>
                <StyledTableCell align="center">{renderValue(row.teamPlan)}</StyledTableCell>
                <StyledTableCell align="center">{renderValue(row.enterprisePlan)}</StyledTableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </StyledTableContainer>

@abhinavkdeval08-design abhinavkdeval08-design force-pushed the feature/subscription-comparison-table branch from 434a2c2 to b7298c4 Compare June 29, 2026 17:38
…ule exports

Signed-off-by: Abhinav Deval <abhinavkdeval08@gmail.com>
@abhinavkdeval08-design abhinavkdeval08-design force-pushed the feature/subscription-comparison-table branch from 56442e9 to 812e1ac Compare June 29, 2026 17:46
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.

1 participant