diff --git a/src/Context.ts b/src/Context.ts index ed1f46e..cefd7f7 100644 --- a/src/Context.ts +++ b/src/Context.ts @@ -1,10 +1,11 @@ import * as React from 'react'; -import type { StepsProps } from './Steps'; +import type { ComponentType, StepsProps } from './Steps'; export interface StepsContextProps { prefixCls: string; classNames: NonNullable; styles: NonNullable; + ItemComponent: ComponentType; } export const StepsContext = React.createContext(null!); diff --git a/src/Step.tsx b/src/Step.tsx index a305f97..1ee6078 100644 --- a/src/Step.tsx +++ b/src/Step.tsx @@ -6,6 +6,7 @@ import type { Status, StepItem, StepsProps } from './Steps'; import Rail from './Rail'; import { UnstableContext } from './UnstableContext'; import StepIcon, { StepIconSemanticContext } from './StepIcon'; +import { StepsContext } from './Context'; function hasContent(value: T) { return value !== undefined && value !== null; @@ -59,8 +60,9 @@ export default function Step(props: StepProps) { const itemCls = `${prefixCls}-item`; - // ==================== Internal Context ==================== + // ======================== Contexts ======================== const { railFollowPrevStatus } = React.useContext(UnstableContext); + const { ItemComponent } = React.useContext(StepsContext); // ========================== Data ========================== const { @@ -233,7 +235,7 @@ export default function Step(props: StepProps) { ); let stepNode: React.ReactNode = ( -
  • {itemWrapperRender ? itemWrapperRender(wrapperNode) : wrapperNode} -
  • + ); if (itemRender) { diff --git a/src/Steps.tsx b/src/Steps.tsx index f928208..fdedc56 100644 --- a/src/Steps.tsx +++ b/src/Steps.tsx @@ -32,6 +32,8 @@ export type ItemSemanticName = | 'icon' | 'rail'; +export type ComponentType = React.ComponentType | string; + export type StepItem = { /** @deprecated Please use `content` instead. */ description?: React.ReactNode; @@ -74,6 +76,13 @@ export interface StepsProps { orientation?: 'horizontal' | 'vertical'; titlePlacement?: 'horizontal' | 'vertical'; + // a11y + /** Internal usage of antd. Do not deps on this. */ + components?: { + root?: ComponentType; + item?: ComponentType; + }; + // data status?: Status; current?: number; @@ -107,6 +116,7 @@ export default function Steps(props: StepsProps) { // layout orientation, titlePlacement, + components, // data status = 'process', @@ -167,14 +177,18 @@ export default function Steps(props: StepsProps) { } }; + // =========================== components =========================== + const { root: RootComponent = 'div', item: ItemComponent = 'div' } = components || {}; + // ============================ contexts ============================ const stepIconContext = React.useMemo( () => ({ prefixCls, classNames, styles, + ItemComponent, }), - [prefixCls, classNames, styles], + [prefixCls, classNames, styles, ItemComponent], ); // ============================= render ============================= @@ -212,7 +226,7 @@ export default function Steps(props: StepsProps) { }; return ( -
      {mergedItems.map(renderStep)} -
    + ); } diff --git a/tests/__snapshots__/index.test.tsx.snap b/tests/__snapshots__/index.test.tsx.snap index 0141179..f297840 100644 --- a/tests/__snapshots__/index.test.tsx.snap +++ b/tests/__snapshots__/index.test.tsx.snap @@ -1,11 +1,42 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Steps render renders correctly 1`] = ` +exports[`Steps components 1`] = `
    1. +
      +
      +
      +
      +
      + test +
      +
      +
      +
      +
    2. +
    +`; + +exports[`Steps render renders correctly 1`] = ` +
    +
    - -
  • +
    -
  • -
  • +
    -
  • -
  • +
    -
  • - +
    + `; exports[`Steps render renders current correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders progressDot correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders progressDot function correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders status correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders step with description 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders step with description and status 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders stepIcon function correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders titlePlacement correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders vertical correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps render renders with falsy children 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    7. +
      -
    8. -
    + + `; exports[`Steps should render customIcon correctly 1`] = ` -
      -
    1. -
    2. -
    3. +
      -
    4. -
    5. +
      -
    6. -
    + + `; diff --git a/tests/index.test.tsx b/tests/index.test.tsx index cc59327..12b4f55 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -363,4 +363,22 @@ describe('Steps', () => { expect(iconEle).toHaveClass('bamboo'); expect(iconEle.textContent).toBe('little'); }); + + it('components', () => { + const { container } = render( + , + ); + + expect(container.firstChild).toMatchSnapshot(); + }); });