diff --git a/.changeset/soft-bananas-behave.md b/.changeset/soft-bananas-behave.md deleted file mode 100644 index 1df88830ada..00000000000 --- a/.changeset/soft-bananas-behave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@primer/react": minor ---- - -Update FormControl sub-components to use new styled components format for migration diff --git a/package-lock.json b/package-lock.json index 086b673380e..8394b00ba12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -62,7 +62,7 @@ "name": "example-app-router", "version": "0.0.0", "dependencies": { - "@primer/react": "37.6.0", + "@primer/react": "37.5.0", "next": "^14.2.10", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -81,7 +81,7 @@ "react-dom": "^18.3.1" }, "devDependencies": { - "@primer/react": "37.6.0", + "@primer/react": "37.5.0", "@types/react": "^18.3.11", "@types/react-dom": "^18.3.0", "@typescript-eslint/eslint-plugin": "^7.11.0", @@ -99,7 +99,7 @@ "name": "example-consumer-test", "version": "0.0.0", "dependencies": { - "@primer/react": "37.6.0", + "@primer/react": "37.5.0", "@types/react": "^18.3.11", "@types/react-dom": "^18.2.19", "@types/styled-components": "^5.1.11", @@ -125,7 +125,7 @@ "version": "0.0.0", "dependencies": { "@primer/octicons-react": "^19.9.0", - "@primer/react": "37.6.0", + "@primer/react": "37.5.0", "clsx": "^1.2.1", "next": "^14.2.10", "react": "^18.3.1", @@ -30443,7 +30443,7 @@ }, "packages/react": { "name": "@primer/react", - "version": "37.6.0", + "version": "37.5.0", "license": "MIT", "dependencies": { "@github/relative-time-element": "^4.4.3", diff --git a/package.json b/package.json index b4f69ece0ba..cf3ab916a77 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,5 @@ "webpack": false, "running": false } - ], - "packageManager": "npm@10.9.1+sha512.c89530d37c4baa38afd43e76a077a84b9aa63840b986426584fd5c5a54ab0a0b21bb1595c851042b733784b0b43706d36a494b4d8ae1a086a762cb8d3f95942a" + ] } diff --git a/packages/react/src/FormControl/FormControl.tsx b/packages/react/src/FormControl/FormControl.tsx index 69d4b9bf871..a629806a353 100644 --- a/packages/react/src/FormControl/FormControl.tsx +++ b/packages/react/src/FormControl/FormControl.tsx @@ -14,9 +14,9 @@ import {get} from '../constants' import {useSlots} from '../hooks/useSlots' import type {SxProp} from '../sx' import {useId} from '../hooks/useId' -import {FormControlCaption} from './FormControlCaption' -import FormControlLabel from './FormControlLabel' -import FormControlLeadingVisual from './FormControlLeadingVisual' +import FormControlCaption from './_FormControlCaption' +import FormControlLabel from './_FormControlLabel' +import FormControlLeadingVisual from './_FormControlLeadingVisual' import FormControlValidation from './_FormControlValidation' import {FormControlContextProvider} from './_FormControlContext' import {warning} from '../utils/warning' diff --git a/packages/react/src/FormControl/FormControlCaption.tsx b/packages/react/src/FormControl/FormControlCaption.tsx deleted file mode 100644 index dc05e1a3bad..00000000000 --- a/packages/react/src/FormControl/FormControlCaption.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import type {SxProp} from '../sx' -import {useFormControlContext} from './_FormControlContext' -import Text from '../Text' -import styled from 'styled-components' -import {get} from '../constants' -import sx from '../sx' - -const StyledCaption = styled(Text)` - color: var(--fgColor-muted); - display: block; - font-size: ${get('fontSizes.0')}; - - &:where([data-control-disabled]) { - color: var(--control-fgColor-disabled); - } - - ${sx} -` - -type FormControlCaptionProps = React.PropsWithChildren< - { - id?: string - } & SxProp -> - -function FormControlCaption({id, children, sx}: FormControlCaptionProps) { - const {captionId, disabled} = useFormControlContext() - return ( - - {children} - - ) -} - -export {FormControlCaption} diff --git a/packages/react/src/FormControl/FormControlLeadingVisual.tsx b/packages/react/src/FormControl/FormControlLeadingVisual.tsx deleted file mode 100644 index 27c18d69aca..00000000000 --- a/packages/react/src/FormControl/FormControlLeadingVisual.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react' -import {get} from '../constants' -import type {SxProp} from '../sx' -import {useFormControlContext} from './_FormControlContext' -import styled from 'styled-components' -import sx from '../sx' - -const FormControlLeadingVisual: React.FC> = ({children, sx}) => { - const {disabled, captionId} = useFormControlContext() - return ( - - {children} - - ) -} - -const StyledLeadingVisual = styled.div` - --leadingVisual-size: ${get('fontSizes.2')}; - - color: var(--fgColor-default); - margin-inline-start: ${get('space.2')}; - - &:where([data-control-disabled]) { - color: var(--fgColor-muted); - } - - & > * { - min-width: var(--leadingVisual-size); - min-height: var(--leadingVisual-size); - fill: currentColor; - } - - &:where([data-has-caption]) { - --leadingVisual-size: ${get('fontSizes.4')}; - } - - ${sx} -` - -export default FormControlLeadingVisual diff --git a/packages/react/src/FormControl/_FormControlCaption.tsx b/packages/react/src/FormControl/_FormControlCaption.tsx new file mode 100644 index 00000000000..4a3be2bdedb --- /dev/null +++ b/packages/react/src/FormControl/_FormControlCaption.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import InputCaption from '../internal/components/InputCaption' +import type {SxProp} from '../sx' +import {useFormControlContext} from './_FormControlContext' + +const FormControlCaption: React.FC> = ({children, sx, id}) => { + const {captionId, disabled} = useFormControlContext() + return ( + + {children} + + ) +} + +export default FormControlCaption diff --git a/packages/react/src/FormControl/FormControlLabel.tsx b/packages/react/src/FormControl/_FormControlLabel.tsx similarity index 95% rename from packages/react/src/FormControl/FormControlLabel.tsx rename to packages/react/src/FormControl/_FormControlLabel.tsx index 485894c18d4..4d62b19e114 100644 --- a/packages/react/src/FormControl/FormControlLabel.tsx +++ b/packages/react/src/FormControl/_FormControlLabel.tsx @@ -1,7 +1,7 @@ import React from 'react' +import InputLabel from '../internal/components/InputLabel' import type {SxProp} from '../sx' import {useFormControlContext} from './_FormControlContext' -import {InputLabel} from '../internal/components/InputLabel' export type Props = { /** @@ -49,7 +49,6 @@ const FormControlLabel: React.FC< sx, ...props, } - return {children} } diff --git a/packages/react/src/FormControl/_FormControlLeadingVisual.tsx b/packages/react/src/FormControl/_FormControlLeadingVisual.tsx new file mode 100644 index 00000000000..80551681704 --- /dev/null +++ b/packages/react/src/FormControl/_FormControlLeadingVisual.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import Box from '../Box' +import {get} from '../constants' +import type {SxProp} from '../sx' +import {useFormControlContext} from './_FormControlContext' + +const FormControlLeadingVisual: React.FC> = ({children, sx}) => { + const {disabled, captionId} = useFormControlContext() + return ( + *': { + minWidth: captionId ? get('fontSizes.4') : get('fontSizes.2'), + minHeight: captionId ? get('fontSizes.4') : get('fontSizes.2'), + fill: 'currentColor', + }, + ...sx, + }} + ml={2} + > + {children} + + ) +} + +export default FormControlLeadingVisual diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index b407db2cf19..6cffe9375e3 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -20,7 +20,7 @@ import {useSlots} from '../../hooks/useSlots' import {useProvidedRefOrCreate, useId, useAnchoredPosition} from '../../hooks' import type {OverlayProps} from '../../Overlay/Overlay' import {StyledOverlay, heightMap} from '../../Overlay/Overlay' -import {InputLabel} from '../../internal/components/InputLabel' +import InputLabel from '../../internal/components/InputLabel' import {invariant} from '../../utils/invariant' import {AriaStatus} from '../../live-region' import {useResponsiveValue} from '../../hooks/useResponsiveValue' diff --git a/packages/react/src/internal/components/InputCaption.tsx b/packages/react/src/internal/components/InputCaption.tsx new file mode 100644 index 00000000000..03fbb184be9 --- /dev/null +++ b/packages/react/src/internal/components/InputCaption.tsx @@ -0,0 +1,30 @@ +import React from 'react' +import Text from '../../Text' +import type {SxProp} from '../../sx' + +type Props = { + /** + * The unique identifier used to associate the caption with an input + */ + id: string + /** + * Whether the input associated with this caption is disabled + */ + disabled?: boolean +} & SxProp + +const InputCaption: React.FC> = ({children, disabled, id, sx}) => ( + + {children} + +) + +export default InputCaption diff --git a/packages/react/src/internal/components/InputLabel.tsx b/packages/react/src/internal/components/InputLabel.tsx index 9126d192086..b4d2fa43aed 100644 --- a/packages/react/src/internal/components/InputLabel.tsx +++ b/packages/react/src/internal/components/InputLabel.tsx @@ -1,7 +1,7 @@ import React from 'react' -import styled from 'styled-components' -import {get} from '../../constants' -import sx, {type SxProp} from '../../sx' +import Box from '../../Box' +import type {SxProp} from '../../sx' +import VisuallyHidden from '../../_VisuallyHidden' type BaseProps = SxProp & { disabled?: boolean @@ -23,9 +23,9 @@ export type LegendOrSpanProps = BaseProps & { htmlFor?: undefined } -type Props = React.PropsWithChildren +type Props = LabelProps | LegendOrSpanProps -function InputLabel({ +const InputLabel: React.FC> = ({ children, disabled, htmlFor, @@ -38,62 +38,37 @@ function InputLabel({ as = 'label', className, ...props -}: Props) { +}) => { return ( - {required || requiredText ? ( - - {children} + + {children} {requiredText ?? '*'} - + ) : ( children )} - + ) } -const StyledRequiredText = styled.span` - display: flex; - column-gap: ${get('space.1')}; -` - -const StyledLabel = styled.label` - align-self: flex-start; - display: block; - color: var(--fgColor-default); - cursor: pointer; - font-weight: 600; - font-size: ${get('fontSizes.1')}; - - &:where([data-control-disabled]) { - color: var(--fgColor-muted); - cursor: not-allowed; - } - - &:where([data-visually-hidden]) { - border: 0; - clip: rect(0 0 0 0); - clip-path: inset(50%); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - white-space: nowrap; - width: 1px; - } - - ${sx} -` - -export {InputLabel} +export default InputLabel diff --git a/packages/react/src/internal/components/InputValidation.tsx b/packages/react/src/internal/components/InputValidation.tsx index d23fe867cb5..cfa2c8537b5 100644 --- a/packages/react/src/internal/components/InputValidation.tsx +++ b/packages/react/src/internal/components/InputValidation.tsx @@ -1,12 +1,10 @@ import type {IconProps} from '@primer/octicons-react' import {AlertFillIcon, CheckCircleFillIcon} from '@primer/octicons-react' import React from 'react' +import Box from '../../Box' import Text from '../../Text' import type {SxProp} from '../../sx' import type {FormValidationStatus} from '../../utils/types/FormValidationStatus' -import styled from 'styled-components' -import {get} from '../../constants' -import sx from '../../sx' type Props = { id: string @@ -21,8 +19,14 @@ const validationIconMap: Record< error: AlertFillIcon, } +const validationColorMap: Record, string> = { + success: 'success.fg', + error: 'danger.fg', +} + const InputValidation: React.FC> = ({children, id, validationStatus, sx}) => { const IconComponent = validationStatus ? validationIconMap[validationStatus] : undefined + const fgColor = validationStatus ? validationColorMap[validationStatus] : undefined // TODO: use `text-caption-lineHeight` token as a custom property when it's available // then, we can move this all to CSS and use `calc` to get our height values @@ -31,57 +35,30 @@ const InputValidation: React.FC> = ({children, id const iconBoxMinHeight = iconSize * captionLineHeight return ( - - {IconComponent ? ( - - ) : null} - + + )} + {children} - - + + ) } -const StyledInputValidation = styled(Text)` - color: var(--inputValidation-fgColor); - display: flex; - font-size: ${get('fontSizes.0')}; - font-weight: 600; - - & :where(a) { - color: currentColor; - text-dectoration: underline; - } - - &:where([data-validation-status='success']) { - --inputValidation-fgColor: ${get('colors.success.fg')}; - } - - &:where([data-validation-status='error']) { - --inputValidation-fgColor: ${get('colors.danger.fg')}; - } - - ${sx} -` - -const StyledValidationIcon = styled.span` - align-items: center; - display: flex; - margin-inline-end: ${get('space.1')}; - min-height: var(--inputValidation-iconSize); -` - -const StyledValidationText = styled.span` - line-height: var(--inputValidation-lineHeight); -` - export default InputValidation