From 8c7c074d5933b9485c8b67e017dc7d8430a298b2 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 6 Feb 2026 18:58:59 -0700 Subject: [PATCH] Remove backwards compatibility --- app/components/buttons/Button.tsx | 54 +------ .../cards/RuleCard/RuleCard.view.tsx | 2 +- .../MultiSelect/MultiSelect.container.tsx | 7 +- .../controls/MultiSelect/MultiSelect.types.ts | 6 +- .../controls/MultiSelect/MultiSelect.view.tsx | 4 +- .../SelectInput/SelectInput.container.tsx | 8 +- .../controls/SelectInput/SelectInput.types.ts | 9 +- .../controls/Switch/Switch.container.tsx | 25 ++-- .../controls/Switch/Switch.types.ts | 12 +- .../controls/Switch/Switch.view.tsx | 10 +- app/components/modals/Alert/Alert.view.tsx | 3 +- .../navigation/TopNav/TopNav.container.tsx | 8 +- .../AskOrganizer/AskOrganizer.view.tsx | 3 +- .../NumberedCards/NumberedCards.view.tsx | 4 +- .../sections/RuleStack/RuleStack.view.tsx | 3 +- .../type/ContentLockup/ContentLockup.view.tsx | 6 +- .../utility/ModalFooter/ModalFooter.view.tsx | 5 +- lib/propNormalization.ts | 45 ------ stories/buttons/Button.stories.js | 138 +++++++++--------- stories/buttons/Button.visual.stories.js | 19 ++- stories/controls/Switch.stories.js | 48 +++--- stories/modals/Tooltip.stories.js | 2 +- tests/components/Button.test.tsx | 2 +- tests/components/MultiSelect.test.tsx | 14 +- 24 files changed, 163 insertions(+), 274 deletions(-) diff --git a/app/components/buttons/Button.tsx b/app/components/buttons/Button.tsx index 109092c..2aa2c6a 100644 --- a/app/components/buttons/Button.tsx +++ b/app/components/buttons/Button.tsx @@ -1,13 +1,11 @@ import { memo } from "react"; import type { - VariantValue, SizeValue, ButtonTypeValue, ButtonPaletteValue, ButtonStateValue, } from "../../../lib/propNormalization"; import { - normalizeVariant, normalizeSize, normalizeButtonType, normalizeButtonPalette, @@ -15,12 +13,6 @@ import { interface ButtonProps extends React.ButtonHTMLAttributes { children: React.ReactNode; - /** - * @deprecated Use `type` and `palette` props instead. This prop is maintained for backward compatibility. - * Button variant. Accepts both lowercase and PascalCase (case-insensitive). - * Figma uses PascalCase, codebase uses lowercase - both are supported. - */ - variant?: VariantValue; /** * Button type (Figma prop). Accepts both lowercase and PascalCase (case-insensitive). * Figma uses PascalCase, codebase uses lowercase - both are supported. @@ -74,7 +66,6 @@ interface ButtonProps extends React.ButtonHTMLAttributes { const Button = memo( ({ children, - variant: variantProp, buttonType: typeProp, palette: paletteProp, size: sizeProp = "xsmall", @@ -92,51 +83,14 @@ const Button = memo( ariaLabel, ...props }) => { - // Determine type and palette from either new props or legacy variant prop - let buttonType: "filled" | "outline" | "ghost" | "danger"; - let buttonPalette: "default" | "inverse"; - - if (variantProp) { - // Backward compatibility: map old variant to new type/palette - const variant = normalizeVariant(variantProp); - if (variant === "filled") { - buttonType = "filled"; - buttonPalette = "default"; - } else if (variant === "filled-inverse") { - buttonType = "filled"; - buttonPalette = "inverse"; - } else if (variant === "outline") { - buttonType = "outline"; - buttonPalette = "default"; - } else if (variant === "outline-inverse") { - buttonType = "outline"; - buttonPalette = "inverse"; - } else if (variant === "ghost") { - buttonType = "ghost"; - buttonPalette = "default"; - } else if (variant === "ghost-inverse") { - buttonType = "ghost"; - buttonPalette = "inverse"; - } else if (variant === "danger") { - buttonType = "danger"; - buttonPalette = "default"; - } else { - // danger-inverse - buttonType = "danger"; - buttonPalette = "inverse"; - } - } else { - // Use new type/palette props - buttonType = normalizeButtonType(typeProp, "filled"); - buttonPalette = normalizeButtonPalette(paletteProp, "default"); - } - - // Normalize other props + // Normalize props + const buttonType = normalizeButtonType(typeProp, "filled"); + const buttonPalette = normalizeButtonPalette(paletteProp, "default"); const size = normalizeSize(sizeProp); // State prop is for Figma alignment - actual state is handled by CSS pseudo-classes // We accept it for API alignment but don't use it for styling (CSS handles states) - // Map type + palette to legacy variant for styling (maintains existing styles) + // Map type + palette to variant string for styling (internal use only) const getVariantFromTypeAndPalette = ( type: typeof buttonType, palette: typeof buttonPalette, diff --git a/app/components/cards/RuleCard/RuleCard.view.tsx b/app/components/cards/RuleCard/RuleCard.view.tsx index 5cdea94..1a0ab30 100644 --- a/app/components/cards/RuleCard/RuleCard.view.tsx +++ b/app/components/cards/RuleCard/RuleCard.view.tsx @@ -242,7 +242,7 @@ export function RuleCardView({ onCustomChipClose={(chipId) => { category.onCustomChipClose?.(category.name, chipId); }} - showAddButton={true} + addButton={true} addButtonText="" // Empty text for icon-only circular button className="w-full" /> diff --git a/app/components/controls/MultiSelect/MultiSelect.container.tsx b/app/components/controls/MultiSelect/MultiSelect.container.tsx index 40a65fb..70abcfd 100644 --- a/app/components/controls/MultiSelect/MultiSelect.container.tsx +++ b/app/components/controls/MultiSelect/MultiSelect.container.tsx @@ -14,8 +14,7 @@ const MultiSelectContainer = memo( options, onChipClick, onAddClick, - showAddButton: showAddButtonProp, - addButton: addButtonProp, + addButton: addButtonProp = true, addButtonText = "Add organization type", formHeader = true, onCustomChipConfirm, @@ -24,8 +23,6 @@ const MultiSelectContainer = memo( }) => { const size = normalizeMultiSelectSize(sizeProp); const palette = normalizeChipPalette(paletteProp); - // Backward compatibility: if addButton is provided, use it; otherwise use showAddButton - const showAddButton = addButtonProp !== undefined ? addButtonProp : (showAddButtonProp !== undefined ? showAddButtonProp : true); return ( ( options={options} onChipClick={onChipClick} onAddClick={onAddClick} - showAddButton={showAddButton} + addButton={addButtonProp} addButtonText={addButtonText} formHeader={formHeader} onCustomChipConfirm={onCustomChipConfirm} diff --git a/app/components/controls/MultiSelect/MultiSelect.types.ts b/app/components/controls/MultiSelect/MultiSelect.types.ts index 4f3e0e0..d70a84b 100644 --- a/app/components/controls/MultiSelect/MultiSelect.types.ts +++ b/app/components/controls/MultiSelect/MultiSelect.types.ts @@ -39,10 +39,6 @@ export interface MultiSelectProps { * Callback when add button is clicked */ onAddClick?: () => void; - /** - * Show the add button (backward compatibility - use addButton instead) - */ - showAddButton?: boolean; /** * Whether to show add button (Figma prop). * @default true @@ -76,7 +72,7 @@ export interface MultiSelectViewProps { options: ChipOption[]; onChipClick?: (chipId: string) => void; onAddClick?: () => void; - showAddButton: boolean; + addButton: boolean; addButtonText: string; formHeader: boolean; onCustomChipConfirm?: (chipId: string, value: string) => void; diff --git a/app/components/controls/MultiSelect/MultiSelect.view.tsx b/app/components/controls/MultiSelect/MultiSelect.view.tsx index fc96e24..b2fbd50 100644 --- a/app/components/controls/MultiSelect/MultiSelect.view.tsx +++ b/app/components/controls/MultiSelect/MultiSelect.view.tsx @@ -13,7 +13,7 @@ function MultiSelectView({ options, onChipClick, onAddClick, - showAddButton, + addButton, addButtonText, formHeader = true, onCustomChipConfirm, @@ -75,7 +75,7 @@ function MultiSelectView({ ))} {/* Add button - Circular button with border (not ghost) when no text, ghost style when text provided */} - {showAddButton && ( + {addButton && ( - {label && {label}} + {text && {text}} ); }, diff --git a/app/components/modals/Alert/Alert.view.tsx b/app/components/modals/Alert/Alert.view.tsx index db8726b..4482230 100644 --- a/app/components/modals/Alert/Alert.view.tsx +++ b/app/components/modals/Alert/Alert.view.tsx @@ -55,7 +55,8 @@ export function AlertView({ )} {/* Outline button for lg and xlg breakpoints */}
-
diff --git a/app/components/sections/RuleStack/RuleStack.view.tsx b/app/components/sections/RuleStack/RuleStack.view.tsx index ae13cfb..533f1f0 100644 --- a/app/components/sections/RuleStack/RuleStack.view.tsx +++ b/app/components/sections/RuleStack/RuleStack.view.tsx @@ -157,7 +157,8 @@ export function RuleStackView({ min-[1024px]:mt-[var(--measures-spacing-1000,40px)] "> {/* Large button for md and lg breakpoints */}
-
{/* XLarge button for xl breakpoint */}
-
diff --git a/app/components/utility/ModalFooter/ModalFooter.view.tsx b/app/components/utility/ModalFooter/ModalFooter.view.tsx index 8efb352..6cac254 100644 --- a/app/components/utility/ModalFooter/ModalFooter.view.tsx +++ b/app/components/utility/ModalFooter/ModalFooter.view.tsx @@ -38,7 +38,7 @@ export function ModalFooterView({ {/* Back Button - Absolutely positioned bottom left */} {showBackButton && (
-
@@ -55,7 +55,8 @@ export function ModalFooterView({ {showNextButton && (
- - - - - - -
@@ -98,7 +94,8 @@ export const Variants = { export const Sizes = { args: { children: "Button", - variant: "filled", + buttonType: "filled", + palette: "default", }, render: (_args) => (
@@ -134,7 +131,8 @@ export const States = { args: { children: "Button", size: "large", - variant: "filled", + buttonType: "filled", + palette: "default", }, render: (_args) => (
@@ -162,19 +160,19 @@ export const AllVariants = {

Filled Variant

- - - - -
@@ -183,19 +181,19 @@ export const AllVariants = {

Filled Inverse Variant

- - - - -
@@ -204,19 +202,19 @@ export const AllVariants = {

Outline Variant

- - - - -
@@ -225,19 +223,19 @@ export const AllVariants = {

Outline Inverse Variant

- - - - -
@@ -246,19 +244,19 @@ export const AllVariants = {

Ghost Variant

- - - - -
@@ -267,19 +265,19 @@ export const AllVariants = {

Ghost Inverse Variant

- - - - -
@@ -288,19 +286,19 @@ export const AllVariants = {

Danger Variant

- - - - -
@@ -309,19 +307,19 @@ export const AllVariants = {

Danger Inverse Variant

- - - - -
@@ -330,28 +328,28 @@ export const AllVariants = {

Disabled States

- - - - - - - -
diff --git a/stories/buttons/Button.visual.stories.js b/stories/buttons/Button.visual.stories.js index 2593846..a4f60c4 100644 --- a/stories/buttons/Button.visual.stories.js +++ b/stories/buttons/Button.visual.stories.js @@ -22,9 +22,13 @@ export default { control: { type: "select" }, options: ["xsmall", "small", "medium", "large", "xlarge"], }, - variant: { + buttonType: { control: { type: "select" }, - options: ["default", "home"], + options: ["filled", "outline", "ghost", "danger"], + }, + palette: { + control: { type: "select" }, + options: ["default", "inverse"], }, disabled: { control: { type: "boolean" }, @@ -192,7 +196,8 @@ export const XLarge = { export const HomeVariant = { args: { children: "Home Button", - variant: "home", + buttonType: "filled", + palette: "default", }, parameters: { docs: { @@ -268,8 +273,8 @@ export const StateComparison = {
- - +
@@ -336,8 +341,8 @@ export const EdgeCases = {
- - +
diff --git a/stories/controls/Switch.stories.js b/stories/controls/Switch.stories.js index 1e0c9af..3d94872 100644 --- a/stories/controls/Switch.stories.js +++ b/stories/controls/Switch.stories.js @@ -8,18 +8,18 @@ export default { layout: "centered", }, argTypes: { - checked: { + propSwitch: { control: "boolean", - description: "Whether the switch is checked (on) or not (off)", + description: "Whether the switch is checked (on) or not (off) (Figma prop)", }, state: { control: "select", options: ["default", "focus"], description: "Visual state of the switch", }, - label: { + text: { control: "text", - description: "Label text displayed next to the switch", + description: "Label text displayed next to the switch (Figma prop)", }, onChange: { action: "changed", @@ -40,28 +40,28 @@ const Template = (args) => ; export const Default = Template.bind({}); Default.args = { - checked: false, - label: "Switch label", + propSwitch: false, + text: "Switch label", }; export const Checked = Template.bind({}); Checked.args = { - checked: true, - label: "Switch label", + propSwitch: true, + text: "Switch label", }; export const Focus = Template.bind({}); Focus.args = { - checked: false, + propSwitch: false, state: "focus", - label: "Switch label", + text: "Switch label", }; export const FocusChecked = Template.bind({}); FocusChecked.args = { - checked: true, + propSwitch: true, state: "focus", - label: "Switch label", + text: "Switch label", }; export const States = () => ( @@ -69,17 +69,17 @@ export const States = () => (

Switch States

- - - - + + + +
); export const Interactive = () => { - const [checked, setChecked] = React.useState(false); + const [propSwitch, setPropSwitch] = React.useState(false); const [state, setState] = React.useState("default"); return ( @@ -87,10 +87,10 @@ export const Interactive = () => {

Interactive Switch

setChecked(!checked)} - label="Enable notifications" + onChange={() => setPropSwitch(!propSwitch)} + text="Enable notifications" />
@@ -118,10 +118,10 @@ export const WithText = () => (

Switch with Different Labels

- - - - + + + +
diff --git a/stories/modals/Tooltip.stories.js b/stories/modals/Tooltip.stories.js index 0a1ea08..6b5f3b8 100644 --- a/stories/modals/Tooltip.stories.js +++ b/stories/modals/Tooltip.stories.js @@ -22,7 +22,7 @@ export default { const Template = (args) => (
- diff --git a/tests/components/Button.test.tsx b/tests/components/Button.test.tsx index ae40e3c..a5a9957 100644 --- a/tests/components/Button.test.tsx +++ b/tests/components/Button.test.tsx @@ -54,7 +54,7 @@ describe("Button (behavioral tests)", () => { it("renders as a link when href is provided", () => { render( - , ); diff --git a/tests/components/MultiSelect.test.tsx b/tests/components/MultiSelect.test.tsx index 265479a..2a22186 100644 --- a/tests/components/MultiSelect.test.tsx +++ b/tests/components/MultiSelect.test.tsx @@ -24,7 +24,7 @@ const config: ComponentTestSuiteConfig = { size: "S", palette: "Default", options: defaultChipOptions, - showAddButton: true, + addButton: true, addButtonText: "", } as Props, requiredProps: ["options"], @@ -35,7 +35,7 @@ const config: ComponentTestSuiteConfig = { palette: "Inverse", onChipClick: vi.fn(), onAddClick: vi.fn(), - showAddButton: false, + addButton: false, addButtonText: "Add", }, primaryRole: undefined, // MultiSelect contains multiple interactive elements @@ -83,7 +83,7 @@ describe("MultiSelect – behaviour specifics", () => { , ); @@ -100,7 +100,7 @@ describe("MultiSelect – behaviour specifics", () => { , ); @@ -127,18 +127,18 @@ describe("MultiSelect – behaviour specifics", () => { render( , ); expect(screen.getByText("Add option")).toBeInTheDocument(); }); - it("does not render add button when showAddButton is false", () => { + it("does not render add button when addButton is false", () => { render( , ); expect(screen.queryByRole("button", { name: /add/i })).not.toBeInTheDocument();