From 34bcb9c15d8454248ae79c5ee98fefeb8da1e256 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Mon, 6 Jan 2025 09:46:49 -0500
Subject: [PATCH 01/17] SegmentedControl

---
 .changeset/cold-ways-rule.md                  |   6 +
 .../componentExample/ComponentExample.tsx     |   2 +-
 apps/docs/app/ui/layout/header/Header.tsx     |   2 +-
 .../components/themeSwitch/ThemeSwitch.tsx    |   4 +-
 .../components/buttons/SegmentedControl.mdx   |  47 +++++
 apps/docs/examples/Preview.ts                 |  18 ++
 .../src/SegmentedControl/docs/controlled.tsx  |  27 +++
 .../src/SegmentedControl/docs/icon.tsx        |  17 ++
 .../src/SegmentedControl/docs/iconOnly.tsx    |  15 ++
 .../src/SegmentedControl/docs/preview.tsx     |  12 ++
 .../src/SegmentedControl/docs/selected.tsx    |  12 ++
 .../src/SegmentedControl/docs/size.tsx        |  12 ++
 .../components/src/SegmentedControl/index.ts  |   1 +
 .../src/SegmentedControl.module.css           |  43 +++++
 .../SegmentedControl/src/SegmentedControl.tsx | 144 +++++++++++++++
 .../src/SegmentedControlContext.ts            |   8 +
 .../src/SegmentedControlItem.module.css       |  64 +++++++
 .../src/SegmentedControlItem.tsx              |  97 +++++++++++
 .../src/SegmentedControlItemContext.ts        |  10 ++
 .../src/SegmentedControl/src/index.ts         |   3 +
 .../chromatic/SegmentedControl.stories.tsx    | 164 ++++++++++++++++++
 .../tests/jest/SegmentedControl.ssr.test.tsx  |  19 ++
 .../tests/jest/SegmentedControl.test.tsx      |  90 ++++++++++
 packages/components/src/index.ts              |   1 +
 24 files changed, 814 insertions(+), 4 deletions(-)
 create mode 100644 .changeset/cold-ways-rule.md
 create mode 100644 apps/docs/content/components/buttons/SegmentedControl.mdx
 create mode 100644 packages/components/src/SegmentedControl/docs/controlled.tsx
 create mode 100644 packages/components/src/SegmentedControl/docs/icon.tsx
 create mode 100644 packages/components/src/SegmentedControl/docs/iconOnly.tsx
 create mode 100644 packages/components/src/SegmentedControl/docs/preview.tsx
 create mode 100644 packages/components/src/SegmentedControl/docs/selected.tsx
 create mode 100644 packages/components/src/SegmentedControl/docs/size.tsx
 create mode 100644 packages/components/src/SegmentedControl/index.ts
 create mode 100644 packages/components/src/SegmentedControl/src/SegmentedControl.module.css
 create mode 100644 packages/components/src/SegmentedControl/src/SegmentedControl.tsx
 create mode 100644 packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
 create mode 100644 packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
 create mode 100644 packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
 create mode 100644 packages/components/src/SegmentedControl/src/SegmentedControlItemContext.ts
 create mode 100644 packages/components/src/SegmentedControl/src/index.ts
 create mode 100644 packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
 create mode 100644 packages/components/src/SegmentedControl/tests/jest/SegmentedControl.ssr.test.tsx
 create mode 100644 packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx

diff --git a/.changeset/cold-ways-rule.md b/.changeset/cold-ways-rule.md
new file mode 100644
index 00000000..3e679da8
--- /dev/null
+++ b/.changeset/cold-ways-rule.md
@@ -0,0 +1,6 @@
+---
+"docs": patch
+"@hopper-ui/components": patch
+---
+
+Added SegmentedControl component
diff --git a/apps/docs/app/ui/components/componentExample/ComponentExample.tsx b/apps/docs/app/ui/components/componentExample/ComponentExample.tsx
index 6c59dd9d..16970e7e 100644
--- a/apps/docs/app/ui/components/componentExample/ComponentExample.tsx
+++ b/apps/docs/app/ui/components/componentExample/ComponentExample.tsx
@@ -4,7 +4,7 @@ import clsx from "clsx";
 import { memo, useEffect, useState, type ReactNode } from "react";
 
 import { CodeIcon, Icon, StackblitzIcon } from "@/components/icon";
-import { ToggleButton } from "@/components/toggleButton/ToggleButton.tsx";
+import { ToggleButton } from "@/components/ToggleButton/ToggleButton.tsx";
 import { useToggle } from "@/hooks/useToggle.ts";
 
 import ComponentPreviewWrapper from "./ComponentPreviewWrapper.tsx";
diff --git a/apps/docs/app/ui/layout/header/Header.tsx b/apps/docs/app/ui/layout/header/Header.tsx
index 89609556..b9cfbe21 100644
--- a/apps/docs/app/ui/layout/header/Header.tsx
+++ b/apps/docs/app/ui/layout/header/Header.tsx
@@ -12,7 +12,7 @@ import { Icon, ProductMenuIcon } from "@/components/icon";
 import LinkIconButton from "@/components/iconButton/LinkIconButton";
 import { Popover, PopoverContext, PopoverTrigger } from "@/components/popover/Popover.tsx";
 import ThemeSwitch from "@/components/themeSwitch/ThemeSwitch";
-import { ToggleButton, ToggleButtonContext } from "@/components/toggleButton/ToggleButton.tsx";
+import { ToggleButton, ToggleButtonContext } from "@/components/ToggleButton/ToggleButton";
 import { navigation } from "@/configs/navigation";
 import { ThemeContext, type ColorScheme } from "@/context/theme/ThemeProvider.tsx";
 import { useIsMobile } from "@/hooks/useIsMobile";
diff --git a/apps/docs/components/themeSwitch/ThemeSwitch.tsx b/apps/docs/components/themeSwitch/ThemeSwitch.tsx
index 419c7a2a..650dc4a8 100644
--- a/apps/docs/components/themeSwitch/ThemeSwitch.tsx
+++ b/apps/docs/components/themeSwitch/ThemeSwitch.tsx
@@ -1,7 +1,7 @@
-import { ToggleButton } from "@/components/toggleButton/ToggleButton";
+import { ToggleButton } from "@/components/ToggleButton/ToggleButton";
 
-import type { ColorScheme } from "@/context/theme/ThemeProvider";
 import Icon from "@/components/themeSwitch/ThemeSwitchIcons";
+import type { ColorScheme } from "@/context/theme/ThemeProvider";
 import clsx from "clsx";
 
 import "./themeSwitch.css";
diff --git a/apps/docs/content/components/buttons/SegmentedControl.mdx b/apps/docs/content/components/buttons/SegmentedControl.mdx
new file mode 100644
index 00000000..c3ae2c27
--- /dev/null
+++ b/apps/docs/content/components/buttons/SegmentedControl.mdx
@@ -0,0 +1,47 @@
+---
+title: SegmentedControl
+description: The SegmentedControl component presents a horizontal row of options or actions that are contextually or conceptually related. It allows users to select a single option at a time.
+category: "pickers"
+links:
+    source: https://github.com/gsoft-inc/wl-hopper/blob/main/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+    aria: https://www.w3.org/WAI/ARIA/apg/patterns/checkbox/
+---
+
+<Example src="SegmentedControl/docs/preview" isOpen />
+
+## Usage
+
+### Selected
+A segmented control supports single selection. At any given time, only one item can be active.
+
+<Example src="SegmentedControl/docs/selected" />
+
+### Size
+A segmented control supports multiple sizes. Here’s an example demonstrating the medium size option:
+
+<Example src="SegmentedControl/docs/size" />
+
+### Icon only
+Items within a segmented control can contain only icons. An accessible name must be provided through [aria-label](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label) prop. See also [WCAG practices](https://www.w3.org/TR/WCAG20-TECHS/ARIA6.html).
+
+<Example src="SegmentedControl/docs/iconOnly" />
+
+### Icon
+A segmented control can contain items with icons, leading or trailing.
+
+<Example src="SegmentedControl/docs/icon" />
+
+### Controlled
+A segmented control can have a controlled selected value. In this example, it shows how it is possible to select an option.
+
+<Example src="SegmentedControl/docs/controlled" />
+
+## Props
+
+### SegmentedControl
+
+<PropTable component="SegmentedControl" />
+
+### SegmentedControlItem
+
+<PropTable component="SegmentedControlItem" />
diff --git a/apps/docs/examples/Preview.ts b/apps/docs/examples/Preview.ts
index 403776f4..84af1001 100644
--- a/apps/docs/examples/Preview.ts
+++ b/apps/docs/examples/Preview.ts
@@ -95,6 +95,24 @@ export const Previews: Record<string, Preview> = {
     "buttons/docs/linkButton/advancedCustomization": {
         component: lazy(() => import("@/../../packages/components/src/buttons/docs/linkButton/advancedCustomization.tsx"))
     },
+    "SegmentedControl/docs/preview": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/preview.tsx"))
+    },
+    "SegmentedControl/docs/selected": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/selected.tsx"))
+    },
+    "SegmentedControl/docs/size": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/size.tsx"))
+    },
+    "SegmentedControl/docs/iconOnly": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/iconOnly.tsx"))
+    },
+    "SegmentedControl/docs/icon": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/icon.tsx"))
+    },
+    "SegmentedControl/docs/controlled": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/controlled.tsx"))
+    },
     "ListBox/docs/preview": {
         component: lazy(() => import("@/../../packages/components/src/ListBox/docs/preview.tsx"))
     },
