Skip to content

Commit

Permalink
rename InputGroup to ControlGroup
Browse files Browse the repository at this point in the history
  • Loading branch information
joshfarrant committed Nov 25, 2024
1 parent aca86dc commit 790fa13
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 162 deletions.
22 changes: 11 additions & 11 deletions packages/react/src/forms/CheckboxGroup/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {
InputGroup,
type InputGroupCaptionProps,
type InputGroupLabelProps,
type InputGroupProps,
type InputGroupValidationProps,
} from '../InputGroup'
ControlGroup,
type ControlGroupCaptionProps,
type ControlGroupLabelProps,
type ControlGroupProps,
type ControlGroupValidationProps,
} from '../ControlGroup'

export type CheckboxGroupProps = InputGroupProps
export type CheckboxGroupLabelProps = InputGroupLabelProps
export type CheckboxGroupCaptionProps = InputGroupCaptionProps
export type CheckboxGroupValidationProps = InputGroupValidationProps
export type CheckboxGroupProps = ControlGroupProps
export type CheckboxGroupLabelProps = ControlGroupLabelProps
export type CheckboxGroupCaptionProps = ControlGroupCaptionProps
export type CheckboxGroupValidationProps = ControlGroupValidationProps

export const CheckboxGroup = InputGroup
export const CheckboxGroup = ControlGroup
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.InputGroup__container {
.ControlGroup__container {
display: flex;
flex-direction: column;
gap: var(--base-size-8);
Expand All @@ -9,51 +9,51 @@
padding: 0;
}

.InputGroup__label {
.ControlGroup__label {
font-weight: var(--base-text-weight-semibold);
margin: 0;
padding: 0;
margin-bottom: var(--base-size-8);
}

.InputGroup__caption {
.ControlGroup__caption {
font-size: var(--brand-text-size-200);
letter-spacing: var(--brand-text-letterSpacing-200);
line-height: var(--brand-text-lineHeight-200);
color: var(--brand-color-text-muted);
}

.InputGroup__validation {
.ControlGroup__validation {
display: flex;
gap: var(--base-size-4);
font-size: var(--brand-text-size-200);
font-weight: var(--base-text-weight-regular);
line-height: var(--brand-text-lineHeight-200);
}

.InputGroup__validation--success {
.ControlGroup__validation--success {
color: var(--brand-color-success-fg);
}

.InputGroup__validation--error {
.ControlGroup__validation--error {
color: var(--brand-color-error-fg);
}

.InputGroup__validation-icon--success {
.ControlGroup__validation-icon--success {
position: relative;
top: -1.6px;
}

.InputGroup__validation-icon--error {
.ControlGroup__validation-icon--error {
position: relative;
top: -1px;
}

.InputGroup__validation--animate-in {
animation: 170ms InputGroupValidationFadeIn cubic-bezier(0.44, 0.74, 0.36, 1);
.ControlGroup__validation--animate-in {
animation: 170ms ControlGroupValidationFadeIn cubic-bezier(0.44, 0.74, 0.36, 1);
}

@keyframes InputGroupValidationFadeIn {
@keyframes ControlGroupValidationFadeIn {
0% {
opacity: 0;
transform: translateY(-100%);
Expand Down
114 changes: 114 additions & 0 deletions packages/react/src/forms/ControlGroup/ControlGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import clsx from 'clsx'
import React, {Children, createContext, forwardRef, isValidElement, useContext, type HTMLAttributes} from 'react'
import {AlertFillIcon, CheckCircleFillIcon} from '@primer/octicons-react'

import styles from './ControlGroup.module.css'
import type {FormValidationStatus} from '..'
import {useId} from '@reach/auto-id'

type ControlGroupContext = {
id?: string
}

const ControlGroupContext = createContext<ControlGroupContext | null>(null)

const useControlGroup = () => {
const context = useContext(ControlGroupContext)

if (!context) {
throw new Error(
'useControlGroup must be used within an ControlGroupProvider. Did you forget to wrap your component in a <ControlGroupProvider>?',
)
}

return context
}

export type ControlGroupProps = HTMLAttributes<HTMLFieldSetElement>
const _ControlGroup = forwardRef<HTMLFieldSetElement, ControlGroupProps>(({className, id, ...props}, ref) => {
const uniqueId = useId(id)

const containsCaption = Children.toArray(props.children).some(
child => isValidElement(child) && child.type === ControlGroupCaption,
)
const containsValidation = Children.toArray(props.children).some(
child => isValidElement(child) && child.type === ControlGroupValidation,
)

const describedBy =
[containsCaption && `${uniqueId}-caption`, containsValidation && `${uniqueId}-validation`]
.filter(Boolean)
.join(' ') || undefined

return (
<ControlGroupContext.Provider value={{id: uniqueId}}>
<fieldset
ref={ref}
className={clsx(styles.ControlGroup__container, className)}
aria-describedby={describedBy}
{...props}
/>
</ControlGroupContext.Provider>
)
})

export type ControlGroupLabelProps = {visuallyHidden?: boolean} & HTMLAttributes<HTMLLegendElement>
const ControlGroupLabel = forwardRef<HTMLLegendElement, ControlGroupLabelProps>(
({className, visuallyHidden, ...props}, ref) => {
return (
<legend
ref={ref}
className={clsx(styles.ControlGroup__label, visuallyHidden && 'visually-hidden', className)}
{...props}
/>
)
},
)

export type ControlGroupCaptionProps = HTMLAttributes<HTMLSpanElement>
const ControlGroupCaption = forwardRef<HTMLSpanElement, ControlGroupCaptionProps>(({className, ...props}, ref) => {
const {id} = useControlGroup()

return <span ref={ref} id={`${id}-caption`} className={clsx(styles.ControlGroup__caption, className)} {...props} />
})

export type ControlGroupValidationProps = {variant: FormValidationStatus} & HTMLAttributes<HTMLSpanElement>
const ControlGroupValidation = forwardRef<HTMLSpanElement, ControlGroupValidationProps>(
({className, variant, children, ...props}, ref) => {
const {id} = useControlGroup()

return (
<span
ref={ref}
id={`${id}-validation`}
className={clsx(
styles.ControlGroup__validation,
styles['ControlGroup__validation--animate-in'],
variant === 'success' && styles['ControlGroup__validation--success'],
variant === 'error' && styles['ControlGroup__validation--error'],
className,
)}
{...props}
>
{variant === 'success' && (
<span className={styles['ControlGroup__validation-icon--success']}>
<CheckCircleFillIcon />
</span>
)}
{variant === 'error' && (
<span className={styles['ControlGroup__validation-icon--error']}>
<AlertFillIcon />
</span>
)}

{children}
</span>
)
},
)

export const ControlGroup = Object.assign(_ControlGroup, {
Label: ControlGroupLabel,
Caption: ControlGroupCaption,
Validation: ControlGroupValidation,
})
14 changes: 14 additions & 0 deletions packages/react/src/forms/ControlGroup/InputGroup.module.css.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
declare const styles: {
readonly "ControlGroup__container": string;
readonly "ControlGroup__label": string;
readonly "ControlGroup__caption": string;
readonly "ControlGroup__validation": string;
readonly "ControlGroup__validation--success": string;
readonly "ControlGroup__validation--error": string;
readonly "ControlGroup__validation-icon--success": string;
readonly "ControlGroup__validation-icon--error": string;
readonly "ControlGroup__validation--animate-in": string;
readonly "ControlGroupValidationFadeIn": string;
};
export = styles;

1 change: 1 addition & 0 deletions packages/react/src/forms/ControlGroup/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ControlGroup'
14 changes: 0 additions & 14 deletions packages/react/src/forms/InputGroup/InputGroup.module.css.d.ts

This file was deleted.

114 changes: 0 additions & 114 deletions packages/react/src/forms/InputGroup/InputGroup.tsx

This file was deleted.

1 change: 0 additions & 1 deletion packages/react/src/forms/InputGroup/index.ts

This file was deleted.

22 changes: 11 additions & 11 deletions packages/react/src/forms/RadioGroup/RadioGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {
InputGroup,
type InputGroupCaptionProps,
type InputGroupLabelProps,
type InputGroupProps,
type InputGroupValidationProps,
} from '../InputGroup'
ControlGroup,
type ControlGroupCaptionProps,
type ControlGroupLabelProps,
type ControlGroupProps,
type ControlGroupValidationProps,
} from '../ControlGroup'

export type RadioGroupProps = InputGroupProps
export type RadioGroupLabelProps = InputGroupLabelProps
export type RadioGroupCaptionProps = InputGroupCaptionProps
export type RadioGroupValidationProps = InputGroupValidationProps
export type RadioGroupProps = ControlGroupProps
export type RadioGroupLabelProps = ControlGroupLabelProps
export type RadioGroupCaptionProps = ControlGroupCaptionProps
export type RadioGroupValidationProps = ControlGroupValidationProps

export const RadioGroup = InputGroup
export const RadioGroup = ControlGroup

0 comments on commit 790fa13

Please sign in to comment.