Skip to content

Commit ba01c75

Browse files
authored
Merge pull request #478 from mashmatrix/support-slds-2-sales-path
Update `SalesPath` for SLDS2
2 parents 4eb3234 + e53b7b2 commit ba01c75

File tree

1 file changed

+57
-31
lines changed

1 file changed

+57
-31
lines changed

src/scripts/SalesPath.tsx

Lines changed: 57 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ type SalesPathKey = string | number;
2323
*/
2424
const SalesPathTypeContext = createContext<SalesPathItemType>('incomplete');
2525

26-
const SalesPathHandlersContext = createContext<{
26+
const SalesPathContext = createContext<{
2727
onSelect?: Bivariant<(eventKey: SalesPathKey) => void>;
28+
activeKey?: SalesPathKey | null;
2829
}>({});
2930

3031
/**
@@ -44,7 +45,7 @@ export type SalesPathItemProps = {
4445
export const SalesPathItem: FC<SalesPathItemProps> = (props) => {
4546
const { className, eventKey, type: type_, title, completedTitle } = props;
4647
const evaluatedType = useContext(SalesPathTypeContext);
47-
const { onSelect } = useContext(SalesPathHandlersContext);
48+
const { onSelect, activeKey } = useContext(SalesPathContext);
4849
const type = type_ ?? evaluatedType;
4950

5051
const onItemClick = useEventCallback(() => {
@@ -53,32 +54,43 @@ export const SalesPathItem: FC<SalesPathItemProps> = (props) => {
5354
}
5455
});
5556

57+
const isSelected = activeKey === eventKey;
58+
const isCurrent = type === 'current';
59+
const isActive = isSelected || (isCurrent && activeKey == null);
60+
5661
const pathItemClassName = classnames(
57-
'slds-tabs_path__item',
58-
type ? `slds-is-${type}` : undefined,
62+
'slds-path__item',
63+
{
64+
'slds-is-complete': type === 'complete',
65+
'slds-is-current': isCurrent,
66+
'slds-is-incomplete': type === 'incomplete',
67+
'slds-is-active': isActive,
68+
},
5969
className
6070
);
6171

62-
const tabIndex = type === 'current' ? 0 : -1;
72+
const tabIndex = isActive ? 0 : -1;
6373
const completedText = completedTitle || 'Stage Complete';
6474

6575
return (
6676
<li className={pathItemClassName} role='presentation'>
6777
<a
68-
className='slds-tabs_path__link'
69-
aria-selected='false'
78+
className='slds-path__link'
79+
aria-selected={isActive}
7080
tabIndex={tabIndex}
71-
role='tab'
72-
aria-live='assertive'
81+
role='option'
7382
onClick={onItemClick}
7483
>
75-
<span className='slds-tabs_path__stage'>
84+
<span className='slds-path__stage'>
7685
<Icon category='utility' icon='check' size='x-small' />
7786
{type === 'complete' ? (
7887
<span className='slds-assistive-text'>{completedText}</span>
7988
) : null}
89+
{isCurrent ? (
90+
<span className='slds-assistive-text'>Current Stage:</span>
91+
) : null}
8092
</span>
81-
<span className='slds-tabs_path__title'>{title}</span>
93+
<span className='slds-path__title'>{title}</span>
8294
</a>
8395
</li>
8496
);
@@ -114,7 +126,7 @@ export const SalesPath = createFC<
114126
activeKey_,
115127
defaultActiveKey ?? null
116128
);
117-
const salesPathClassNames = classnames(className, 'slds-tabs_path');
129+
const salesPathClassNames = classnames(className, 'slds-path');
118130

119131
const onSelect = useEventCallback((itemKey: SalesPathKey) => {
120132
onSelect_?.(itemKey);
@@ -133,27 +145,41 @@ export const SalesPath = createFC<
133145
}
134146
});
135147

136-
const handlers = useMemo(() => ({ onSelect }), [onSelect]);
148+
const ctx = useMemo(() => ({ onSelect, activeKey }), [onSelect, activeKey]);
137149

138150
return (
139-
<div className={salesPathClassNames} role='application tablist'>
140-
<ul className='slds-tabs_path__nav' role='presentation'>
141-
<SalesPathHandlersContext.Provider value={handlers}>
142-
{React.Children.map(children, (child, idx) => {
143-
const evaluatedType =
144-
idx === activeIdx
145-
? 'current'
146-
: idx < activeIdx
147-
? 'complete'
148-
: 'incomplete';
149-
return (
150-
<SalesPathTypeContext.Provider value={evaluatedType}>
151-
{child}
152-
</SalesPathTypeContext.Provider>
153-
);
154-
})}
155-
</SalesPathHandlersContext.Provider>
156-
</ul>
151+
<div className={salesPathClassNames}>
152+
<div className={classnames('slds-grid', 'slds-path__track')}>
153+
<div
154+
className={classnames('slds-grid', 'slds-path__scroller-container')}
155+
>
156+
<div className='slds-path__scroller'>
157+
<div className='slds-path__scroller_inner'>
158+
<ul
159+
className='slds-path__nav'
160+
role='listbox'
161+
aria-orientation='horizontal'
162+
>
163+
<SalesPathContext.Provider value={ctx}>
164+
{React.Children.map(children, (child, idx) => {
165+
const evaluatedType =
166+
idx === activeIdx
167+
? 'current'
168+
: idx < activeIdx
169+
? 'complete'
170+
: 'incomplete';
171+
return (
172+
<SalesPathTypeContext.Provider value={evaluatedType}>
173+
{child}
174+
</SalesPathTypeContext.Provider>
175+
);
176+
})}
177+
</SalesPathContext.Provider>
178+
</ul>
179+
</div>
180+
</div>
181+
</div>
182+
</div>
157183
</div>
158184
);
159185
},

0 commit comments

Comments
 (0)