From bb827eb4f93324d9dc7271696a1c710a7cfd29dc Mon Sep 17 00:00:00 2001 From: Slizhevsky Vladislav Date: Mon, 10 Aug 2026 17:49:45 +0200 Subject: [PATCH] [UIK-5725][wizard] rewrite component to NS --- semcore/wizard/src/Wizard.tsx | 66 ++-- semcore/wizard/src/Wizard.types.ts | 355 ++++++++++-------- .../tests/examples/sidebar-as-component.tsx | 6 +- website/docs/components/wizard/wizard-api.md | 16 +- 4 files changed, 249 insertions(+), 194 deletions(-) diff --git a/semcore/wizard/src/Wizard.tsx b/semcore/wizard/src/Wizard.tsx index 71a376bf86..57216b25eb 100644 --- a/semcore/wizard/src/Wizard.tsx +++ b/semcore/wizard/src/Wizard.tsx @@ -1,7 +1,7 @@ import { ScreenReaderOnly, Box } from '@semcore/base-components'; import Button from '@semcore/button'; import { createComponent, Component, Root, sstyled } from '@semcore/core'; -import type { IRootComponentProps, Intergalactic } from '@semcore/core'; +import type { Intergalactic } from '@semcore/core'; import type { WithI18nEnhanceProps } from '@semcore/core/lib/utils/enhances/i18nEnhance'; import i18nEnhance from '@semcore/core/lib/utils/enhances/i18nEnhance'; import findComponent from '@semcore/core/lib/utils/findComponent'; @@ -16,31 +16,19 @@ import React from 'react'; import style from './style/wizard.shadow.css'; import { localizedMessages } from './translations/__intergalactic-dynamic-locales'; -import type { - WizardStep, - WizardProps, - WizardStepProps, - WizardStepperProps, - WizardSidebarProps, - WizardContentProps, - IntergalacticWizardStepperComponent, - WizardType, - WizardStepBackProps, - WizardStepNextProps, - WizardDefaultProps, -} from './Wizard.types'; +import type { NSWizard } from './Wizard.types'; type State = { highlighted: number; }; class WizardRoot extends Component< - WizardProps, + Intergalactic.InternalTypings.InferComponentProps, typeof WizardRoot.enhance, {}, WithI18nEnhanceProps, - State, - WizardDefaultProps + NSWizard.State, + NSWizard.DefaultProps > { static displayName = 'Wizard'; static style = style; @@ -61,7 +49,7 @@ class WizardRoot extends Component< highlighted: this.props.step, }; - getStepId(step: WizardStep): string { + getStepId(step: NSWizard.Step): string { return `${this.asProps.uid}-step-${step}`; } @@ -69,19 +57,19 @@ class WizardRoot extends Component< return `${this.asProps.uid}-title`; } - getStepperId(step: WizardStep): string { + getStepperId(step: NSWizard.Step): string { const { uid } = this.asProps; return `${uid}-stepper-${step}`; } - getContentId(step: WizardStep): string { + getContentId(step: NSWizard.Step): string { const { uid } = this.asProps; return `${uid}-content-${step}`; } - getStepProps(props: WizardStepProps) { + getStepProps(props: NSWizard.Step.Props) { return { steps: this._steps, active: props.step === this.asProps.step, @@ -148,7 +136,7 @@ class WizardRoot extends Component< }, 0); }; - getStepperProps(props: WizardStepperProps, i: number) { + getStepperProps(props: NSWizard.Stepper.Props, i: number) { let number = i + 1; if (this._steps.has(props.step)) { const step = this._steps.get(props.step); @@ -178,7 +166,7 @@ class WizardRoot extends Component< }; } - componentDidUpdate(prevProps: WizardProps) { + componentDidUpdate(prevProps: typeof this.asProps) { if (prevProps.step === this.asProps.step) return; this.setState({ highlighted: this.asProps.step }); @@ -209,7 +197,9 @@ class WizardRoot extends Component< } } -function Sidebar(props: WizardSidebarProps & IRootComponentProps) { +function Sidebar( + props: Intergalactic.InternalTypings.InferChildComponentProps, +) { const { Children, styles, title, id } = props; const SSidebar = Root; const SSidebarHeader = 'h2'; @@ -225,7 +215,9 @@ function Sidebar(props: WizardSidebarProps & IRootComponentProps) { ); } -function Step(props: IRootComponentProps & WizardStepProps) { +function Step( + props: Intergalactic.InternalTypings.InferChildComponentProps, +) { const SStep = Root; const { Children, styles, active } = props; if (active) { @@ -238,7 +230,9 @@ function Step(props: IRootComponentProps & WizardStepProps) { return null; } -function Stepper(props: Required & IRootComponentProps) { +function Stepper( + props: Intergalactic.InternalTypings.InferChildComponentProps, +) { const { Children, styles, @@ -299,7 +293,7 @@ function Stepper(props: Required & IRootComponentProps) { ); } -function Content(props: WizardContentProps & IRootComponentProps) { +function Content(props: Intergalactic.InternalTypings.InferChildComponentProps) { const { Children, styles } = props; const SContent = Root; return sstyled(styles)( @@ -312,7 +306,9 @@ function Content(props: WizardContentProps & IRootComponentProps) { ); } -function StepBack(props: Required & IRootComponentProps) { +function StepBack( + props: Intergalactic.InternalTypings.InferChildComponentProps, +) { const SStepBack = Root; const { Children, children: hasChildren, styles, getI18nText, stepName } = props; const handleClick = React.useCallback(() => { @@ -333,7 +329,9 @@ function StepBack(props: Required & IRootComponentProps) { , ); } -function StepNext(props: Required & IRootComponentProps) { +function StepNext( + props: Intergalactic.InternalTypings.InferChildComponentProps, +) { const SStepNext = Root; const { Children, children: hasChildren, styles, getI18nText, stepName } = props; const handleClick = React.useCallback(() => { @@ -355,7 +353,9 @@ function StepNext(props: Required & IRootComponentProps) { ); } -function StepTitle(props: Intergalactic.InternalTypings.InferChildComponentProps) { +function StepTitle( + props: Intergalactic.InternalTypings.InferChildComponentProps, +) { const SWizardStepTitle = Root; const { styles } = props; @@ -370,7 +370,7 @@ function StepTitle(props: Intergalactic.InternalTypings.InferChildComponentProps * {@link https://developer.semrush.com/intergalactic/components/wizard/wizard-api/|API} | {@link https://developer.semrush.com/intergalactic/components/wizard/wizard-code/|Examples} */ const Wizard = createComponent< - WizardType, + NSWizard.Component, typeof WizardRoot >(WizardRoot, { Sidebar, @@ -385,10 +385,10 @@ const Wizard = createComponent< export const wrapWizardStepper = ( wrapper: ( props: Intergalactic.InternalTypings.UntypeRefAndTag< - Intergalactic.InternalTypings.ComponentPropsNesting + Intergalactic.InternalTypings.ComponentPropsNesting > & PropsExtending, ) => React.ReactNode, -) => wrapper as IntergalacticWizardStepperComponent; +) => wrapper as NSWizard.Stepper.Component; export default Wizard; diff --git a/semcore/wizard/src/Wizard.types.ts b/semcore/wizard/src/Wizard.types.ts index 6c20c06481..e11ca53bb3 100644 --- a/semcore/wizard/src/Wizard.types.ts +++ b/semcore/wizard/src/Wizard.types.ts @@ -6,155 +6,210 @@ import type { NSModal } from '@semcore/modal'; import type { Text, NSText } from '@semcore/typography'; import type React from 'react'; -/** Ordered step position from 0 */ -export type WizardStep = number; - -export type WizardProps = NSModal.Props & { - /** - * Active step value - */ - step: WizardStep; - /** Specifies the locale for i18n support */ - locale?: string; -}; - -export type WizardSidebarProps = NSBox.Props & { - /** - * Sidebar title - */ - title?: React.ReactNode; - - /** - * @internal html id attribute - */ - id?: string; -}; - -export type WizardStepProps = NSBox.Props & { - /** - * Ordered step position from 0 - */ - step: WizardStep; - /** - * Disabled step - */ - disabled?: boolean; - /** - * Active flag - * @internal - */ - active?: boolean; -}; - -export type WizardStepperProps = NSBox.Props & { - /** - * Ordered step position from 0 - */ - step: WizardStep; - /** - * Is invoked when active the step - */ - onActive?: - | ((step: WizardStep, e: React.SyntheticEvent | React.KeyboardEvent) => void) - | React.Dispatch>; - /** - * Stepper number - * @default incremental value - */ - number?: React.ReactNode; - /** - * Is the step completed - */ - completed?: boolean; - /** Disables interaction with the stepper */ - disabled?: boolean; - - /** - * Translation function - * @internal - */ - getI18nText?: ReturnType; - - /** - * Go to next step - * @internal - */ - focusNext?: () => void; - /** - * Go to prev step - * @internal - */ - focusPrev?: () => void; -}; - -export type WizardContentProps = NSBox.Props & { - /** - * Renders wizard content container with border-radius on the left side - */ - noSidebar?: boolean; -}; - -export type WizardStepBackProps = NSButton.Props & { - /** Callback invoked when navigating to the previous step */ - onActive?: - | ((step: WizardStep, e?: React.SyntheticEvent) => void) - | React.Dispatch>; - /** Step name being navigated to */ - stepName?: string; - - /** - * CurrentStep - * @internal - */ - step?: WizardStep; - /** - * Translation function - * @internal - */ - getI18nText?: ReturnType; -}; -export type WizardStepNextProps = NSButton.Props & { - /** Callback invoked when navigating to the next step */ - onActive?: - | ((step: WizardStep, e?: React.SyntheticEvent) => void) - | React.Dispatch>; - /** Step name being navigated to */ - stepName?: string; - - /** - * CurrentStep - * @internal - */ - step?: WizardStep; - /** - * Translation function - * @internal - */ - getI18nText?: ReturnType; -}; -export type WizardDefaultProps = { - step: WizardStep; - i18n: Record; - locale: 'en'; -}; +declare namespace NSWizard { + /** Ordered step position from 0 */ + type Step = number; + type Props = NSModal.Props & { + /** + * Active step value + */ + step: NSWizard.Step; + /** Specifies the locale for i18n support */ + locale?: string; + }; + type DefaultProps = { + step: NSWizard.Step; + i18n: Record; + locale: 'en'; + }; + type State = { + highlighted: number; + }; + namespace Sidebar { + type Props = NSBox.Props & { + /** + * Sidebar title + */ + title?: React.ReactNode; + + /** + * @internal html id attribute + */ + id?: string; + }; + + type Component = Intergalactic.Component<'div', Props>; + } + + namespace Step { + type Props = NSBox.Props & { + /** + * Ordered step position from 0 + */ + step: NSWizard.Step; + /** + * Disabled step + */ + disabled?: boolean; + /** + * Active flag + * @internal + */ + active?: boolean; + }; + + type Component = Intergalactic.Component<'div', Props>; + } + + namespace StepTitle { + type Props = NSText.Props; + + type Component = NSText.Component; + } + + namespace Stepper { + type Props = NSBox.Props & { + /** + * Ordered step position from 0 + */ + step: NSWizard.Step; + /** + * Is invoked when active the step + */ + onActive?: + | ((step: NSWizard.Step, e: React.SyntheticEvent | React.KeyboardEvent) => void) + | React.Dispatch>; + /** + * Stepper number + * @default incremental value + */ + number?: React.ReactNode; + /** + * Is the step completed + */ + completed?: boolean; + /** Disables interaction with the stepper */ + disabled?: boolean; + + /** + * Translation function + * @internal + */ + getI18nText?: ReturnType; + + /** + * Go to next step + * @internal + */ + focusNext?: () => void; + /** + * Go to prev step + * @internal + */ + focusPrev?: () => void; + }; + + type Component = (( + props: Intergalactic.InternalTypings.ComponentProps & PropsExtending, + ) => Intergalactic.InternalTypings.ComponentRenderingResults) & + Intergalactic.InternalTypings.ComponentAdditive<'div', 'div', Props>; + } + + namespace Content { + type Props = NSBox.Props & { + /** + * Renders wizard content container with border-radius on the left side + */ + noSidebar?: boolean; + }; + + type Component = Intergalactic.Component<'div', Props>; + } + + namespace StepBack { + type Props = NSButton.Props & { + /** Callback invoked when navigating to the previous step */ + onActive?: + | ((step: NSWizard.Step, e?: React.SyntheticEvent) => void) + | React.Dispatch>; + /** Step name being navigated to */ + stepName?: string; + + /** + * CurrentStep + * @internal + */ + step?: NSWizard.Step; + /** + * Translation function + * @internal + */ + getI18nText?: ReturnType; + }; + + type Component = Intergalactic.Component<'button', Props>; + } + + namespace StepNext { + type Props = NSButton.Props & { + /** Callback invoked when navigating to the next step */ + onActive?: + | ((step: NSWizard.Step, e?: React.SyntheticEvent) => void) + | React.Dispatch>; + /** Step name being navigated to */ + stepName?: string; + + /** + * CurrentStep + * @internal + */ + step?: NSWizard.Step; + /** + * Translation function + * @internal + */ + getI18nText?: ReturnType; + }; + + type Component = Intergalactic.Component<'button', Props>; + } + + type Component = Intergalactic.Component<'div', Props> & { + Sidebar: Sidebar.Component; + Step: Step.Component; + StepTitle: StepTitle.Component; + Stepper: Stepper.Component; + Content: Content.Component; + StepBack: StepBack.Component; + StepNext: StepNext.Component; + }; +} + +/** @deprecated It will be removed in v19. */ +export type WizardStep = NSWizard.Step; +/** @deprecated It will be removed in v19. */ +export type WizardProps = NSWizard.Props; +/** @deprecated It will be removed in v19. */ +export type WizardSidebarProps = NSWizard.Sidebar.Props; +/** @deprecated It will be removed in v19. */ +export type WizardStepProps = NSWizard.Step.Props; +/** @deprecated It will be removed in v19. */ +export type WizardStepperProps = NSWizard.Stepper.Props; +/** @deprecated It will be removed in v19. */ +export type WizardContentProps = NSWizard.Content.Props; +/** @deprecated It will be removed in v19. */ +export type WizardStepBackProps = NSWizard.StepBack.Props; +/** @deprecated It will be removed in v19. */ +export type WizardStepNextProps = NSWizard.StepNext.Props; +/** @deprecated It will be removed in v19. */ +export type WizardDefaultProps = NSWizard.DefaultProps; // Need this for API page in docs -export type WizardStepTitleProps = NSText.Props; - -export type IntergalacticWizardStepperComponent = (< - Tag extends Intergalactic.Tag = 'div', ->( - props: Intergalactic.InternalTypings.ComponentProps & - PropsExtending, -) => Intergalactic.InternalTypings.ComponentRenderingResults) & -Intergalactic.InternalTypings.ComponentAdditive<'div', 'div', WizardStepperProps>; - -export type WizardType = Intergalactic.Component<'div', WizardProps> & { - Sidebar: Intergalactic.Component<'div', WizardSidebarProps>; - Step: Intergalactic.Component<'div', WizardStepProps>; - StepTitle: typeof Text; - Stepper: IntergalacticWizardStepperComponent; - Content: Intergalactic.Component<'div', WizardContentProps>; - StepBack: Intergalactic.Component<'button', WizardStepBackProps>; - StepNext: Intergalactic.Component<'button', WizardStepNextProps>; -}; +/** @deprecated It will be removed in v19. */ +export type WizardStepTitleProps = NSWizard.StepTitle.Props; +/** @deprecated It will be removed in v19. */ +export type IntergalacticWizardStepperComponent = NSWizard.Stepper.Component; +/** @deprecated It will be removed in v19. */ +export type WizardType = NSWizard.Component; + +export type { NSWizard }; diff --git a/stories/components/wizard/tests/examples/sidebar-as-component.tsx b/stories/components/wizard/tests/examples/sidebar-as-component.tsx index 740aae40e8..8f38ff2029 100644 --- a/stories/components/wizard/tests/examples/sidebar-as-component.tsx +++ b/stories/components/wizard/tests/examples/sidebar-as-component.tsx @@ -2,14 +2,14 @@ import { Flex } from '@semcore/ui/base-components'; import Button from '@semcore/ui/button'; import { Text } from '@semcore/ui/typography'; import Wizard from '@semcore/ui/wizard'; -import type { WizardContentProps } from '@semcore/ui/wizard'; +import type { NSWizard } from '@semcore/ui/wizard'; import React from 'react'; import { WizardSidebar } from './components/WizardSidebar'; const steps = [{ title: 'Location' }, { title: 'Keywords' }, { title: 'Schedule' }]; -const Demo = (props: WizardContentProps) => { +const Demo = (props: NSWizard.Content.Props) => { const [step, setStep] = React.useState(1); const [visible, setVisible] = React.useState(false); @@ -52,7 +52,7 @@ const Demo = (props: WizardContentProps) => { ); }; -export const defaultExampleNoSideBarProps: WizardContentProps = { +export const defaultExampleNoSideBarProps: NSWizard.Content.Props = { noSidebar: false, }; diff --git a/website/docs/components/wizard/wizard-api.md b/website/docs/components/wizard/wizard-api.md index abc9cc2882..af2d1931d9 100644 --- a/website/docs/components/wizard/wizard-api.md +++ b/website/docs/components/wizard/wizard-api.md @@ -10,7 +10,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + ## Wizard.Sidebar @@ -19,7 +19,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + ## Wizard.Stepper @@ -28,7 +28,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + @@ -39,7 +39,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + ## Wizard.StepTitle @@ -48,7 +48,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + ## Wizard.Content @@ -57,7 +57,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + ## Wizard.StepBack @@ -66,7 +66,7 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - + ## Wizard.StepNext @@ -75,4 +75,4 @@ import Wizard from '@semcore/ui/wizard'; ; ``` - +