Skip to content

Commit

Permalink
feat: add segment group
Browse files Browse the repository at this point in the history
  • Loading branch information
segunadebayo committed Jun 10, 2024
1 parent 8532d7d commit 09bea21
Show file tree
Hide file tree
Showing 8 changed files with 311 additions and 0 deletions.
77 changes: 77 additions & 0 deletions packages/react/__stories__/segment-group.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Box, For, SegmentGroup, useSlotRecipe } from "../src"
import { PlaygroundTable } from "./shared/playground-table"

export default {
title: "Components / Segment Group",
decorators: [
(Story: any) => (
<Box padding="40px">
<Story />
</Box>
),
],
}

export const Basic = () => {
return (
<SegmentGroup.Root defaultValue="react">
<SegmentGroup.Indicator />
<SegmentGroup.Item value="react">
<SegmentGroup.ItemText>React</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>

<SegmentGroup.Item value="solid">
<SegmentGroup.ItemText>Solid.js</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>

<SegmentGroup.Item value="vue">
<SegmentGroup.ItemText>Vue</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.Root>
)
}

export const Sizes = () => {
const recipe = useSlotRecipe("SegmentGroup")
return (
<PlaygroundTable>
<thead>
<tr>
<td />
<For each={recipe.variantMap.size}>{(v) => <td>{v}</td>}</For>
</tr>
</thead>
<tbody>
<tr>
<td />
<For each={recipe.variantMap.size}>
{(v) => (
<td key={v}>
<SegmentGroup.Root defaultValue="react" size={v}>
<SegmentGroup.Indicator />
<SegmentGroup.Item value="react">
<SegmentGroup.ItemText>React</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>

<SegmentGroup.Item value="solid">
<SegmentGroup.ItemText>Solid.js</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>

<SegmentGroup.Item value="vue">
<SegmentGroup.ItemText>Vue</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.Root>
</td>
)}
</For>
</tr>
</tbody>
</PlaygroundTable>
)
}
1 change: 1 addition & 0 deletions packages/react/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export * from "./portal"
export * from "./progress"
export * from "./progress-circular"
export * from "./radio-group"
export * from "./segment-group"
export * from "./select"
export * from "./separator"
export * from "./show"
Expand Down
25 changes: 25 additions & 0 deletions packages/react/src/components/segment-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export {
SegmentGroupRoot,
SegmentGroupItem,
SegmentGroupItemText,
SegmentGroupIndicator,
} from "./segment-group"

export type {
SegmentGroupRootProps,
SegmentGroupItemProps,
SegmentGroupItemTextProps,
SegmentGroupIndicatorProps,
} from "./segment-group"

export {
SegmentGroupItemHiddenInput,
SegmentGroupItemContext,
useSegmentGroupContext,
} from "@ark-ui/react/segment-group"
export type {
SegmentGroupItemHiddenInputProps,
SegmentGroupValueChangeDetails,
} from "@ark-ui/react/segment-group"

export * as SegmentGroup from "./namespace"
22 changes: 22 additions & 0 deletions packages/react/src/components/segment-group/namespace.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export {
SegmentGroupRoot as Root,
SegmentGroupItem as Item,
SegmentGroupItemText as ItemText,
SegmentGroupIndicator as Indicator,
} from "./segment-group"

export type {
SegmentGroupRootProps as RootProps,
SegmentGroupItemProps as ItemProps,
SegmentGroupItemTextProps as ItemTextProps,
SegmentGroupIndicatorProps as IndicatorProps,
} from "./segment-group"

export {
SegmentGroupItemHiddenInput as ItemHiddenInput,
SegmentGroupItemContext as ItemContext,
} from "@ark-ui/react/segment-group"
export type {
SegmentGroupItemHiddenInputProps as ItemHiddenInputProps,
SegmentGroupValueChangeDetails as ValueChangeDetails,
} from "@ark-ui/react/segment-group"
61 changes: 61 additions & 0 deletions packages/react/src/components/segment-group/segment-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use client"

import { SegmentGroup as ArkSegmentGroup } from "@ark-ui/react/segment-group"
import {
type HTMLChakraProps,
type SlotRecipeProps,
type UnstyledProp,
createStyleContext,
} from "../../styled-system"

////////////////////////////////////////////////////////////////////////////////////

const {
withProvider,
withContext,
useStyles: useSegmentGroupStyles,
} = createStyleContext("SegmentGroup")

export { useSegmentGroupStyles }

////////////////////////////////////////////////////////////////////////////////////

export interface SegmentGroupRootProps
extends HTMLChakraProps<"div", ArkSegmentGroup.RootProps>,
SlotRecipeProps<"SegmentGroup">,
UnstyledProp {}

export const SegmentGroupRoot = withProvider<
HTMLDivElement,
SegmentGroupRootProps
>(ArkSegmentGroup.Root, "root", { forwardAsChild: true })

////////////////////////////////////////////////////////////////////////////////////

export interface SegmentGroupItemProps
extends HTMLChakraProps<"label", ArkSegmentGroup.ItemProps> {}

export const SegmentGroupItem = withContext<
HTMLLabelElement,
SegmentGroupItemProps
>(ArkSegmentGroup.Item, "item", { forwardAsChild: true })