diff --git a/packages/components/src/SegmentedControl/docs/controlled.tsx b/packages/components/src/SegmentedControl/docs/controlled.tsx
new file mode 100644
index 00000000..05303931
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/controlled.tsx
@@ -0,0 +1,27 @@
+import { SegmentedControl, SegmentedControlItem, type Key } from "@hopper-ui/components";
+import { useState } from "react";
+
+export default function Example() {
+    const [selectedKey, setSelectedKey] = useState<Key>();
+
+    const handleSelectionChange = (key: Key) => {
+        if (selectedKey === key) {
+            return;
+        }
+
+        setSelectedKey(key);
+    };
+
+    return (
+        <SegmentedControl
+            aria-label="Time granularity"
+            selectedKey={selectedKey}
+            onSelectionChange={handleSelectionChange}
+        >
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/docs/icon.tsx b/packages/components/src/SegmentedControl/docs/icon.tsx
new file mode 100644
index 00000000..ee4b46a2
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/icon.tsx
@@ -0,0 +1,17 @@
+import { SegmentedControl, SegmentedControlItem, Text } from "@hopper-ui/components";
+import { OrderedListIcon, UnorderedListIcon } from "@hopper-ui/icons";
+
+export default function Example() {
+    return (
+        <SegmentedControl aria-label="List ordering">
+            <SegmentedControlItem id="unordered">
+                <UnorderedListIcon />
+                <Text>Unordered</Text>
+            </SegmentedControlItem>
+            <SegmentedControlItem id="ordered">
+                <Text>Ordered</Text>
+                <OrderedListIcon />
+            </SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/docs/iconOnly.tsx b/packages/components/src/SegmentedControl/docs/iconOnly.tsx
new file mode 100644
index 00000000..2dd3de56
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/iconOnly.tsx
@@ -0,0 +1,15 @@
+import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
+import { OrderedListIcon, UnorderedListIcon } from "@hopper-ui/icons";
+
+export default function Example() {
+    return (
+        <SegmentedControl aria-label="List ordering">
+            <SegmentedControlItem id="unordered">
+                <UnorderedListIcon />
+            </SegmentedControlItem>
+            <SegmentedControlItem id="ordered">
+                <OrderedListIcon />
+            </SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/docs/preview.tsx b/packages/components/src/SegmentedControl/docs/preview.tsx
new file mode 100644
index 00000000..ab2b4905
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/preview.tsx
@@ -0,0 +1,12 @@
+import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
+
+export default function Example() {
+    return (
+        <SegmentedControl aria-label="Time granularity">
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/docs/selected.tsx b/packages/components/src/SegmentedControl/docs/selected.tsx
new file mode 100644
index 00000000..ccfa53bf
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/selected.tsx
@@ -0,0 +1,12 @@
+import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
+
+export default function Example() {
+    return (
+        <SegmentedControl aria-label="Time granularity" defaultSelectedKey="day">
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/docs/size.tsx b/packages/components/src/SegmentedControl/docs/size.tsx
new file mode 100644
index 00000000..51485dbc
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/size.tsx
@@ -0,0 +1,12 @@
+import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
+
+export default function Example() {
+    return (
+        <SegmentedControl aria-label="Time granularity" defaultSelectedKey="day" size="md">
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/index.ts b/packages/components/src/SegmentedControl/index.ts
new file mode 100644
index 00000000..401c73ac
--- /dev/null
+++ b/packages/components/src/SegmentedControl/index.ts
@@ -0,0 +1 @@
+export * from "./src/index.ts";
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
new file mode 100644
index 00000000..28a90d45
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
@@ -0,0 +1,43 @@
+.hop-SegmentedControl {
+    --hop-SegmentedControl-gap: var(--hop-space-inline-xs);
+    --hop-SegmentedControl-padding: var(--hop-space-inset-xs);
+    --hop-SegmentedControl-witdh: fit-content;
+    --hop-SegmentedControl-background: var(--hop-neutral-surface);
+    --hop-SegmentedControl-border: 0.0625rem solid var(--hop-neutral-border);
+    --hop-SegmentedControl-border-radius: var(--hop-shape-rounded-md);
+
+     /* Item background selected animation */
+    --hop-SegmentedControl-item-width: 0rem;
+    --hop-SegmentedControl-item-border-radius: var(--hop-shape-rounded-sm);
+    --hop-SegmentedControl-item-offset: 0rem;
+
+    position: relative;
+
+    display: flex;
+    gap: var(--hop-SegmentedControl-gap);
+    align-items: center;
+    justify-content: center;
+
+    inline-size: var(--hop-SegmentedControl-witdh);
+    padding: var(--hop-SegmentedControl-padding);
+
+    background: var(--hop-SegmentedControl-background);
+    border: var(--hop-SegmentedControl-border);
+    border-radius: var(--hop-SegmentedControl-border-radius)
+}
+
+.hop-SegmentedControl::after {
+    content: '';
+
+    position: absolute;
+    inset-block-start: var(--hop-SegmentedControl-padding);
+    inset-inline-start: var(--hop-SegmentedControl-item-offset);
+
+    inline-size: var(--hop-SegmentedControl-item-width);
+    block-size: calc(100% - 2 * var(--hop-SegmentedControl-padding));
+
+    background: var(--hop-neutral-surface-selected);
+    border-radius: var(--hop-SegmentedControl-item-border-radius);
+
+    transition: left 0.3s;
+}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
new file mode 100644
index 00000000..dd24d807
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -0,0 +1,144 @@
+import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
+import clsx from "clsx";
+import { forwardRef, useEffect, useMemo, useState, type CSSProperties, type ForwardedRef } from "react";
+import { Provider, ToggleButtonGroup, useContextProps, type Key } from "react-aria-components";
+
+import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
+
+import { SegmentedControlContext } from "./SegmentedControlContext.ts";
+import type { SegmentedControlItemSize } from "./SegmentedControlItem.tsx";
+import { SegmentedControlItemContext } from "./SegmentedControlItemContext.ts";
+
+import styles from "./SegmentedControl.module.css";
+
+export const GlobalSegmentedControlCssSelector = "hop-SegmentedControl";
+
+export interface SegmentedControlProps extends StyledComponentProps<BaseComponentDOMProps> {
+    /**
+    *  Whether the segmented control is disabled.
+    */
+    isDisabled?: boolean;
+    /**
+     * The id of the currently selected item (controlled).
+     */
+    selectedKey?: Key;
+    /**
+     * The id of the initial selected item (uncontrolled).
+     */
+    defaultSelectedKey?: Key;
+    /**
+     * Handler that is called when the selection changes.
+     */
+    onSelectionChange?: (id: Key) => void;
+    /**
+     * The size of the controls.
+     * * @default "sm"
+     */
+    size?: ResponsiveProp<SegmentedControlItemSize>;
+}
+
+const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDivElement>) => {
+    [props, ref] = useContextProps(props, ref, SegmentedControlContext);
+
+    const { stylingProps, ...ownProps } = useStyledSystem(props);
+    const {
+        className,
+        children,
+        style,
+        slot,
+        defaultSelectedKey,
+        selectedKey,
+        onSelectionChange,
+        ...otherProps
+    } = ownProps;
+
+    const [selected, setSelected] = useState<Key | undefined>(defaultSelectedKey ?? selectedKey);
+
+    const classNames = clsx(
+        GlobalSegmentedControlCssSelector,
+        cssModule(
+            styles,
+            "hop-SegmentedControl"
+        ),
+        stylingProps.className,
+        className
+    );
+
+    const mergedStyles: CSSProperties = {
+        ...style,
+        ...stylingProps.style
+    };
+
+    const onChange = (values: Set<Key>) => {
+        const [firstKey] = values;
+
+        if (!firstKey) {
+            return;
+        }
+
+        setSelected(firstKey);
+        onSelectionChange?.(firstKey);
+    };
+
+    const selectedKeys = useMemo(() => {
+        if (onSelectionChange) {
+            return selectedKey != null ? [selectedKey] : undefined;
+        }
+
+        return selected ? [selected] : undefined;
+    }, [onSelectionChange, selectedKey, selected]);
+
+    useEffect(() => {
+        const container = ref.current;
+
+        // Code to create sliding animation background between buttons when selecting a new value
+        if (container && (selectedKeys || defaultSelectedKey)) {
+            const { childNodes } = container;
+
+            const childNodesArray = Array.from(childNodes) as HTMLElement[];
+
+            const [firstKey] = selectedKeys ?? [];
+            const key = firstKey ?? defaultSelectedKey;
+            const selectedNode = childNodesArray.find(x => x.getAttribute("data-key") === key);
+
+            if (!selectedNode) {
+                return;
+            }
+
+            container.style.setProperty("--hop-SegmentedControl-item-width", `${selectedNode.offsetWidth}px`);
+            container.style.setProperty("--hop-SegmentedControl-item-offset", `${selectedNode.offsetLeft}px`);
+        }
+    }, [ref, selectedKeys, defaultSelectedKey]);
+
+    return (
+        <ToggleButtonGroup
+            ref={ref}
+            className={classNames}
+            style={mergedStyles}
+            slot={slot ?? undefined}
+            selectedKeys={selectedKeys}
+            defaultSelectedKeys={defaultSelectedKey != null ? [defaultSelectedKey] : undefined}
+            orientation="horizontal"
+            onSelectionChange={onChange}
+            {...otherProps}
+        >
+            <Provider
+                values={[
+                    [SegmentedControlItemContext, otherProps]
+                ]}
+            >
+                {children}
+            </Provider>
+        </ToggleButtonGroup>
+    );
+};
+
+/**
+ * Segmented control displays multiple contextually or conceptually related action or option stacked in a horizontal row.
+ *
+ * [View Documentation](TODO)
+ */
+const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(SegmentedControl);
+_SegmentedControl.displayName = "SegmentedControl";
+
+export { _SegmentedControl as SegmentedControl };
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
new file mode 100644
index 00000000..b5397cf0
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
@@ -0,0 +1,8 @@
+import { createContext } from "react";
+import type { ContextValue } from "react-aria-components";
+
+import type { SegmentedControlProps } from "./SegmentedControl.tsx";
+
+export const SegmentedControlContext = createContext<ContextValue<SegmentedControlProps, HTMLDivElement>>({});
+
+SegmentedControlContext.displayName = "SegmentedControlContext";
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
new file mode 100644
index 00000000..d0ac2918
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -0,0 +1,64 @@
+.hop-SegmentedControlItem {
+    /* Default */
+    --hop-SegmentedControlItem-gap: var(--hop-space-inline-xs);
+    --hop-SegmentedControlItem-color: var(--hop-neutral-text);
+    --hop-SegmentedControlItem-background: transparent;
+    --hop-SegmentedControlItem-border: none;
+    --hop-SegmentedControlItem-border-radius: var(--hop-shape-rounded-sm);
+    --hop-SegmentedControlItem-cursor: auto;
+    --hop-SegmentedControlItem-z-index: 1;
+    --hop-SegmentedControlItem-color-transition: color 0.3s;
+
+    /* Small */
+    --hop-SegmentedControlItem-sm-padding:  0.125rem var(--hop-space-inset-md);
+
+    /* Medium */
+    --hop-SegmentedControlItem-md-padding:  0.375rem var(--hop-space-inset-md);
+
+    cursor: var(--hop-SegmentedControlItem-cursor);
+
+    z-index: var(--hop-SegmentedControlItem-z-index);
+
+    display: flex;
+    gap: var(--hop-SegmentedControlItem-gap);
+    align-items: center;
+    justify-content: center;
+
+    padding: var(--hop-SegmentedControlItem-sm-padding);
+
+    color: var(--hop-SegmentedControlItem-color);
+
+    background: var(--hop-SegmentedControlItem-background);
+    border: var(--hop-SegmentedControlItem-border);
+    border-radius: var(--hop-SegmentedControlItem-border-radius);
+
+    transition: var(--hop-SegmentedControlItem-color-transition);
+}
+
+.hop-SegmentedControlItem:not([data-disabled]) {
+    --hop-SegmentedControlItem-cursor: pointer;
+}
+
+.hop-SegmentedControlItem[data-hovered], .hop-SegmentedControlItem[data-focused] {
+    --hop-SegmentedControlItem-color: var(--hop-neutral-text-hover);
+    --hop-SegmentedControlItem-background: var(--hop-neutral-surface-hover);
+}
+
+.hop-SegmentedControlItem[data-pressed] {
+    --hop-SegmentedControlItem-color: var(--hop-neutral-text-press);
+    --hop-SegmentedControlItem-background: var(--hop-neutral-surface-press);
+}
+
+.hop-SegmentedControlItem[data-selected] {
+    --hop-SegmentedControlItem-color: var(--hop-neutral-text-selected);
+    --hop-SegmentedControlItem-background: transparent;
+}
+
+.hop-SegmentedControlItem[data-disabled] {
+    --hop-SegmentedControlItem-color: var(--hop-neutral-text-disabled);
+    --hop-SegmentedControlItem-background: var(--hop-neutral-surface);
+}
+
+.hop-SegmentedControlItem--md {
+    --hop-SegmentedControlItem-padding: var(--hop-SegmentedControlItem-md-padding);
+}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
new file mode 100644
index 00000000..5674b683
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -0,0 +1,97 @@
+import { IconContext } from "@hopper-ui/icons";
+import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
+import clsx from "clsx";
+import { forwardRef, type CSSProperties, type ForwardedRef } from "react";
+import { Provider, ToggleButton, useContextProps, type Key } from "react-aria-components";
+
+import { Text, TextContext } from "../../typography/index.ts";
+import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
+
+import { SegmentedControlItemContext } from "./SegmentedControlItemContext.ts";
+
+import styles from "./SegmentedControlItem.module.css";
+
+export const GlobalSegmentedControlItemCssSelector = "hop-SegmentedControlItem";
+
+export type SegmentedControlItemSize = "sm" | "md";
+
+export interface SegmentedControlItemProps extends Omit<StyledComponentProps<BaseComponentDOMProps>, "id"> {
+    /**
+     * The id of the item, matching the value used in SegmentedControl's `selectedKey` prop.
+     */
+    id: Key;
+    /**
+     * Whether the item is disabled or not.
+     */
+    isDisabled?: boolean;
+    /**
+     * The size of the item.
+     * * @default "sm"
+     */
+    size?: ResponsiveProp<SegmentedControlItemSize>;
+}
+
+const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRef<HTMLButtonElement>) => {
+    [props, ref] = useContextProps(props, ref, SegmentedControlItemContext);
+
+    const { stylingProps, ...ownProps } = useStyledSystem(props);
+    const {
+        className,
+        children,
+        style,
+        slot,
+        size = "sm",
+        ...otherProps
+    } = ownProps;
+
+    const classNames = clsx(
+        GlobalSegmentedControlItemCssSelector,
+        cssModule(
+            styles,
+            "hop-SegmentedControlItem",
+            size
+        ),
+        stylingProps.className,
+        className
+    );
+
+    const mergedStyles: CSSProperties = {
+        ...style,
+        ...stylingProps.style
+    };
+
+    return (
+        <ToggleButton
+            {...otherProps}
+            ref={ref}
+            className={classNames}
+            style={mergedStyles}
+            slot={slot ?? undefined}
+            data-key={props.id}
+        >
+            <Provider
+                values={[
+                    [IconContext, {
+                        size
+                    }],
+                    [TextContext, {
+                        size: "sm"
+                    }]
+                ]}
+            >
+                {typeof children === "string" ? <Text>{children}</Text> : children}
+            </Provider>
+        </ToggleButton>
+    );
+};
+
+/**
+ * A SegmentedControlItem represents an option within a SegmentedControl.
+ *
+ * [View Documentation](TODO)
+ */
+const _SegmentedControlItem = forwardRef<HTMLButtonElement, SegmentedControlItemProps>(SegmentedControlItem);
+_SegmentedControlItem.displayName = "SegmentedControlItem";
+
+export { _SegmentedControlItem as SegmentedControlItem };
+
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItemContext.ts b/packages/components/src/SegmentedControl/src/SegmentedControlItemContext.ts
new file mode 100644
index 00000000..3a83be78
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItemContext.ts
@@ -0,0 +1,10 @@
+import { createContext } from "react";
+import type { ContextValue } from "react-aria-components";
+
+import type { SegmentedControlItemProps } from "./SegmentedControlItem.tsx";
+
+interface InternalSegmentedControlItemProps extends Omit<SegmentedControlItemProps, "id"> {}
+
+export const SegmentedControlItemContext = createContext<ContextValue<InternalSegmentedControlItemProps, HTMLButtonElement>>({});
+
+SegmentedControlItemContext.displayName = "SegmentedControlItemContext";
diff --git a/packages/components/src/SegmentedControl/src/index.ts b/packages/components/src/SegmentedControl/src/index.ts
new file mode 100644
index 00000000..299fbc8a
--- /dev/null
+++ b/packages/components/src/SegmentedControl/src/index.ts
@@ -0,0 +1,3 @@
+export * from "./SegmentedControl.tsx";
+export * from "./SegmentedControlItem.tsx";
+
diff --git a/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx b/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
new file mode 100644
index 00000000..950eeab9
--- /dev/null
+++ b/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
@@ -0,0 +1,164 @@
+import { OrderedListIcon, UnorderedListIcon } from "@hopper-ui/icons";
+import type { Meta, StoryObj } from "@storybook/react";
+
+import { Inline, Stack } from "../../../layout/index.ts";
+import { Text } from "../../../typography/Text/index.ts";
+import { SegmentedControl, SegmentedControlItem } from "../../src/index.ts";
+
+const meta = {
+    title: "Components/SegmentedControl",
+    component: SegmentedControl
+} satisfies Meta<typeof SegmentedControl>;
+
+export default meta;
+
+type Story = StoryObj<typeof meta>;
+
+export const Default = {
+    render: props => (
+        <SegmentedControl defaultSelectedKey="day" {...props}>
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
+        </SegmentedControl>
+    ),
+    args: {
+        "aria-label": "Time granularity"
+    }
+} satisfies Story;
+
+export const Sizes = {
+    render: props => (
+        <Stack>
+            <Inline>
+                <SegmentedControl defaultSelectedKey="day" {...props}>
+                    <SegmentedControlItem id="day">Day</SegmentedControlItem>
+                    <SegmentedControlItem id="week">Week</SegmentedControlItem>
+                    <SegmentedControlItem id="month">Month</SegmentedControlItem>
+                    <SegmentedControlItem id="year">Year</SegmentedControlItem>
+                </SegmentedControl>
+                <SegmentedControl defaultSelectedKey="day" {...props} size="md">
+                    <SegmentedControlItem id="day">Day</SegmentedControlItem>
+                    <SegmentedControlItem id="week">Week</SegmentedControlItem>
+                    <SegmentedControlItem id="month">Month</SegmentedControlItem>
+                    <SegmentedControlItem id="year">Year</SegmentedControlItem>
+                </SegmentedControl>
+            </Inline>
+            <Inline>
+                <SegmentedControl defaultSelectedKey="unordered" {...props}>
+                    <SegmentedControlItem id="unordered">
+                        <UnorderedListIcon />
+                        <Text>Unordered</Text>
+                    </SegmentedControlItem>
+                    <SegmentedControlItem id="ordered">
+                        <OrderedListIcon />
+                        <Text>Ordered</Text>
+                    </SegmentedControlItem>
+                </SegmentedControl>
+                <SegmentedControl defaultSelectedKey="unordered" size="md" {...props}>
+                    <SegmentedControlItem id="unordered">
+                        <UnorderedListIcon />
+                        <Text>Unordered</Text>
+                    </SegmentedControlItem>
+                    <SegmentedControlItem id="ordered">
+                        <OrderedListIcon />
+                        <Text>Ordered</Text>
+                    </SegmentedControlItem>
+                </SegmentedControl>
+            </Inline>
+            <Inline>
+                <SegmentedControl defaultSelectedKey="unordered" {...props} >
+                    <SegmentedControlItem aria-label="Unordered" id="unordered"><UnorderedListIcon /></SegmentedControlItem>
+                    <SegmentedControlItem aria-label="Ordered" id="ordered"><OrderedListIcon /></SegmentedControlItem>
+                </SegmentedControl>
+                <SegmentedControl defaultSelectedKey="unordered" size="md" {...props} >
+                    <SegmentedControlItem aria-label="Unordered" id="unordered"><UnorderedListIcon /></SegmentedControlItem>
+                    <SegmentedControlItem aria-label="Ordered" id="ordered"><OrderedListIcon /></SegmentedControlItem>
+                </SegmentedControl>
+            </Inline>
+        </Stack>
+    ),
+    args: {
+        "aria-label": "Example of sizes"
+    }
+} satisfies Story;
+
+export const WithIcons = {
+    render: props => (
+        <SegmentedControl defaultSelectedKey="unordered" {...props}>
+            <SegmentedControlItem id="unordered">
+                <UnorderedListIcon />
+                <Text>Unordered</Text>
+            </SegmentedControlItem>
+            <SegmentedControlItem id="ordered">
+                <OrderedListIcon />
+                <Text>Ordered</Text>
+            </SegmentedControlItem>
+        </SegmentedControl>
+    ),
+    args: {
+        "aria-label": "List organization"
+    }
+} satisfies Story;
+
+export const WithTrailingIcons = {
+    render: props => (
+        <SegmentedControl defaultSelectedKey="unordered" {...props}>
+            <SegmentedControlItem id="unordered">
+                <Text>Unordered</Text>
+                <UnorderedListIcon />
+            </SegmentedControlItem>
+            <SegmentedControlItem id="ordered">
+                <Text>Ordered</Text>
+                <OrderedListIcon />
+            </SegmentedControlItem>
+        </SegmentedControl>
+    ),
+    args: {
+        "aria-label": "List organization"
+    }
+} satisfies Story;
+
+export const OnlyIcons = {
+    render: props => (
+        <SegmentedControl defaultSelectedKey="unordered" {...props} >
+            <SegmentedControlItem aria-label="Unordered" id="unordered"><UnorderedListIcon /></SegmentedControlItem>
+            <SegmentedControlItem aria-label="Ordered" id="ordered"><OrderedListIcon /></SegmentedControlItem>
+        </SegmentedControl>
+    ),
+    args: {
+        "aria-label": "List organization"
+    }
+} satisfies Story;
+
+export const Disabled = {
+    render: props => (
+        <Stack>
+            <SegmentedControl isDisabled defaultSelectedKey="day" {...props}>
+                <SegmentedControlItem id="day">Day</SegmentedControlItem>
+                <SegmentedControlItem id="week">Week</SegmentedControlItem>
+                <SegmentedControlItem id="month">Month</SegmentedControlItem>
+                <SegmentedControlItem id="year">Year</SegmentedControlItem>
+            </SegmentedControl>
+            <SegmentedControl isDisabled defaultSelectedKey="unordered" {...props}>
+                <SegmentedControlItem id="unordered">
+                    <UnorderedListIcon />
+                    <Text>Unordered</Text>
+                </SegmentedControlItem>
+                <SegmentedControlItem id="ordered">
+                    <OrderedListIcon />
+                    <Text>Ordered</Text>
+                </SegmentedControlItem>
+            </SegmentedControl>
+            <SegmentedControl isDisabled defaultSelectedKey="unordered" {...props} >
+                <SegmentedControlItem aria-label="Unordered" id="unordered"><UnorderedListIcon /></SegmentedControlItem>
+                <SegmentedControlItem aria-label="Ordered" id="ordered"><OrderedListIcon /></SegmentedControlItem>
+            </SegmentedControl>
+        </Stack>
+    ),
+    args: {
+        "aria-label": "Examples of disabled segmented controls"
+    }
+} satisfies Story;
+
diff --git a/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.ssr.test.tsx b/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.ssr.test.tsx
new file mode 100644
index 00000000..cd7bb30e
--- /dev/null
+++ b/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.ssr.test.tsx
@@ -0,0 +1,19 @@
+/**
+ * @jest-environment node
+ */
+import { renderToString } from "react-dom/server";
+
+import { SegmentedControl } from "../../src/SegmentedControl.tsx";
+
+describe("SegmentedControl", () => {
+    it("should render on the server", () => {
+        const renderOnServer = () =>
+            renderToString(
+                <SegmentedControl>
+                    test
+                </SegmentedControl>
+            );
+
+        expect(renderOnServer).not.toThrow();
+    });
+});
diff --git a/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx b/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx
new file mode 100644
index 00000000..775301c9
--- /dev/null
+++ b/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx
@@ -0,0 +1,90 @@
+/* eslint-disable testing-library/no-node-access */
+/* Using closest to get the label is the best way, even react-aria does this. */
+import { render, screen } from "@hopper-ui/test-utils";
+import { createRef } from "react";
+
+import { SegmentedControl, SegmentedControlItem } from "../../src/index.ts";
+import { SegmentedControlContext } from "../../src/SegmentedControlContext.ts";
+
+describe("SegmentedControl", () => {
+    it("should render with default class", () => {
+        render(<SegmentedControl aria-label="options"><SegmentedControlItem id="day">Day</SegmentedControlItem><SegmentedControlItem id="week">Week</SegmentedControlItem></SegmentedControl>);
+
+        const element = screen.getByRole("radiogroup");
+        expect(element).toHaveClass("hop-SegmentedControl");
+    });
+
+    it("should support custom class", () => {
+        render(<SegmentedControl aria-label="options" className="test"><SegmentedControlItem id="option1">option 1</SegmentedControlItem></SegmentedControl>);
+
+        const element = screen.getByRole("radiogroup");
+        expect(element).toHaveClass("hop-SegmentedControl");
+        expect(element).toHaveClass("test");
+    });
+
+    it("should support custom style", () => {
+        render(<SegmentedControl aria-label="options" marginTop="stack-sm" style={{ marginBottom: "13px" }}>
+            <SegmentedControlItem id="option1">option 1</SegmentedControlItem>
+        </SegmentedControl>);
+
+        const element = screen.getByRole("radiogroup");
+        expect(element).toHaveStyle({ marginTop: "var(--hop-space-stack-sm)", marginBottom: "13px" });
+    });
+
+    it("should support DOM props", () => {
+        render(<SegmentedControl aria-label="options" data-foo="bar"><SegmentedControlItem id="option1">option 1</SegmentedControlItem></SegmentedControl>);
+
+        const element = screen.getByRole("radiogroup");
+        expect(element).toHaveAttribute("data-foo", "bar");
+    });
+
+    it("should support slots", () => {
+        render(
+            <SegmentedControlContext.Provider value={{ slots: { test: { "aria-label": "test" } } }}>
+                <SegmentedControl slot="test"><SegmentedControlItem id="option1">option 1</SegmentedControlItem></SegmentedControl>
+            </SegmentedControlContext.Provider>
+        );
+
+        const element = screen.getByRole("radiogroup");
+
+        expect(element).toHaveAttribute("slot", "test");
+        expect(element).toHaveAttribute("aria-label", "test");
+    });
+
+    it("should support refs", () => {
+        const ref = createRef<HTMLDivElement>();
+        render(<SegmentedControl aria-label="options" ref={ref}><SegmentedControlItem id="option1">option 1</SegmentedControlItem></SegmentedControl>);
+
+        expect(ref.current).not.toBeNull();
+        expect(ref.current instanceof HTMLDivElement).toBeTruthy();
+    });
+
+    it("should pass the size to the SegmentedControlItem.", () => {
+        const testId = "SegmentedControlItem";
+
+        render(
+            <SegmentedControl aria-label="options" size="sm">
+                <SegmentedControlItem data-testid={testId} id="option1">
+                    option 1
+                </SegmentedControlItem>
+            </SegmentedControl>
+        );
+
+        const item = screen.getByTestId(testId);
+        expect(item).toHaveClass("hop-SegmentedControlItem--sm");
+    });
+
+    it("should be disabled and pass it to the SegmentedControlItem.", () => {
+        const testId = "SegmentedControlItem";
+
+        render(<SegmentedControl aria-label="options" isDisabled><SegmentedControlItem data-testid={testId} id="option1">option 1</SegmentedControlItem></SegmentedControl>);
+
+        const element = screen.getByRole("radiogroup");
+        expect(element).toHaveAttribute("data-disabled", "true");
+
+        const item = screen.getByTestId(testId);
+        expect(item).toHaveAttribute("data-disabled", "true");
+
+        expect(item).toBeDisabled();
+    });
+});
diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts
index 204f3cb6..7733b5dc 100644
--- a/packages/components/src/index.ts
+++ b/packages/components/src/index.ts
@@ -21,6 +21,7 @@ export * from "./ListBox/index.ts";
 export * from "./ListBoxSection/index.ts";
 export * from "./overlays/Popover/index.ts";
 export * from "./radio/index.ts";
+export * from "./SegmentedControl/index.ts";
 export * from "./Select/index.ts";
 export * from "./Spinner/index.ts";
 export * from "./switch/index.ts";

From c164134333d17795a30f05332fbddf60fbbeb182 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Wed, 8 Jan 2025 16:56:16 -0500
Subject: [PATCH 02/17] Revert weird changes

---
 .../app/ui/components/componentExample/ComponentExample.tsx     | 2 +-
 apps/docs/app/ui/layout/header/Header.tsx                       | 2 +-
 apps/docs/components/themeSwitch/ThemeSwitch.tsx                | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/apps/docs/app/ui/components/componentExample/ComponentExample.tsx b/apps/docs/app/ui/components/componentExample/ComponentExample.tsx
index 16970e7e..6c59dd9d 100644
--- a/apps/docs/app/ui/components/componentExample/ComponentExample.tsx
+++ b/apps/docs/app/ui/components/componentExample/ComponentExample.tsx
@@ -4,7 +4,7 @@ import clsx from "clsx";
 import { memo, useEffect, useState, type ReactNode } from "react";
 
 import { CodeIcon, Icon, StackblitzIcon } from "@/components/icon";
-import { ToggleButton } from "@/components/ToggleButton/ToggleButton.tsx";
+import { ToggleButton } from "@/components/toggleButton/ToggleButton.tsx";
 import { useToggle } from "@/hooks/useToggle.ts";
 
 import ComponentPreviewWrapper from "./ComponentPreviewWrapper.tsx";
diff --git a/apps/docs/app/ui/layout/header/Header.tsx b/apps/docs/app/ui/layout/header/Header.tsx
index b9cfbe21..89609556 100644
--- a/apps/docs/app/ui/layout/header/Header.tsx
+++ b/apps/docs/app/ui/layout/header/Header.tsx
@@ -12,7 +12,7 @@ import { Icon, ProductMenuIcon } from "@/components/icon";
 import LinkIconButton from "@/components/iconButton/LinkIconButton";
 import { Popover, PopoverContext, PopoverTrigger } from "@/components/popover/Popover.tsx";
 import ThemeSwitch from "@/components/themeSwitch/ThemeSwitch";
-import { ToggleButton, ToggleButtonContext } from "@/components/ToggleButton/ToggleButton";
+import { ToggleButton, ToggleButtonContext } from "@/components/toggleButton/ToggleButton.tsx";
 import { navigation } from "@/configs/navigation";
 import { ThemeContext, type ColorScheme } from "@/context/theme/ThemeProvider.tsx";
 import { useIsMobile } from "@/hooks/useIsMobile";
diff --git a/apps/docs/components/themeSwitch/ThemeSwitch.tsx b/apps/docs/components/themeSwitch/ThemeSwitch.tsx
index 650dc4a8..97f30a18 100644
--- a/apps/docs/components/themeSwitch/ThemeSwitch.tsx
+++ b/apps/docs/components/themeSwitch/ThemeSwitch.tsx
@@ -1,4 +1,4 @@
-import { ToggleButton } from "@/components/ToggleButton/ToggleButton";
+import { ToggleButton } from "@/components/toggleButton/ToggleButton";
 
 import Icon from "@/components/themeSwitch/ThemeSwitchIcons";
 import type { ColorScheme } from "@/context/theme/ThemeProvider";

From ba5e3eb0a17c651f254eaf8a54b7b8ec8333cc41 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Thu, 9 Jan 2025 17:49:56 -0500
Subject: [PATCH 03/17] Fix animation to match more Spectrum

---
 .../src/SegmentedControl.module.css           | 16 -----
 .../SegmentedControl/src/SegmentedControl.tsx | 53 ++++++---------
 .../src/SegmentedControlContext.ts            |  9 ++-
 .../src/SegmentedControlItem.module.css       | 20 ++++--
 .../src/SegmentedControlItem.tsx              | 68 +++++++++++++++----
 5 files changed, 93 insertions(+), 73 deletions(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
index 28a90d45..63ca6130 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
@@ -11,8 +11,6 @@
     --hop-SegmentedControl-item-border-radius: var(--hop-shape-rounded-sm);
     --hop-SegmentedControl-item-offset: 0rem;
 
-    position: relative;
-
     display: flex;
     gap: var(--hop-SegmentedControl-gap);
     align-items: center;
@@ -26,18 +24,4 @@
     border-radius: var(--hop-SegmentedControl-border-radius)
 }
 
-.hop-SegmentedControl::after {
-    content: '';
-
-    position: absolute;
-    inset-block-start: var(--hop-SegmentedControl-padding);
-    inset-inline-start: var(--hop-SegmentedControl-item-offset);
-
-    inline-size: var(--hop-SegmentedControl-item-width);
-    block-size: calc(100% - 2 * var(--hop-SegmentedControl-padding));
 
-    background: var(--hop-neutral-surface-selected);
-    border-radius: var(--hop-SegmentedControl-item-border-radius);
-
-    transition: left 0.3s;
-}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index dd24d807..d29b8ac5 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -1,11 +1,11 @@
 import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
 import clsx from "clsx";
-import { forwardRef, useEffect, useMemo, useState, type CSSProperties, type ForwardedRef } from "react";
-import { Provider, ToggleButtonGroup, useContextProps, type Key } from "react-aria-components";
+import { forwardRef, useContext, useEffect, useRef, type CSSProperties, type ForwardedRef } from "react";
+import { Provider, ToggleButtonGroup, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
 import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
 
-import { SegmentedControlContext } from "./SegmentedControlContext.ts";
+import { InternalSegmentedControlContext, SegmentedControlContext } from "./SegmentedControlContext.ts";
 import type { SegmentedControlItemSize } from "./SegmentedControlItem.tsx";
 import { SegmentedControlItemContext } from "./SegmentedControlItemContext.ts";
 
@@ -39,6 +39,10 @@ export interface SegmentedControlProps extends StyledComponentProps<BaseComponen
 
 const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDivElement>) => {
     [props, ref] = useContextProps(props, ref, SegmentedControlContext);
+    const state = useContext(ToggleGroupStateContext);
+
+    const prevRef = useRef<DOMRect | null>(null);
+    const currentSelectedRef = useRef<HTMLDivElement>(null);
 
     const { stylingProps, ...ownProps } = useStyledSystem(props);
     const {
@@ -49,11 +53,10 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         defaultSelectedKey,
         selectedKey,
         onSelectionChange,
+        size,
         ...otherProps
     } = ownProps;
 
-    const [selected, setSelected] = useState<Key | undefined>(defaultSelectedKey ?? selectedKey);
-
     const classNames = clsx(
         GlobalSegmentedControlCssSelector,
         cssModule(
@@ -76,39 +79,20 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
             return;
         }
 
-        setSelected(firstKey);
-        onSelectionChange?.(firstKey);
-    };
-
-    const selectedKeys = useMemo(() => {
-        if (onSelectionChange) {
-            return selectedKey != null ? [selectedKey] : undefined;
+        if (currentSelectedRef.current) {
+            prevRef.current = currentSelectedRef?.current.getBoundingClientRect();
         }
 
-        return selected ? [selected] : undefined;
-    }, [onSelectionChange, selectedKey, selected]);
+        onSelectionChange?.(firstKey);
+    };
 
     useEffect(() => {
-        const container = ref.current;
-
-        // Code to create sliding animation background between buttons when selecting a new value
-        if (container && (selectedKeys || defaultSelectedKey)) {
-            const { childNodes } = container;
-
-            const childNodesArray = Array.from(childNodes) as HTMLElement[];
-
-            const [firstKey] = selectedKeys ?? [];
-            const key = firstKey ?? defaultSelectedKey;
-            const selectedNode = childNodesArray.find(x => x.getAttribute("data-key") === key);
-
-            if (!selectedNode) {
-                return;
-            }
+        const key = defaultSelectedKey ?? selectedKey;
 
-            container.style.setProperty("--hop-SegmentedControl-item-width", `${selectedNode.offsetWidth}px`);
-            container.style.setProperty("--hop-SegmentedControl-item-offset", `${selectedNode.offsetLeft}px`);
+        if (key) {
+            state?.toggleKey(key);
         }
-    }, [ref, selectedKeys, defaultSelectedKey]);
+    }, []);
 
     return (
         <ToggleButtonGroup
@@ -116,7 +100,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
             className={classNames}
             style={mergedStyles}
             slot={slot ?? undefined}
-            selectedKeys={selectedKeys}
+            selectedKeys={selectedKey != null ? [selectedKey] : undefined}
             defaultSelectedKeys={defaultSelectedKey != null ? [defaultSelectedKey] : undefined}
             orientation="horizontal"
             onSelectionChange={onChange}
@@ -124,7 +108,8 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         >
             <Provider
                 values={[
-                    [SegmentedControlItemContext, otherProps]
+                    [SegmentedControlItemContext, { size, isDisabled: otherProps.isDisabled }],
+                    [InternalSegmentedControlContext, { prevRef, currentSelectedRef }]
                 ]}
             >
                 {children}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
index b5397cf0..43fdea0a 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
@@ -1,4 +1,4 @@
-import { createContext } from "react";
+import { createContext, type MutableRefObject, type RefObject } from "react";
 import type { ContextValue } from "react-aria-components";
 
 import type { SegmentedControlProps } from "./SegmentedControl.tsx";
@@ -6,3 +6,10 @@ import type { SegmentedControlProps } from "./SegmentedControl.tsx";
 export const SegmentedControlContext = createContext<ContextValue<SegmentedControlProps, HTMLDivElement>>({});
 
 SegmentedControlContext.displayName = "SegmentedControlContext";
+
+interface InternalSegmentedControlContextProps {
+    prevRef?: MutableRefObject<DOMRect | null>;
+    currentSelectedRef?: RefObject<HTMLDivElement>;
+}
+
+export const InternalSegmentedControlContext = createContext<InternalSegmentedControlContextProps>({});
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index d0ac2918..b925e28f 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -6,8 +6,6 @@
     --hop-SegmentedControlItem-border: none;
     --hop-SegmentedControlItem-border-radius: var(--hop-shape-rounded-sm);
     --hop-SegmentedControlItem-cursor: auto;
-    --hop-SegmentedControlItem-z-index: 1;
-    --hop-SegmentedControlItem-color-transition: color 0.3s;
 
     /* Small */
     --hop-SegmentedControlItem-sm-padding:  0.125rem var(--hop-space-inset-md);
@@ -17,22 +15,23 @@
 
     cursor: var(--hop-SegmentedControlItem-cursor);
 
-    z-index: var(--hop-SegmentedControlItem-z-index);
+    position: relative;
 
     display: flex;
     gap: var(--hop-SegmentedControlItem-gap);
     align-items: center;
     justify-content: center;
 
-    padding: var(--hop-SegmentedControlItem-sm-padding);
+    padding: var(--hop-SegmentedControlItem-padding, var(--hop-SegmentedControlItem-sm-padding));
 
     color: var(--hop-SegmentedControlItem-color);
 
-    background: var(--hop-SegmentedControlItem-background);
+    background: var(--hop-SegmentedControlItem-background)
+}
+
+.hop-SegmentedControlItem, .hop-SegmentedControlItem__slider {
     border: var(--hop-SegmentedControlItem-border);
     border-radius: var(--hop-SegmentedControlItem-border-radius);
-
-    transition: var(--hop-SegmentedControlItem-color-transition);
 }
 
 .hop-SegmentedControlItem:not([data-disabled]) {
@@ -62,3 +61,10 @@
 .hop-SegmentedControlItem--md {
     --hop-SegmentedControlItem-padding: var(--hop-SegmentedControlItem-md-padding);
 }
+
+.hop-SegmentedControlItem__slider {
+    position: absolute;
+    inline-size: 100%;
+    block-size: 100%;
+    background: var(--hop-neutral-surface-selected);
+}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 5674b683..57e2c4cd 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -1,12 +1,13 @@
 import { IconContext } from "@hopper-ui/icons";
 import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
 import clsx from "clsx";
-import { forwardRef, type CSSProperties, type ForwardedRef } from "react";
-import { Provider, ToggleButton, useContextProps, type Key } from "react-aria-components";
+import { forwardRef, useContext, useLayoutEffect, type CSSProperties, type ForwardedRef } from "react";
+import { Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
 import { Text, TextContext } from "../../typography/index.ts";
 import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
 
+import { InternalSegmentedControlContext } from "./SegmentedControlContext.ts";
 import { SegmentedControlItemContext } from "./SegmentedControlItemContext.ts";
 
 import styles from "./SegmentedControlItem.module.css";
@@ -33,6 +34,9 @@ export interface SegmentedControlItemProps extends Omit<StyledComponentProps<Bas
 
 const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRef<HTMLButtonElement>) => {
     [props, ref] = useContextProps(props, ref, SegmentedControlItemContext);
+    const { prevRef, currentSelectedRef } = useContext(InternalSegmentedControlContext);
+    const state = useContext(ToggleGroupStateContext);
+    const itemSelected = state?.selectedKeys.has(props.id);
 
     const { stylingProps, ...ownProps } = useStyledSystem(props);
     const {
@@ -60,6 +64,34 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
         ...stylingProps.style
     };
 
+    const isReduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
+
+    useLayoutEffect(() => {
+        if (isReduced || !itemSelected || !prevRef?.current || !currentSelectedRef?.current) {
+            return;
+        }
+
+        const prevSlider = prevRef.current;
+        const currentSlider = currentSelectedRef.current;
+
+        const currentItem = currentSlider.getBoundingClientRect();
+
+        const deltaX = prevSlider.left - currentItem?.left;
+
+        currentSelectedRef.current.animate(
+            [
+                { transform: `translateX(${deltaX}px)`, width: `${prevSlider.width}px` },
+                { transform: "translateX(0px)", width: `${currentItem.width}px` }
+            ],
+            {
+                duration: 200,
+                easing: "ease-out"
+            }
+        );
+
+        prevRef.current = null;
+    }, [currentSelectedRef, isReduced, itemSelected, prevRef]);
+
     return (
         <ToggleButton
             {...otherProps}
@@ -67,20 +99,26 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
             className={classNames}
             style={mergedStyles}
             slot={slot ?? undefined}
-            data-key={props.id}
         >
-            <Provider
-                values={[
-                    [IconContext, {
-                        size
-                    }],
-                    [TextContext, {
-                        size: "sm"
-                    }]
-                ]}
-            >
-                {typeof children === "string" ? <Text>{children}</Text> : children}
-            </Provider>
+            {({ isSelected }) => (
+                <>
+                    {isSelected && <div className={styles["hop-SegmentedControlItem__slider"]} ref={currentSelectedRef} />}
+                    <Provider
+                        values={[
+                            [IconContext, {
+                                size
+                            }],
+                            [TextContext, {
+                                size: "sm",
+                                zIndex: 1
+                            }]
+                        ]}
+                    >
+                        {typeof children === "string" ? <Text>{children}</Text> : children}
+                    </Provider>
+                </>
+            )}
+
         </ToggleButton>
     );
 };

From 6dfc40e175040ec1624435303a17c76550627f2c Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Thu, 9 Jan 2025 18:12:41 -0500
Subject: [PATCH 04/17] More fixes

---
 .../SegmentedControl/src/SegmentedControl.tsx |  1 +
 .../src/SegmentedControlItem.module.css       | 21 +++++++++++--------
 .../src/SegmentedControlItem.tsx              |  3 ++-
 .../tests/jest/SegmentedControl.test.tsx      | 12 ++++-------
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index d29b8ac5..2d2093b3 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -92,6 +92,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         if (key) {
             state?.toggleKey(key);
         }
+    // eslint-disable-next-line react-hooks/exhaustive-deps
     }, []);
 
     return (
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index b925e28f..943e9fed 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -8,10 +8,13 @@
     --hop-SegmentedControlItem-cursor: auto;
 
     /* Small */
-    --hop-SegmentedControlItem-sm-padding:  0.125rem var(--hop-space-inset-md);
+    --hop-SegmentedControlItem-sm-padding: 0.125rem var(--hop-space-inset-md);
 
     /* Medium */
-    --hop-SegmentedControlItem-md-padding:  0.375rem var(--hop-space-inset-md);
+    --hop-SegmentedControlItem-md-padding: 0.375rem var(--hop-space-inset-md);
+
+    /* Slider */
+    --hop-SegmentedControlItem-slider-background: var(--hop-neutral-surface-selected);
 
     cursor: var(--hop-SegmentedControlItem-cursor);
 
@@ -34,6 +37,13 @@
     border-radius: var(--hop-SegmentedControlItem-border-radius);
 }
 
+.hop-SegmentedControlItem__slider {
+    position: absolute;
+    inline-size: 100%;
+    block-size: 100%;
+    background: var(--hop-SegmentedControlItem-slider-background);
+}
+
 .hop-SegmentedControlItem:not([data-disabled]) {
     --hop-SegmentedControlItem-cursor: pointer;
 }
@@ -61,10 +71,3 @@
 .hop-SegmentedControlItem--md {
     --hop-SegmentedControlItem-padding: var(--hop-SegmentedControlItem-md-padding);
 }
-
-.hop-SegmentedControlItem__slider {
-    position: absolute;
-    inline-size: 100%;
-    block-size: 100%;
-    background: var(--hop-neutral-surface-selected);
-}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 57e2c4cd..bd283a8c 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -106,7 +106,8 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
                     <Provider
                         values={[
                             [IconContext, {
-                                size
+                                size,
+                                zIndex: 1
                             }],
                             [TextContext, {
                                 size: "sm",
diff --git a/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx b/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx
index 775301c9..1b025f11 100644
--- a/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx
+++ b/packages/components/src/SegmentedControl/tests/jest/SegmentedControl.test.tsx
@@ -60,29 +60,25 @@ describe("SegmentedControl", () => {
     });
 
     it("should pass the size to the SegmentedControlItem.", () => {
-        const testId = "SegmentedControlItem";
-
         render(
             <SegmentedControl aria-label="options" size="sm">
-                <SegmentedControlItem data-testid={testId} id="option1">
+                <SegmentedControlItem id="option1">
                     option 1
                 </SegmentedControlItem>
             </SegmentedControl>
         );
 
-        const item = screen.getByTestId(testId);
+        const item = screen.getByRole("radio");
         expect(item).toHaveClass("hop-SegmentedControlItem--sm");
     });
 
     it("should be disabled and pass it to the SegmentedControlItem.", () => {
-        const testId = "SegmentedControlItem";
-
-        render(<SegmentedControl aria-label="options" isDisabled><SegmentedControlItem data-testid={testId} id="option1">option 1</SegmentedControlItem></SegmentedControl>);
+        render(<SegmentedControl aria-label="options" isDisabled><SegmentedControlItem id="option1">option 1</SegmentedControlItem></SegmentedControl>);
 
         const element = screen.getByRole("radiogroup");
         expect(element).toHaveAttribute("data-disabled", "true");
 
-        const item = screen.getByTestId(testId);
+        const item = screen.getByRole("radio");
         expect(item).toHaveAttribute("data-disabled", "true");
 
         expect(item).toBeDisabled();

From c1db0db941163d471f2771cdf4acd73b0edcd5b7 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 00:52:31 -0500
Subject: [PATCH 05/17] More PR fixes

---
 apps/docs/content/components/buttons/SegmentedControl.mdx    | 3 ++-
 packages/components/src/SegmentedControl/docs/controlled.tsx | 2 +-
 packages/components/src/SegmentedControl/docs/iconOnly.tsx   | 4 ++--
 .../components/src/SegmentedControl/src/SegmentedControl.tsx | 5 +++--
 4 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/apps/docs/content/components/buttons/SegmentedControl.mdx b/apps/docs/content/components/buttons/SegmentedControl.mdx
index c3ae2c27..ed55fe66 100644
--- a/apps/docs/content/components/buttons/SegmentedControl.mdx
+++ b/apps/docs/content/components/buttons/SegmentedControl.mdx
@@ -12,7 +12,8 @@ links:
 ## Usage
 
 ### Selected
-A segmented control supports single selection. At any given time, only one item can be active.
+A segmented control can have an item initially selected, by using `defaultSelectedKey` for uncontrolled or `selectedKey` for controlled.
+Here's an example where one item is selected using defaultSelectedKey.
 
 <Example src="SegmentedControl/docs/selected" />
 
diff --git a/packages/components/src/SegmentedControl/docs/controlled.tsx b/packages/components/src/SegmentedControl/docs/controlled.tsx
index 05303931..cb65fe56 100644
--- a/packages/components/src/SegmentedControl/docs/controlled.tsx
+++ b/packages/components/src/SegmentedControl/docs/controlled.tsx
@@ -2,7 +2,7 @@ import { SegmentedControl, SegmentedControlItem, type Key } from "@hopper-ui/com
 import { useState } from "react";
 
 export default function Example() {
-    const [selectedKey, setSelectedKey] = useState<Key>();
+    const [selectedKey, setSelectedKey] = useState<Key>("day");
 
     const handleSelectionChange = (key: Key) => {
         if (selectedKey === key) {
diff --git a/packages/components/src/SegmentedControl/docs/iconOnly.tsx b/packages/components/src/SegmentedControl/docs/iconOnly.tsx
index 2dd3de56..06b0f8f1 100644
--- a/packages/components/src/SegmentedControl/docs/iconOnly.tsx
+++ b/packages/components/src/SegmentedControl/docs/iconOnly.tsx
@@ -5,10 +5,10 @@ export default function Example() {
     return (
         <SegmentedControl aria-label="List ordering">
             <SegmentedControlItem id="unordered">
-                <UnorderedListIcon />
+                <UnorderedListIcon aria-label="unordered" />
             </SegmentedControlItem>
             <SegmentedControlItem id="ordered">
-                <OrderedListIcon />
+                <OrderedListIcon aria-label="ordered" />
             </SegmentedControlItem>
         </SegmentedControl>
     );
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index 2d2093b3..e38eef5e 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -101,10 +101,11 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
             className={classNames}
             style={mergedStyles}
             slot={slot ?? undefined}
-            selectedKeys={selectedKey != null ? [selectedKey] : undefined}
-            defaultSelectedKeys={defaultSelectedKey != null ? [defaultSelectedKey] : undefined}
             orientation="horizontal"
             onSelectionChange={onChange}
+            selectedKeys={selectedKey != null ? [selectedKey] : undefined}
+            defaultSelectedKeys={defaultSelectedKey != null ? [defaultSelectedKey] : undefined}
+            disallowEmptySelection
             {...otherProps}
         >
             <Provider

From d51f75735b4f4dbfa7b839943f4a4bc0619e309b Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 00:59:31 -0500
Subject: [PATCH 06/17] More fixes and try to fix build

---
 .../components/buttons/SegmentedControl.mdx       |  3 ++-
 .../components/src/SegmentedControl/docs/icon.tsx |  2 +-
 .../src/SegmentedControl/src/SegmentedControl.tsx |  2 +-
 .../src/SegmentedControlItem.module.css           | 12 ++++++++++++
 .../SegmentedControl/src/SegmentedControlItem.tsx | 15 ++++++++++++---
 5 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/apps/docs/content/components/buttons/SegmentedControl.mdx b/apps/docs/content/components/buttons/SegmentedControl.mdx
index ed55fe66..64ec325f 100644
--- a/apps/docs/content/components/buttons/SegmentedControl.mdx
+++ b/apps/docs/content/components/buttons/SegmentedControl.mdx
@@ -28,7 +28,8 @@ Items within a segmented control can contain only icons. An accessible name must
 <Example src="SegmentedControl/docs/iconOnly" />
 
 ### Icon
-A segmented control can contain items with icons, leading or trailing.
+A segmented control can contain items with icons, starting or ending.
+**Non standard** starting icons can be provided to handle special cases. However, think twice before adding start icons, end icons should be your go to.
 
 <Example src="SegmentedControl/docs/icon" />
 
diff --git a/packages/components/src/SegmentedControl/docs/icon.tsx b/packages/components/src/SegmentedControl/docs/icon.tsx
index ee4b46a2..6b14ac61 100644
--- a/packages/components/src/SegmentedControl/docs/icon.tsx
+++ b/packages/components/src/SegmentedControl/docs/icon.tsx
@@ -5,7 +5,7 @@ export default function Example() {
     return (
         <SegmentedControl aria-label="List ordering">
             <SegmentedControlItem id="unordered">
-                <UnorderedListIcon />
+                <UnorderedListIcon slot="start-icon" />
                 <Text>Unordered</Text>
             </SegmentedControlItem>
             <SegmentedControlItem id="ordered">
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index e38eef5e..16c767ad 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -42,7 +42,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
     const state = useContext(ToggleGroupStateContext);
 
     const prevRef = useRef<DOMRect | null>(null);
-    const currentSelectedRef = useRef<HTMLDivElement>(null);
+    const currentSelectedRef = useRef<HTMLDivElement | null>(null);
 
     const { stylingProps, ...ownProps } = useStyledSystem(props);
     const {
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index 943e9fed..1868637c 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -71,3 +71,15 @@
 .hop-SegmentedControlItem--md {
     --hop-SegmentedControlItem-padding: var(--hop-SegmentedControlItem-md-padding);
 }
+
+.hop-SegmentedControlItem__icon {
+    order: 2
+}
+
+.hop-SegmentedControlItem__text {
+    order: 1
+}
+
+.hop-SegmentedControlItem__start-icon {
+    order: 0
+}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index bd283a8c..992d87cf 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -2,7 +2,7 @@ import { IconContext } from "@hopper-ui/icons";
 import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
 import clsx from "clsx";
 import { forwardRef, useContext, useLayoutEffect, type CSSProperties, type ForwardedRef } from "react";
-import { Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
+import { DEFAULT_SLOT, Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
 import { Text, TextContext } from "../../typography/index.ts";
 import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
@@ -107,11 +107,20 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
                         values={[
                             [IconContext, {
                                 size,
-                                zIndex: 1
+                                zIndex: 1,
+                                slots: {
+                                    [DEFAULT_SLOT]: {
+                                        className: styles["hop-SegmentedControlItem__icon"]
+                                    },
+                                    "start-icon": {
+                                        className: styles["hop-SegmentedControlItem__start-icon"]
+                                    }
+                                }
                             }],
                             [TextContext, {
                                 size: "sm",
-                                zIndex: 1
+                                zIndex: 1,
+                                className: styles["hop-SegmentedControlItem__text"]
                             }]
                         ]}
                     >

From bd9aaddbed6728ab4d04ecb536e888896c1ff04e Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 01:14:53 -0500
Subject: [PATCH 07/17] Not sure

---
 .../components/src/SegmentedControl/src/SegmentedControl.tsx    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index 16c767ad..e38eef5e 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -42,7 +42,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
     const state = useContext(ToggleGroupStateContext);
 
     const prevRef = useRef<DOMRect | null>(null);
-    const currentSelectedRef = useRef<HTMLDivElement | null>(null);
+    const currentSelectedRef = useRef<HTMLDivElement>(null);
 
     const { stylingProps, ...ownProps } = useStyledSystem(props);
     const {

From 42f486a741ffe6aac70974c3191625333768548d Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 01:21:03 -0500
Subject: [PATCH 08/17] Try casting

---
 .../components/src/SegmentedControl/src/SegmentedControl.tsx  | 2 +-
 .../src/SegmentedControl/src/SegmentedControlContext.ts       | 2 +-
 .../src/SegmentedControl/src/SegmentedControlItem.tsx         | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index e38eef5e..17df031a 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -80,7 +80,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         }
 
         if (currentSelectedRef.current) {
-            prevRef.current = currentSelectedRef?.current.getBoundingClientRect();
+            prevRef.current = currentSelectedRef.current.getBoundingClientRect();
         }
 
         onSelectionChange?.(firstKey);
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
index 43fdea0a..b5b23e1a 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
@@ -9,7 +9,7 @@ SegmentedControlContext.displayName = "SegmentedControlContext";
 
 interface InternalSegmentedControlContextProps {
     prevRef?: MutableRefObject<DOMRect | null>;
-    currentSelectedRef?: RefObject<HTMLDivElement>;
+    currentSelectedRef?: RefObject<HTMLDivElement | null>;
 }
 
 export const InternalSegmentedControlContext = createContext<InternalSegmentedControlContextProps>({});
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 992d87cf..4dbaea81 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -1,7 +1,7 @@
 import { IconContext } from "@hopper-ui/icons";
 import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
 import clsx from "clsx";
-import { forwardRef, useContext, useLayoutEffect, type CSSProperties, type ForwardedRef } from "react";
+import { forwardRef, useContext, useLayoutEffect, type CSSProperties, type ForwardedRef, type RefObject } from "react";
 import { DEFAULT_SLOT, Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
 import { Text, TextContext } from "../../typography/index.ts";
@@ -102,7 +102,7 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
         >
             {({ isSelected }) => (
                 <>
-                    {isSelected && <div className={styles["hop-SegmentedControlItem__slider"]} ref={currentSelectedRef} />}
+                    {isSelected && <div className={styles["hop-SegmentedControlItem__slider"]} ref={currentSelectedRef as RefObject<HTMLDivElement>} />}
                     <Provider
                         values={[
                             [IconContext, {

From feabf8fa4278984ae5c765f48ca1985bc74dcdd7 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 10:40:38 -0500
Subject: [PATCH 09/17] Fix all comments

---
 .../components/buttons/SegmentedControl.mdx   |  5 ++
 apps/docs/examples/Preview.ts                 |  3 +
 .../src/SegmentedControl/docs/justified.tsx   | 12 +++
 .../src/SegmentedControl.module.css           | 16 ++--
 .../src/SegmentedControlItem.module.css       | 84 +++++++++++++------
 .../src/SegmentedControlItem.tsx              | 10 ++-
 6 files changed, 93 insertions(+), 37 deletions(-)
 create mode 100644 packages/components/src/SegmentedControl/docs/justified.tsx

diff --git a/apps/docs/content/components/buttons/SegmentedControl.mdx b/apps/docs/content/components/buttons/SegmentedControl.mdx
index 64ec325f..675174c3 100644
--- a/apps/docs/content/components/buttons/SegmentedControl.mdx
+++ b/apps/docs/content/components/buttons/SegmentedControl.mdx
@@ -33,6 +33,11 @@ A segmented control can contain items with icons, starting or ending.
 
 <Example src="SegmentedControl/docs/icon" />
 
+### Justified
+A segmented control can have items with similar widths.
+
+<Example src="SegmentedControl/docs/justified" />
+
 ### Controlled
 A segmented control can have a controlled selected value. In this example, it shows how it is possible to select an option.
 
diff --git a/apps/docs/examples/Preview.ts b/apps/docs/examples/Preview.ts
index 84af1001..87a6ebdf 100644
--- a/apps/docs/examples/Preview.ts
+++ b/apps/docs/examples/Preview.ts
@@ -110,6 +110,9 @@ export const Previews: Record<string, Preview> = {
     "SegmentedControl/docs/icon": {
         component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/icon.tsx"))
     },
+    "SegmentedControl/docs/justified": {
+        component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/justified.tsx"))
+    },
     "SegmentedControl/docs/controlled": {
         component: lazy(() => import("@/../../packages/components/src/SegmentedControl/docs/controlled.tsx"))
     },
diff --git a/packages/components/src/SegmentedControl/docs/justified.tsx b/packages/components/src/SegmentedControl/docs/justified.tsx
new file mode 100644
index 00000000..5db4cef6
--- /dev/null
+++ b/packages/components/src/SegmentedControl/docs/justified.tsx
@@ -0,0 +1,12 @@
+import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
+
+export default function Example() {
+    return (
+        <SegmentedControl width="100%" aria-label="Types of frog">
+            <SegmentedControlItem id="common" flex={1}>Common</SegmentedControlItem>
+            <SegmentedControlItem id="american" flex={1}>American Bullfrog</SegmentedControlItem>
+            <SegmentedControlItem id="month" flex={1}>Red-Eyed Tree</SegmentedControlItem>
+            <SegmentedControlItem id="year" flex={1}>Golden Mantella</SegmentedControlItem>
+        </SegmentedControl>
+    );
+}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
index 63ca6130..ee8af51c 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
@@ -5,23 +5,21 @@
     --hop-SegmentedControl-background: var(--hop-neutral-surface);
     --hop-SegmentedControl-border: 0.0625rem solid var(--hop-neutral-border);
     --hop-SegmentedControl-border-radius: var(--hop-shape-rounded-md);
+    --hop-SegmentedControl-display: flex;
+    --hop-SegmentedControl-align-items: center;
+    --hop-SegmentedControl-justify-content: center;
 
-     /* Item background selected animation */
-    --hop-SegmentedControl-item-width: 0rem;
-    --hop-SegmentedControl-item-border-radius: var(--hop-shape-rounded-sm);
-    --hop-SegmentedControl-item-offset: 0rem;
-
-    display: flex;
+    display: var(--hop-SegmentedControl-display);
     gap: var(--hop-SegmentedControl-gap);
-    align-items: center;
-    justify-content: center;
+    align-items: var(--hop-SegmentedControl-align-items);
+    justify-content: var(--hop-SegmentedControl-justify-content);
 
     inline-size: var(--hop-SegmentedControl-witdh);
     padding: var(--hop-SegmentedControl-padding);
 
     background: var(--hop-SegmentedControl-background);
     border: var(--hop-SegmentedControl-border);
-    border-radius: var(--hop-SegmentedControl-border-radius)
+    border-radius: var(--hop-SegmentedControl-border-radius);
 }
 
 
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index 1868637c..f16960aa 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -5,7 +5,11 @@
     --hop-SegmentedControlItem-background: transparent;
     --hop-SegmentedControlItem-border: none;
     --hop-SegmentedControlItem-border-radius: var(--hop-shape-rounded-sm);
-    --hop-SegmentedControlItem-cursor: auto;
+    --hop-SegmentedControlItem-cursor: pointer;
+    --hop-SegmentedControlItem-position: relative;
+    --hop-SegmentedControlItem-display: flex;
+    --hop-SegmentedControlItem-align-items: center;
+    --hop-SegmentedControlItem-justify-content: center;
 
     /* Small */
     --hop-SegmentedControlItem-sm-padding: 0.125rem var(--hop-space-inset-md);
@@ -15,21 +19,51 @@
 
     /* Slider */
     --hop-SegmentedControlItem-slider-background: var(--hop-neutral-surface-selected);
+    --hop-SegmentedControlItem-slider-position: absolute;
+    --hop-SegmentedControlItem-slider-width: 100%;
+    --hop-SegmentedControlItem-slider-height: 100%;
+
+    /* Focused */
+    --hop-SegmentedControlItem-color-focused: var(--hop-neutral-text-hover);
+    --hop-SegmentedControlItem-background-focused: var(--hop-neutral-surface-hover);
+
+    /* Hovered */
+    --hop-SegmentedControlItem-color-hovered: var(--hop-neutral-text-hover);
+    --hop-SegmentedControlItem-background-hovered: var(--hop-neutral-surface-hover);
+
+    /* Pressed */
+    --hop-SegmentedControlItem-color-pressed: var(--hop-neutral-text-press);
+    --hop-SegmentedControlItem-background-pressed: var(--hop-neutral-surface-press);
+
+    /* Selected */
+    --hop-SegmentedControlItem-color-selected: var(--hop-neutral-text-selected);
+    --hop-SegmentedControlItem-background-selected: transparent;
 
-    cursor: var(--hop-SegmentedControlItem-cursor);
+    /* Disabled */
+    --hop-SegmentedControlItem-color-disabled: var(--hop-neutral-text-disabled);
+    --hop-SegmentedControlItem-background-disabled: var(--hop-neutral-surface);
+    --hop-SegmentedControlItem-cursor-disabled: auto;
 
-    position: relative;
+    /* Internal variables */
+    --color: var(--hop-SegmentedControlItem-color);
+    --cursor: var(--hop-SegmentedControlItem-cursor);
+    --background: var(--hop-SegmentedControlItem-background);
+    --padding: var(--hop-SegmentedControlItem-sm-padding);
 
-    display: flex;
+    cursor: var(--cursor);
+
+    position: var(--hop-SegmentedControlItem-position);
+
+    display: var(--hop-SegmentedControlItem-display);
     gap: var(--hop-SegmentedControlItem-gap);
-    align-items: center;
-    justify-content: center;
+    align-items: var(--hop-SegmentedControlItem-align-items);
+    justify-content: var(--hop-SegmentedControlItem-justify-content);
 
-    padding: var(--hop-SegmentedControlItem-padding, var(--hop-SegmentedControlItem-sm-padding));
+    padding: var(--padding);
 
-    color: var(--hop-SegmentedControlItem-color);
+    color: var(--color);
 
-    background: var(--hop-SegmentedControlItem-background)
+    background: var(--background);
 }
 
 .hop-SegmentedControlItem, .hop-SegmentedControlItem__slider {
@@ -38,38 +72,40 @@
 }
 
 .hop-SegmentedControlItem__slider {
-    position: absolute;
-    inline-size: 100%;
-    block-size: 100%;
+    position: var(--hop-SegmentedControlItem-slider-position);
+    inline-size: var(--hop-SegmentedControlItem-slider-width);
+    block-size: var(--hop-SegmentedControlItem-slider-height);
     background: var(--hop-SegmentedControlItem-slider-background);
 }
 
-.hop-SegmentedControlItem:not([data-disabled]) {
-    --hop-SegmentedControlItem-cursor: pointer;
+.hop-SegmentedControlItem[data-hovered] {
+    --color: var(--hop-SegmentedControlItem-color-hovered);
+    --background: var(--hop-SegmentedControlItem-background-hovered);
 }
 
-.hop-SegmentedControlItem[data-hovered], .hop-SegmentedControlItem[data-focused] {
-    --hop-SegmentedControlItem-color: var(--hop-neutral-text-hover);
-    --hop-SegmentedControlItem-background: var(--hop-neutral-surface-hover);
+.hop-SegmentedControlItem[data-focused] {
+    --color: var(--hop-SegmentedControlItem-color-focused);
+    --background: var(--hop-SegmentedControlItem-background-focused);
 }
 
 .hop-SegmentedControlItem[data-pressed] {
-    --hop-SegmentedControlItem-color: var(--hop-neutral-text-press);
-    --hop-SegmentedControlItem-background: var(--hop-neutral-surface-press);
+    --color: var(--hop-SegmentedControlItem-color-pressed);
+    --background: var(--hop-SegmentedControlItem-background-pressed);
 }
 
 .hop-SegmentedControlItem[data-selected] {
-    --hop-SegmentedControlItem-color: var(--hop-neutral-text-selected);
-    --hop-SegmentedControlItem-background: transparent;
+    --color: var(--hop-SegmentedControlItem-color-selected);
+    --background: var(--hop-SegmentedControlItem-background-selected);
 }
 
 .hop-SegmentedControlItem[data-disabled] {
-    --hop-SegmentedControlItem-color: var(--hop-neutral-text-disabled);
-    --hop-SegmentedControlItem-background: var(--hop-neutral-surface);
+    --cursor: var(--hop-SegmentedControlItem-cursor-disabled);
+    --color: var(--hop-SegmentedControlItem-color-disabled);
+    --background: var(--hop-SegmentedControlItem-background-disabled);
 }
 
 .hop-SegmentedControlItem--md {
-    --hop-SegmentedControlItem-padding: var(--hop-SegmentedControlItem-md-padding);
+    --padding: var(--hop-SegmentedControlItem-md-padding);
 }
 
 .hop-SegmentedControlItem__icon {
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 4dbaea81..3b119d79 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -106,14 +106,16 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
                     <Provider
                         values={[
                             [IconContext, {
-                                size,
-                                zIndex: 1,
                                 slots: {
                                     [DEFAULT_SLOT]: {
-                                        className: styles["hop-SegmentedControlItem__icon"]
+                                        className: styles["hop-SegmentedControlItem__icon"],
+                                        size,
+                                        zIndex: 1
                                     },
                                     "start-icon": {
-                                        className: styles["hop-SegmentedControlItem__start-icon"]
+                                        className: styles["hop-SegmentedControlItem__start-icon"],
+                                        size,
+                                        zIndex: 1
                                     }
                                 }
                             }],

From 1afb768febb4ad2559af1f29ac86bd899bb892b8 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 12:53:16 -0500
Subject: [PATCH 10/17] Change to data-focused-visible

---
 .../src/SegmentedControl/src/SegmentedControlItem.module.css    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index f16960aa..c63169bc 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -83,7 +83,7 @@
     --background: var(--hop-SegmentedControlItem-background-hovered);
 }
 
-.hop-SegmentedControlItem[data-focused] {
+.hop-SegmentedControlItem[data-focused-visible] {
     --color: var(--hop-SegmentedControlItem-color-focused);
     --background: var(--hop-SegmentedControlItem-background-focused);
 }

From f2d93389c841db3123db5578a3dd5943f4970c2f Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 13:54:49 -0500
Subject: [PATCH 11/17] Add pressScale and remove z-index like Spectrum

---
 .../src/SegmentedControlItem.tsx              | 22 ++++++++--------
 packages/components/src/utils/src/index.ts    |  1 +
 .../components/src/utils/src/pressScale.ts    | 25 +++++++++++++++++++
 3 files changed, 37 insertions(+), 11 deletions(-)
 create mode 100644 packages/components/src/utils/src/pressScale.ts

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 3b119d79..7d62505f 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -1,11 +1,11 @@
 import { IconContext } from "@hopper-ui/icons";
 import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
 import clsx from "clsx";
-import { forwardRef, useContext, useLayoutEffect, type CSSProperties, type ForwardedRef, type RefObject } from "react";
+import { forwardRef, useContext, useLayoutEffect, useRef, type CSSProperties, type ForwardedRef, type RefObject } from "react";
 import { DEFAULT_SLOT, Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
-import { Text, TextContext } from "../../typography/index.ts";
-import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
+import { TextContext } from "../../typography/index.ts";
+import { cssModule, pressScale, type BaseComponentDOMProps } from "../../utils/index.ts";
 
 import { InternalSegmentedControlContext } from "./SegmentedControlContext.ts";
 import { SegmentedControlItemContext } from "./SegmentedControlItemContext.ts";
@@ -34,6 +34,7 @@ export interface SegmentedControlItemProps extends Omit<StyledComponentProps<Bas
 
 const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRef<HTMLButtonElement>) => {
     [props, ref] = useContextProps(props, ref, SegmentedControlItemContext);
+    const divRef = useRef<HTMLDivElement>(null);
     const { prevRef, currentSelectedRef } = useContext(InternalSegmentedControlContext);
     const state = useContext(ToggleGroupStateContext);
     const itemSelected = state?.selectedKeys.has(props.id);
@@ -100,33 +101,32 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
             style={mergedStyles}
             slot={slot ?? undefined}
         >
-            {({ isSelected }) => (
+            {({ isSelected, isDisabled, isPressed }) => (
                 <>
-                    {isSelected && <div className={styles["hop-SegmentedControlItem__slider"]} ref={currentSelectedRef as RefObject<HTMLDivElement>} />}
+                    {isSelected && !isDisabled && <div className={styles["hop-SegmentedControlItem__slider"]} ref={currentSelectedRef as RefObject<HTMLDivElement>} />}
                     <Provider
                         values={[
                             [IconContext, {
                                 slots: {
                                     [DEFAULT_SLOT]: {
                                         className: styles["hop-SegmentedControlItem__icon"],
-                                        size,
-                                        zIndex: 1
+                                        size
                                     },
                                     "start-icon": {
                                         className: styles["hop-SegmentedControlItem__start-icon"],
-                                        size,
-                                        zIndex: 1
+                                        size
                                     }
                                 }
                             }],
                             [TextContext, {
                                 size: "sm",
-                                zIndex: 1,
                                 className: styles["hop-SegmentedControlItem__text"]
                             }]
                         ]}
                     >
-                        {typeof children === "string" ? <Text>{children}</Text> : children}
+                        <div ref={divRef} style={pressScale(divRef)({ isPressed })} >
+                            {children}
+                        </div>
                     </Provider>
                 </>
             )}
diff --git a/packages/components/src/utils/src/index.ts b/packages/components/src/utils/src/index.ts
index 11540888..388c2a25 100644
--- a/packages/components/src/utils/src/index.ts
+++ b/packages/components/src/utils/src/index.ts
@@ -4,6 +4,7 @@ export * from "./composeClassnameRenderProps.ts";
 export * from "./cssModule.ts";
 export * from "./EnsureTextWrapper.tsx";
 export * from "./isTextOnlyChildren.ts";
+export * from "./pressScale.ts";
 export * from "./sizeAdapter.ts";
 export * from "./SlotProvider.ts";
 export * from "./types.ts";
diff --git a/packages/components/src/utils/src/pressScale.ts b/packages/components/src/utils/src/pressScale.ts
new file mode 100644
index 00000000..b9d843e9
--- /dev/null
+++ b/packages/components/src/utils/src/pressScale.ts
@@ -0,0 +1,25 @@
+/*
+ * Taken from: https://github.com/adobe/react-spectrum/blob/main/packages/%40react-spectrum/s2/src/pressScale.ts
+ */
+
+import type { CSSProperties, RefObject } from "react";
+import { composeRenderProps } from "react-aria-components";
+
+export function pressScale<R extends { isPressed: boolean }>(ref: RefObject<HTMLElement | null>, _style?: CSSProperties | ((renderProps: R) => CSSProperties)) {
+    return composeRenderProps(_style, (style, renderProps: R) => {
+        if (renderProps.isPressed && ref.current) {
+            const { width = 0, height = 0 } = ref.current.getBoundingClientRect() ?? {};
+
+            return {
+                ...style,
+                willChange: `${style?.willChange ?? ""} transform`,
+                transform: `${style?.transform ?? ""} perspective(${Math.max(height, width / 3, 24)}px) translate3d(0, 0, -2px)`
+            };
+        } else {
+            return {
+                ...style,
+                willChange: `${style?.willChange ?? ""} transform`
+            };
+        }
+    });
+}

From 7c8293e4cce058b72ba59a65152a5863bca64920 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 15:05:21 -0500
Subject: [PATCH 12/17] Remove pressScale

---
 .../src/SegmentedControlItem.module.css       | 19 ++++++++++++++
 .../src/SegmentedControlItem.tsx              |  6 ++---
 packages/components/src/utils/src/index.ts    |  1 -
 .../components/src/utils/src/pressScale.ts    | 25 -------------------
 4 files changed, 22 insertions(+), 29 deletions(-)
 delete mode 100644 packages/components/src/utils/src/pressScale.ts

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index c63169bc..30d79059 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -10,6 +10,10 @@
     --hop-SegmentedControlItem-display: flex;
     --hop-SegmentedControlItem-align-items: center;
     --hop-SegmentedControlItem-justify-content: center;
+    --hop-SegmentedControlItem-transition: color 0.3s;
+    --hop-SegmentedControlItem-outline: none;
+    --hop-SegmentedControlItem-outline-offset: var(--hop-space-20);
+    --hop-SegmentedControlItem-focus-ring-color: var(--hop-primary-border-focus);
 
     /* Small */
     --hop-SegmentedControlItem-sm-padding: 0.125rem var(--hop-space-inset-md);
@@ -49,6 +53,7 @@
     --cursor: var(--hop-SegmentedControlItem-cursor);
     --background: var(--hop-SegmentedControlItem-background);
     --padding: var(--hop-SegmentedControlItem-sm-padding);
+    --outline: var(--hop-SegmentedControlItem-outline);
 
     cursor: var(--cursor);
 
@@ -64,6 +69,10 @@
     color: var(--color);
 
     background: var(--background);
+    outline: var(--outline);
+    outline-offset: var(--hop-SegmentedControlItem-outline-offset);
+
+    transition: var(--hop-SegmentedControlItem-transition);
 }
 
 .hop-SegmentedControlItem, .hop-SegmentedControlItem__slider {
@@ -78,6 +87,15 @@
     background: var(--hop-SegmentedControlItem-slider-background);
 }
 
+.hop-SegmentedControlItem__wrapper {
+    will-change: transform;
+
+    display: var(--hop-SegmentedControlItem-display);
+    gap: var(--hop-SegmentedControlItem-gap);
+    align-items: var(--hop-SegmentedControlItem-align-items);
+    justify-content: var(--hop-SegmentedControlItem-justify-content);
+}
+
 .hop-SegmentedControlItem[data-hovered] {
     --color: var(--hop-SegmentedControlItem-color-hovered);
     --background: var(--hop-SegmentedControlItem-background-hovered);
@@ -86,6 +104,7 @@
 .hop-SegmentedControlItem[data-focused-visible] {
     --color: var(--hop-SegmentedControlItem-color-focused);
     --background: var(--hop-SegmentedControlItem-background-focused);
+    --outline: var(--hop-SegmentedControlItem-outline-offset) solid var(--hop-SegmentedControlItem-focus-ring-color);
 }
 
 .hop-SegmentedControlItem[data-pressed] {
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 7d62505f..5877e7a6 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -5,7 +5,7 @@ import { forwardRef, useContext, useLayoutEffect, useRef, type CSSProperties, ty
 import { DEFAULT_SLOT, Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
 import { TextContext } from "../../typography/index.ts";
-import { cssModule, pressScale, type BaseComponentDOMProps } from "../../utils/index.ts";
+import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
 
 import { InternalSegmentedControlContext } from "./SegmentedControlContext.ts";
 import { SegmentedControlItemContext } from "./SegmentedControlItemContext.ts";
@@ -101,7 +101,7 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
             style={mergedStyles}
             slot={slot ?? undefined}
         >
-            {({ isSelected, isDisabled, isPressed }) => (
+            {({ isSelected, isDisabled }) => (
                 <>
                     {isSelected && !isDisabled && <div className={styles["hop-SegmentedControlItem__slider"]} ref={currentSelectedRef as RefObject<HTMLDivElement>} />}
                     <Provider
@@ -124,7 +124,7 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
                             }]
                         ]}
                     >
-                        <div ref={divRef} style={pressScale(divRef)({ isPressed })} >
+                        <div ref={divRef} className={styles["hop-SegmentedControlItem__wrapper"]} >
                             {children}
                         </div>
                     </Provider>
diff --git a/packages/components/src/utils/src/index.ts b/packages/components/src/utils/src/index.ts
index 388c2a25..11540888 100644
--- a/packages/components/src/utils/src/index.ts
+++ b/packages/components/src/utils/src/index.ts
@@ -4,7 +4,6 @@ export * from "./composeClassnameRenderProps.ts";
 export * from "./cssModule.ts";
 export * from "./EnsureTextWrapper.tsx";
 export * from "./isTextOnlyChildren.ts";
-export * from "./pressScale.ts";
 export * from "./sizeAdapter.ts";
 export * from "./SlotProvider.ts";
 export * from "./types.ts";
diff --git a/packages/components/src/utils/src/pressScale.ts b/packages/components/src/utils/src/pressScale.ts
deleted file mode 100644
index b9d843e9..00000000
--- a/packages/components/src/utils/src/pressScale.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Taken from: https://github.com/adobe/react-spectrum/blob/main/packages/%40react-spectrum/s2/src/pressScale.ts
- */
-
-import type { CSSProperties, RefObject } from "react";
-import { composeRenderProps } from "react-aria-components";
-
-export function pressScale<R extends { isPressed: boolean }>(ref: RefObject<HTMLElement | null>, _style?: CSSProperties | ((renderProps: R) => CSSProperties)) {
-    return composeRenderProps(_style, (style, renderProps: R) => {
-        if (renderProps.isPressed && ref.current) {
-            const { width = 0, height = 0 } = ref.current.getBoundingClientRect() ?? {};
-
-            return {
-                ...style,
-                willChange: `${style?.willChange ?? ""} transform`,
-                transform: `${style?.transform ?? ""} perspective(${Math.max(height, width / 3, 24)}px) translate3d(0, 0, -2px)`
-            };
-        } else {
-            return {
-                ...style,
-                willChange: `${style?.willChange ?? ""} transform`
-            };
-        }
-    });
-}

From 69db9a24e3f7c3bb19e3d0c2242c589ed28431a0 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 16:36:09 -0500
Subject: [PATCH 13/17] Add isJustified

---
 .../src/SegmentedControl/docs/justified.tsx    | 10 +++++-----
 .../src/SegmentedControl.module.css            | 18 ++++++++++++------
 .../SegmentedControl/src/SegmentedControl.tsx  | 12 +++++++++---
 .../src/SegmentedControlContext.ts             |  1 +
 .../src/SegmentedControlItem.module.css        | 11 ++++++++++-
 .../src/SegmentedControlItem.tsx               |  5 +++--
 .../chromatic/SegmentedControl.stories.tsx     | 14 ++++++++++++++
 7 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/packages/components/src/SegmentedControl/docs/justified.tsx b/packages/components/src/SegmentedControl/docs/justified.tsx
index 5db4cef6..572d8b30 100644
--- a/packages/components/src/SegmentedControl/docs/justified.tsx
+++ b/packages/components/src/SegmentedControl/docs/justified.tsx
@@ -2,11 +2,11 @@ import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
 
 export default function Example() {
     return (
-        <SegmentedControl width="100%" aria-label="Types of frog">
-            <SegmentedControlItem id="common" flex={1}>Common</SegmentedControlItem>
-            <SegmentedControlItem id="american" flex={1}>American Bullfrog</SegmentedControlItem>
-            <SegmentedControlItem id="month" flex={1}>Red-Eyed Tree</SegmentedControlItem>
-            <SegmentedControlItem id="year" flex={1}>Golden Mantella</SegmentedControlItem>
+        <SegmentedControl isJustified aria-label="Types of frog">
+            <SegmentedControlItem id="american">American Bullfrog</SegmentedControlItem>
+            <SegmentedControlItem id="month">Red-Eyed Tree</SegmentedControlItem>
+            <SegmentedControlItem id="year">Golden Mantella</SegmentedControlItem>
+            <SegmentedControlItem id="common">Common</SegmentedControlItem>
         </SegmentedControl>
     );
 }
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
index ee8af51c..7465b091 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
@@ -1,20 +1,22 @@
 .hop-SegmentedControl {
     --hop-SegmentedControl-gap: var(--hop-space-inline-xs);
     --hop-SegmentedControl-padding: var(--hop-space-inset-xs);
-    --hop-SegmentedControl-witdh: fit-content;
+    --hop-SegmentedControl-width: fit-content;
     --hop-SegmentedControl-background: var(--hop-neutral-surface);
     --hop-SegmentedControl-border: 0.0625rem solid var(--hop-neutral-border);
     --hop-SegmentedControl-border-radius: var(--hop-shape-rounded-md);
     --hop-SegmentedControl-display: flex;
-    --hop-SegmentedControl-align-items: center;
-    --hop-SegmentedControl-justify-content: center;
+
+    /* Justified */
+    --hop-SegmentedControl-width-justified: 100%;
+
+    /* Internal variables */
+    --width: var(--hop-SegmentedControl-width);
 
     display: var(--hop-SegmentedControl-display);
     gap: var(--hop-SegmentedControl-gap);
-    align-items: var(--hop-SegmentedControl-align-items);
-    justify-content: var(--hop-SegmentedControl-justify-content);
 
-    inline-size: var(--hop-SegmentedControl-witdh);
+    inline-size: var(--width);
     padding: var(--hop-SegmentedControl-padding);
 
     background: var(--hop-SegmentedControl-background);
@@ -22,4 +24,8 @@
     border-radius: var(--hop-SegmentedControl-border-radius);
 }
 
+.hop-SegmentedControl--justified {
+    --width: var(--hop-SegmentedControl-width-justified);
+}
+
 
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index 17df031a..2ace7735 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -18,6 +18,10 @@ export interface SegmentedControlProps extends StyledComponentProps<BaseComponen
     *  Whether the segmented control is disabled.
     */
     isDisabled?: boolean;
+    /**
+     * Whether the items should divide the container width equally.
+     */
+    isJustified?: boolean;
     /**
      * The id of the currently selected item (controlled).
      */
@@ -54,6 +58,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         selectedKey,
         onSelectionChange,
         size,
+        isJustified,
         ...otherProps
     } = ownProps;
 
@@ -61,7 +66,8 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         GlobalSegmentedControlCssSelector,
         cssModule(
             styles,
-            "hop-SegmentedControl"
+            "hop-SegmentedControl",
+            isJustified && "justified"
         ),
         stylingProps.className,
         className
@@ -111,7 +117,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
             <Provider
                 values={[
                     [SegmentedControlItemContext, { size, isDisabled: otherProps.isDisabled }],
-                    [InternalSegmentedControlContext, { prevRef, currentSelectedRef }]
+                    [InternalSegmentedControlContext, { prevRef, currentSelectedRef, isJustified }]
                 ]}
             >
                 {children}
@@ -123,7 +129,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
 /**
  * Segmented control displays multiple contextually or conceptually related action or option stacked in a horizontal row.
  *
- * [View Documentation](TODO)
+ * [View Documentation](https://hopper.workleap.design/components/SegmentedControl)
  */
 const _SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>(SegmentedControl);
 _SegmentedControl.displayName = "SegmentedControl";
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
index b5b23e1a..ba2f1ad6 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlContext.ts
@@ -10,6 +10,7 @@ SegmentedControlContext.displayName = "SegmentedControlContext";
 interface InternalSegmentedControlContextProps {
     prevRef?: MutableRefObject<DOMRect | null>;
     currentSelectedRef?: RefObject<HTMLDivElement | null>;
+    isJustified?: boolean;
 }
 
 export const InternalSegmentedControlContext = createContext<InternalSegmentedControlContextProps>({});
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index 30d79059..49b2650a 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -14,6 +14,8 @@
     --hop-SegmentedControlItem-outline: none;
     --hop-SegmentedControlItem-outline-offset: var(--hop-space-20);
     --hop-SegmentedControlItem-focus-ring-color: var(--hop-primary-border-focus);
+    --hop-SegmentedControlItem-user-select: none;
+    --hop-SegmentedControlItem-whitespace: nowrap;
 
     /* Small */
     --hop-SegmentedControlItem-sm-padding: 0.125rem var(--hop-space-inset-md);
@@ -56,6 +58,7 @@
     --outline: var(--hop-SegmentedControlItem-outline);
 
     cursor: var(--cursor);
+    user-select: var(--hop-SegmentedControlItem-user-select);
 
     position: var(--hop-SegmentedControlItem-position);
 
@@ -67,6 +70,7 @@
     padding: var(--padding);
 
     color: var(--color);
+    white-space: var(--hop-SegmentedControlItem-whitespace);
 
     background: var(--background);
     outline: var(--outline);
@@ -101,7 +105,7 @@
     --background: var(--hop-SegmentedControlItem-background-hovered);
 }
 
-.hop-SegmentedControlItem[data-focused-visible] {
+.hop-SegmentedControlItem[data-focus-visible] {
     --color: var(--hop-SegmentedControlItem-color-focused);
     --background: var(--hop-SegmentedControlItem-background-focused);
     --outline: var(--hop-SegmentedControlItem-outline-offset) solid var(--hop-SegmentedControlItem-focus-ring-color);
@@ -138,3 +142,8 @@
 .hop-SegmentedControlItem__start-icon {
     order: 0
 }
+
+.hop-SegmentedControlItem--justified {
+    flex-basis: 0%;
+    flex-grow: 1;
+}
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 5877e7a6..320bf69a 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -35,7 +35,7 @@ export interface SegmentedControlItemProps extends Omit<StyledComponentProps<Bas
 const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRef<HTMLButtonElement>) => {
     [props, ref] = useContextProps(props, ref, SegmentedControlItemContext);
     const divRef = useRef<HTMLDivElement>(null);
-    const { prevRef, currentSelectedRef } = useContext(InternalSegmentedControlContext);
+    const { prevRef, currentSelectedRef, isJustified } = useContext(InternalSegmentedControlContext);
     const state = useContext(ToggleGroupStateContext);
     const itemSelected = state?.selectedKeys.has(props.id);
 
@@ -54,7 +54,8 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
         cssModule(
             styles,
             "hop-SegmentedControlItem",
-            size
+            size,
+            isJustified && "justified"
         ),
         stylingProps.className,
         className
diff --git a/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx b/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
index 950eeab9..13911f61 100644
--- a/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
+++ b/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
@@ -132,6 +132,20 @@ export const OnlyIcons = {
     }
 } satisfies Story;
 
+export const Justified = {
+    render: props => (
+        <SegmentedControl isJustified defaultSelectedKey="american" {...props} >
+            <SegmentedControlItem id="common">Common</SegmentedControlItem>
+            <SegmentedControlItem id="american">American Bullfrog</SegmentedControlItem>
+            <SegmentedControlItem id="month">Red-Eyed Tree</SegmentedControlItem>
+            <SegmentedControlItem id="year">Golden Mantella</SegmentedControlItem>
+        </SegmentedControl>
+    ),
+    args: {
+        "aria-label": "List organization"
+    }
+} satisfies Story;
+
 export const Disabled = {
     render: props => (
         <Stack>

From 5495ec218f99df238368360c524de8b6d700796f Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 16:44:44 -0500
Subject: [PATCH 14/17] Fix justified

---
 .../src/SegmentedControl/docs/justified.tsx          | 10 +++++-----
 .../SegmentedControl/src/SegmentedControl.module.css | 12 +-----------
 .../src/SegmentedControl/src/SegmentedControl.tsx    |  3 +--
 .../src/SegmentedControlItem.module.css              |  3 +--
 .../tests/chromatic/SegmentedControl.stories.tsx     | 10 +++++-----
 5 files changed, 13 insertions(+), 25 deletions(-)

diff --git a/packages/components/src/SegmentedControl/docs/justified.tsx b/packages/components/src/SegmentedControl/docs/justified.tsx
index 572d8b30..cd082256 100644
--- a/packages/components/src/SegmentedControl/docs/justified.tsx
+++ b/packages/components/src/SegmentedControl/docs/justified.tsx
@@ -2,11 +2,11 @@ import { SegmentedControl, SegmentedControlItem } from "@hopper-ui/components";
 
 export default function Example() {
     return (
-        <SegmentedControl isJustified aria-label="Types of frog">
-            <SegmentedControlItem id="american">American Bullfrog</SegmentedControlItem>
-            <SegmentedControlItem id="month">Red-Eyed Tree</SegmentedControlItem>
-            <SegmentedControlItem id="year">Golden Mantella</SegmentedControlItem>
-            <SegmentedControlItem id="common">Common</SegmentedControlItem>
+        <SegmentedControl UNSAFE_width="400px" isJustified aria-label="Time granularity">
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
         </SegmentedControl>
     );
 }
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
index 7465b091..cd7d71ad 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.module.css
@@ -7,16 +7,10 @@
     --hop-SegmentedControl-border-radius: var(--hop-shape-rounded-md);
     --hop-SegmentedControl-display: flex;
 
-    /* Justified */
-    --hop-SegmentedControl-width-justified: 100%;
-
-    /* Internal variables */
-    --width: var(--hop-SegmentedControl-width);
-
     display: var(--hop-SegmentedControl-display);
     gap: var(--hop-SegmentedControl-gap);
 
-    inline-size: var(--width);
+    inline-size: var(--hop-SegmentedControl-width);
     padding: var(--hop-SegmentedControl-padding);
 
     background: var(--hop-SegmentedControl-background);
@@ -24,8 +18,4 @@
     border-radius: var(--hop-SegmentedControl-border-radius);
 }
 
-.hop-SegmentedControl--justified {
-    --width: var(--hop-SegmentedControl-width-justified);
-}
-
 
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
index 2ace7735..4f79b17d 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControl.tsx
@@ -66,8 +66,7 @@ const SegmentedControl = (props: SegmentedControlProps, ref: ForwardedRef<HTMLDi
         GlobalSegmentedControlCssSelector,
         cssModule(
             styles,
-            "hop-SegmentedControl",
-            isJustified && "justified"
+            "hop-SegmentedControl"
         ),
         stylingProps.className,
         className
diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
index 49b2650a..8ba5fd81 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.module.css
@@ -144,6 +144,5 @@
 }
 
 .hop-SegmentedControlItem--justified {
-    flex-basis: 0%;
-    flex-grow: 1;
+    flex: 1;
 }
diff --git a/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx b/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
index 13911f61..d3228a6a 100644
--- a/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
+++ b/packages/components/src/SegmentedControl/tests/chromatic/SegmentedControl.stories.tsx
@@ -134,11 +134,11 @@ export const OnlyIcons = {
 
 export const Justified = {
     render: props => (
-        <SegmentedControl isJustified defaultSelectedKey="american" {...props} >
-            <SegmentedControlItem id="common">Common</SegmentedControlItem>
-            <SegmentedControlItem id="american">American Bullfrog</SegmentedControlItem>
-            <SegmentedControlItem id="month">Red-Eyed Tree</SegmentedControlItem>
-            <SegmentedControlItem id="year">Golden Mantella</SegmentedControlItem>
+        <SegmentedControl UNSAFE_width="400px" isJustified defaultSelectedKey="day" {...props} >
+            <SegmentedControlItem id="day">Day</SegmentedControlItem>
+            <SegmentedControlItem id="week">Week</SegmentedControlItem>
+            <SegmentedControlItem id="month">Month</SegmentedControlItem>
+            <SegmentedControlItem id="year">Year</SegmentedControlItem>
         </SegmentedControl>
     ),
     args: {

From 5d99d234d23e4bff002958c9cd334300ad929bfc Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 16:56:38 -0500
Subject: [PATCH 15/17] Fix Text size

---
 .../src/SegmentedControl/src/SegmentedControlItem.tsx         | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 320bf69a..b41fe13f 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -4,7 +4,7 @@ import clsx from "clsx";
 import { forwardRef, useContext, useLayoutEffect, useRef, type CSSProperties, type ForwardedRef, type RefObject } from "react";
 import { DEFAULT_SLOT, Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
-import { TextContext } from "../../typography/index.ts";
+import { Text, TextContext } from "../../typography/index.ts";
 import { cssModule, type BaseComponentDOMProps } from "../../utils/index.ts";
 
 import { InternalSegmentedControlContext } from "./SegmentedControlContext.ts";
@@ -126,7 +126,7 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
                         ]}
                     >
                         <div ref={divRef} className={styles["hop-SegmentedControlItem__wrapper"]} >
-                            {children}
+                            {typeof children === "string" ? <Text>{children}</Text> : children}
                         </div>
                     </Provider>
                 </>

From 2be171aa2a40b66c20946e236c4597195ec4ebd5 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 16:58:01 -0500
Subject: [PATCH 16/17] Remove unused divRef

---
 .../src/SegmentedControl/src/SegmentedControlItem.tsx        | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index b41fe13f..520d9f9c 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -1,7 +1,7 @@
 import { IconContext } from "@hopper-ui/icons";
 import { useStyledSystem, type ResponsiveProp, type StyledComponentProps } from "@hopper-ui/styled-system";
 import clsx from "clsx";
-import { forwardRef, useContext, useLayoutEffect, useRef, type CSSProperties, type ForwardedRef, type RefObject } from "react";
+import { forwardRef, useContext, useLayoutEffect, type CSSProperties, type ForwardedRef, type RefObject } from "react";
 import { DEFAULT_SLOT, Provider, ToggleButton, ToggleGroupStateContext, useContextProps, type Key } from "react-aria-components";
 
 import { Text, TextContext } from "../../typography/index.ts";
@@ -34,7 +34,6 @@ export interface SegmentedControlItemProps extends Omit<StyledComponentProps<Bas
 
 const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRef<HTMLButtonElement>) => {
     [props, ref] = useContextProps(props, ref, SegmentedControlItemContext);
-    const divRef = useRef<HTMLDivElement>(null);
     const { prevRef, currentSelectedRef, isJustified } = useContext(InternalSegmentedControlContext);
     const state = useContext(ToggleGroupStateContext);
     const itemSelected = state?.selectedKeys.has(props.id);
@@ -125,7 +124,7 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
                             }]
                         ]}
                     >
-                        <div ref={divRef} className={styles["hop-SegmentedControlItem__wrapper"]} >
+                        <div className={styles["hop-SegmentedControlItem__wrapper"]} >
                             {typeof children === "string" ? <Text>{children}</Text> : children}
                         </div>
                     </Provider>

From fdf3904d8558cf1134e8dc198e0b13ff52a2cb40 Mon Sep 17 00:00:00 2001
From: Victor Trinh <victor.trinh@gsoft.com>
Date: Fri, 10 Jan 2025 16:58:57 -0500
Subject: [PATCH 17/17] Add documentation link for SegmentedControlItem

---
 .../src/SegmentedControl/src/SegmentedControlItem.tsx           | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
index 520d9f9c..1fbe5596 100644
--- a/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
+++ b/packages/components/src/SegmentedControl/src/SegmentedControlItem.tsx
@@ -138,7 +138,7 @@ const SegmentedControlItem = (props: SegmentedControlItemProps, ref: ForwardedRe
 /**
  * A SegmentedControlItem represents an option within a SegmentedControl.
  *
- * [View Documentation](TODO)
+ * [View Documentation](https://hopper.workleap.design/components/SegmentedControl)
  */
 const _SegmentedControlItem = forwardRef<HTMLButtonElement, SegmentedControlItemProps>(SegmentedControlItem);
 _SegmentedControlItem.displayName = "SegmentedControlItem";