{ "name": "segmented-input", "type": "registry:ui", "dependencies": [ "radix-ui" ], "registryDependencies": [ "input" ], "files": [ { "path": "ui/segmented-input.tsx", "type": "registry:ui", "content": "\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport {\n Direction as DirectionPrimitive,\n Slot as SlotPrimitive,\n} from \"radix-ui\";\nimport * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Input } from \"@/registry/bases/radix/ui/input\";\n\nconst ROOT_NAME = \"SegmentedInput\";\nconst ITEM_NAME = \"SegmentedInputItem\";\n\ntype Direction = \"ltr\" | \"rtl\";\ntype Orientation = \"horizontal\" | \"vertical\";\ntype Size = \"default\" | \"sm\" | \"lg\";\ntype Position = \"isolated\" | \"first\" | \"middle\" | \"last\";\n\ninterface SegmentedInputContextValue {\n dir?: Direction;\n orientation?: Orientation;\n size?: Size;\n disabled?: boolean;\n invalid?: boolean;\n required?: boolean;\n}\n\nconst SegmentedInputContext =\n React.createContext(null);\n\nfunction useSegmentedInputContext(consumerName: string) {\n const context = React.useContext(SegmentedInputContext);\n if (!context) {\n throw new Error(`\\`${consumerName}\\` must be used within \\`${ROOT_NAME}\\``);\n }\n return context;\n}\n\ninterface SegmentedInputProps extends React.ComponentProps<\"div\"> {\n dir?: Direction;\n orientation?: Orientation;\n size?: Size;\n asChild?: boolean;\n disabled?: boolean;\n invalid?: boolean;\n required?: boolean;\n}\n\nfunction SegmentedInput(props: SegmentedInputProps) {\n const {\n size = \"default\",\n dir: dirProp,\n orientation = \"horizontal\",\n children,\n className,\n asChild,\n disabled,\n invalid,\n required,\n ...rootProps\n } = props;\n\n const dir = DirectionPrimitive.useDirection(dirProp);\n\n const contextValue = React.useMemo(\n () => ({\n dir,\n orientation,\n size,\n disabled,\n invalid,\n required,\n }),\n [dir, orientation, size, disabled, invalid, required],\n );\n\n const childrenArray = React.Children.toArray(children);\n const childrenCount = childrenArray.length;\n\n const segmentedInputItems = React.Children.map(children, (child, index) => {\n if (React.isValidElement(child)) {\n if (!child.props.position) {\n let position: Position;\n\n if (childrenCount === 1) {\n position = \"isolated\";\n } else if (index === 0) {\n position = \"first\";\n } else if (index === childrenCount - 1) {\n position = \"last\";\n } else {\n position = \"middle\";\n }\n\n return React.cloneElement(child, { position });\n }\n }\n return child;\n });\n\n const RootPrimitive = asChild ? SlotPrimitive.Slot : \"div\";\n\n return (\n \n \n {segmentedInputItems}\n \n \n );\n}\n\nconst segmentedInputItemVariants = cva(\"\", {\n variants: {\n position: {\n isolated: \"\",\n first: \"rounded-e-none\",\n middle: \"-ms-px rounded-none border-l-0\",\n last: \"-ms-px rounded-s-none border-l-0\",\n },\n orientation: {\n horizontal: \"\",\n vertical: \"\",\n },\n size: {\n sm: \"h-8 px-2 text-xs\",\n default: \"h-9 px-3\",\n lg: \"h-11 px-4\",\n },\n },\n compoundVariants: [\n {\n position: \"first\",\n orientation: \"vertical\",\n class: \"ms-0 rounded-e-md rounded-b-none border-l\",\n },\n {\n position: \"middle\",\n orientation: \"vertical\",\n class: \"ms-0 -mt-px rounded-none border-t-0 border-l\",\n },\n {\n position: \"last\",\n orientation: \"vertical\",\n class: \"ms-0 -mt-px rounded-s-md rounded-t-none border-t-0 border-l\",\n },\n ],\n defaultVariants: {\n position: \"isolated\",\n orientation: \"horizontal\",\n size: \"default\",\n },\n});\n\ninterface SegmentedInputItemProps\n extends React.ComponentProps<\"input\">,\n Omit, \"size\"> {\n asChild?: boolean;\n}\n\nfunction SegmentedInputItem(props: SegmentedInputItemProps) {\n const { asChild, className, position, disabled, required, ...inputProps } =\n props;\n const context = useSegmentedInputContext(ITEM_NAME);\n\n const isDisabled = disabled ?? context.disabled;\n const isRequired = required ?? context.required;\n\n const ItemPrimitive = asChild ? SlotPrimitive.Slot : Input;\n\n return (\n \n );\n}\n\nexport { SegmentedInput, SegmentedInputItem, type SegmentedInputProps };\n", "target": "" } ] }