////////////////////////////////////////////////////////////////////////////////////

export interface SegmentGroupItemTextProps
extends HTMLChakraProps<"span", ArkSegmentGroup.ItemTextProps> {}

export const SegmentGroupItemText = withContext<
HTMLSpanElement,
SegmentGroupItemTextProps
>(ArkSegmentGroup.ItemText, "itemText", { forwardAsChild: true })

////////////////////////////////////////////////////////////////////////////////////

export interface SegmentGroupIndicatorProps
extends HTMLChakraProps<"div", ArkSegmentGroup.IndicatorProps> {}

export const SegmentGroupIndicator = withContext<
HTMLSpanElement,
SegmentGroupIndicatorProps
>(ArkSegmentGroup.Indicator, "indicator", { forwardAsChild: true })
16 changes: 16 additions & 0 deletions packages/react/src/styled-system/generated/recipes.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,20 @@ export interface CheckboxCardVariantProps {
variant?: "plain" | "subtle"
}

// SegmentGroup

export type SegmentGroupSlot =
| "root"
| "label"
| "item"
| "itemText"
| "itemControl"
| "indicator"

export interface SegmentGroupVariantProps {
size?: "sm" | "md" | "lg"
}

export interface ConfigSlotRecipes {
Accordion: SystemSlotRecipeFn<AccordionSlot, AccordionVariantProps>
Alert: SystemSlotRecipeFn<AlertSlot, AlertVariantProps>
Expand Down Expand Up @@ -658,6 +672,7 @@ export interface ConfigSlotRecipes {
PinInput: SystemSlotRecipeFn<PinInputSlot, PinInputVariantProps>
EmptyState: SystemSlotRecipeFn<EmptyStateSlot, EmptyStateVariantProps>
CheckboxCard: SystemSlotRecipeFn<CheckboxCardSlot, CheckboxCardVariantProps>
SegmentGroup: SystemSlotRecipeFn<SegmentGroupSlot, SegmentGroupVariantProps>
}

export interface ConfigRecipeSlots {
Expand Down Expand Up @@ -695,6 +710,7 @@ export interface ConfigRecipeSlots {
PinInput: PinInputSlot
EmptyState: EmptyStateSlot
CheckboxCard: CheckboxCardSlot
SegmentGroup: SegmentGroupSlot
}

export type SlotRecipeRecord<T, K> = T extends keyof ConfigRecipeSlots
Expand Down
107 changes: 107 additions & 0 deletions packages/react/src/theme/recipes/segment-group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { anatomy } from "@ark-ui/anatomy/segment-group"
import { defineSlotRecipe } from "../../styled-system"

export const segmentGroupSlotRecipe = defineSlotRecipe({
slots: anatomy.keys(),
base: {
root: {
display: "inline-flex",
boxShadow: "inset",
minW: "max-content",
textAlign: "center",
position: "relative",
isolation: "isolate",
bg: "bg.muted",
},

item: {
display: "flex",
alignItems: "center",
userSelect: "none",
fontSize: "sm",
position: "relative",
color: "fg",
_disabled: {
color: "fg.subtle/60!",
},
_before: {
content: '""',
position: "absolute",
top: 0,
bottom: 0,
insetInlineStart: 0,
bg: "border.subtle",
width: "1px",
marginBlock: "3px",
transition: "opacity 0.2s",
},
"& + &[data-state=checked], &[data-state=checked] + &, &:first-of-type": {
_before: {
opacity: "0",
},
},
},

indicator: {
shadow: "sm",
pos: "absolute",
bg: "bg",
width: "var(--width)",
height: "var(--height)",
top: "var(--top)",
left: "var(--left)",
zIndex: -1,
},
},

variants: {
size: {
sm: {
root: {
rounded: "sm",
height: "6",
},
item: {
fontSize: "xs",
px: "3",
gap: "1",
},
indicator: {
rounded: "xs",
},
},
md: {
root: {
rounded: "md",
height: "8",
},
item: {
fontSize: "sm",
px: "4",
gap: "2",
},
indicator: {
rounded: "sm",
},
},
lg: {
root: {
rounded: "lg",
height: "10",
},
item: {
fontSize: "md",
px: "5",
gap: "3",
},
indicator: {
rounded: "md",
},
},
},
},

defaultVariants: {
size: "md",
},
})
2 changes: 2 additions & 0 deletions packages/react/src/theme/slot-recipes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { popoverSlotRecipe } from "./recipes/popover"
import { progressSlotRecipe } from "./recipes/progress"
import { circularProgressSlotRecipe } from "./recipes/progress-circular"
import { radioSlotRecipe } from "./recipes/radio"
import { segmentGroupSlotRecipe } from "./recipes/segment-group"
import { selectSlotRecipe } from "./recipes/select"
import { sliderSlotRecipe } from "./recipes/slider"
import { statSlotRecipe } from "./recipes/stat"
Expand Down Expand Up @@ -68,4 +69,5 @@ export const slotRecipes = {
PinInput: pinInputSlotRecipe,
EmptyState: emptyStateSlotRecipe,
CheckboxCard: checkboxCardSlotRecipe,
SegmentGroup: segmentGroupSlotRecipe,
}

0 comments on commit 09bea21

Please sign in to comment.