> = ({
child.props['aria-disabled'] === true
if (!isDisabled) {
child.props.onClick && child.props.onClick(event)
- isUncontrolled && setSelectedIndexInternalState(index)
+ isUncontrolled && setSelectedIndexInternalState(segmentIndex)
}
},
- selected: index === selectedIndex,
+ selected: segmentIndex === selectedIndex,
style: {
'--separator-color':
- index === selectedIndex || index === selectedIndex - 1 ? 'transparent' : 'var(--borderColor-default)',
+ segmentIndex === selectedIndex || segmentIndex === selectedIndex - 1
+ ? 'transparent'
+ : 'var(--borderColor-default)',
...child.props.style,
},
}
// Render the children as-is and add the shared child props
- return React.cloneElement(child, sharedChildProps)
+ return React.cloneElement(child, {key: child.key ?? `segmented-control-item-${index}`, ...sharedChildProps})
})}
)
- // Return both variants when dropdown is used, otherwise just the segmented control
- return hasDropdownVariant ? (
- <>
+ const inlineActionContent = actionChild && (
+
+ {actionChild}
+
+ )
+
+ return hasDropdownVariant || actionChild ? (
+
{dropdownContent}
{segmentedControlContent}
- >
+ {inlineActionContent}
+
) : (
segmentedControlContent
)
@@ -228,4 +283,6 @@ Root.displayName = 'SegmentedControl'
export const SegmentedControl = Object.assign(Root, {
Button,
IconButton: SegmentedControlIconButton,
+ Divider,
+ Action,
})
diff --git a/packages/react/src/SegmentedControl/SegmentedControlAction.tsx b/packages/react/src/SegmentedControl/SegmentedControlAction.tsx
new file mode 100644
index 00000000000..9c4da2f8d4f
--- /dev/null
+++ b/packages/react/src/SegmentedControl/SegmentedControlAction.tsx
@@ -0,0 +1,82 @@
+import type React from 'react'
+import {useContext} from 'react'
+import type {ElementType} from 'react'
+import {ActionList} from '../ActionList'
+import {IconButton} from '../Button'
+import type {FCWithSlotMarker} from '../utils/types'
+import classes from './SegmentedControl.module.css'
+import {SegmentedControlActionContext} from './SegmentedControlActionContext'
+
+export interface SegmentedControlActionProps {
+ label: string
+ icon: ElementType
+ onClick?: () => void
+ disabled?: boolean
+ loading?: boolean
+}
+
+interface SegmentedControlMenuActionProps {
+ children?: React.ReactNode
+ onClick?: (event: React.MouseEvent) => void
+ onKeyPress?: (event: React.KeyboardEvent) => void
+ 'aria-disabled'?: boolean
+ 'aria-labelledby'?: string
+ 'aria-describedby'?: string
+ className?: string
+ role?: string
+ tabIndex?: number
+}
+
+const SegmentedControlMenuAction: React.FC = ({children, ...props}) => (
+
+ {children}
+
+)
+
+const SegmentedControlAction: FCWithSlotMarker = props => {
+ const {disabled, icon: Icon, label, loading, onClick} = props
+ const variant = useContext(SegmentedControlActionContext)
+
+ if (variant === 'menu') {
+ return (
+ <>
+
+ {
+ event.preventDefault()
+ onClick?.()
+ }}
+ >
+
+
+
+ {label}
+
+ >
+ )
+ }
+
+ return (
+
+ onClick?.()}
+ variant="invisible"
+ />
+
+ )
+}
+
+SegmentedControlAction.displayName = 'SegmentedControl.Action'
+
+export default SegmentedControlAction
+
+SegmentedControlAction.__SLOT__ = Symbol('SegmentedControl.Action')
diff --git a/packages/react/src/SegmentedControl/SegmentedControlActionContext.ts b/packages/react/src/SegmentedControl/SegmentedControlActionContext.ts
new file mode 100644
index 00000000000..0fec8d0d4d6
--- /dev/null
+++ b/packages/react/src/SegmentedControl/SegmentedControlActionContext.ts
@@ -0,0 +1,3 @@
+import {createContext} from 'react'
+
+export const SegmentedControlActionContext = createContext<'inline' | 'menu'>('inline')
diff --git a/packages/react/src/SegmentedControl/SegmentedControlDivider.tsx b/packages/react/src/SegmentedControl/SegmentedControlDivider.tsx
new file mode 100644
index 00000000000..182f3269589
--- /dev/null
+++ b/packages/react/src/SegmentedControl/SegmentedControlDivider.tsx
@@ -0,0 +1,16 @@
+import type React from 'react'
+import type {FCWithSlotMarker} from '../utils/types'
+
+export type SegmentedControlDividerProps = {
+ className?: string
+ style?: React.CSSProperties
+}
+
+const SegmentedControlDivider: FCWithSlotMarker = ({className, style}) => (
+
+)
+
+SegmentedControlDivider.displayName = 'SegmentedControl.Divider'
+SegmentedControlDivider.__SLOT__ = Symbol('SegmentedControl.Divider')
+
+export default SegmentedControlDivider
diff --git a/packages/react/src/SegmentedControl/index.ts b/packages/react/src/SegmentedControl/index.ts
index abb2932cb5e..77bf8c7cdff 100644
--- a/packages/react/src/SegmentedControl/index.ts
+++ b/packages/react/src/SegmentedControl/index.ts
@@ -3,3 +3,5 @@ export * from './SegmentedControl'
export type {SegmentedControlProps} from './SegmentedControl'
export type {SegmentedControlButtonProps} from './SegmentedControlButton'
export type {SegmentedControlIconButtonProps} from './SegmentedControlIconButton'
+export type {SegmentedControlActionProps} from './SegmentedControlAction'
+export type {SegmentedControlDividerProps} from './SegmentedControlDivider'
diff --git a/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap b/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap
index 94bd40f056e..c9b215f88fa 100644
--- a/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap
+++ b/packages/react/src/__tests__/__snapshots__/exports.test.ts.snap
@@ -150,7 +150,9 @@ exports[`@primer/react > should not update exports without a semver change 1`] =
"type RelativeTimeProps",
"ResponsiveValue",
"SegmentedControl",
+ "type SegmentedControlActionProps",
"type SegmentedControlButtonProps",
+ "type SegmentedControlDividerProps",
"type SegmentedControlIconButtonProps",
"type SegmentedControlProps",
"Select",
diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts
index 0c4ebf8767d..3f89766df4d 100644
--- a/packages/react/src/index.ts
+++ b/packages/react/src/index.ts
@@ -163,6 +163,8 @@ export type {
SegmentedControlProps,
SegmentedControlButtonProps,
SegmentedControlIconButtonProps,
+ SegmentedControlActionProps,
+ SegmentedControlDividerProps,
} from './SegmentedControl'
// Currently there is a duplicate Select component at the root of the dir, so need to be explicit about exporting from the src/Select dir
export {default as Select} from './Select'