From 7c56e33d8dc72a4ec163a1b35f04bcc7dfe6e347 Mon Sep 17 00:00:00 2001 From: Hussam Ghazzi Date: Thu, 21 Nov 2024 23:14:28 +0000 Subject: [PATCH 1/6] feat(SelectPanel): Convert SelectPanel to CSS modules behind feature flag --- .changeset/cyan-boxes-peel.md | 5 + .../SelectPanel2/SelectPanel.module.css | 273 ++++++++++++++++++ .../experimental/SelectPanel2/SelectPanel.tsx | 249 +++++----------- 3 files changed, 343 insertions(+), 184 deletions(-) create mode 100644 .changeset/cyan-boxes-peel.md create mode 100644 packages/react/src/experimental/SelectPanel2/SelectPanel.module.css diff --git a/.changeset/cyan-boxes-peel.md b/.changeset/cyan-boxes-peel.md new file mode 100644 index 00000000000..351dabb95aa --- /dev/null +++ b/.changeset/cyan-boxes-peel.md @@ -0,0 +1,5 @@ +--- +"@primer/react": minor +--- + +Convert SelectPanel2 to CSS modules behind feature flag diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css b/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css new file mode 100644 index 00000000000..25e61289d13 --- /dev/null +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css @@ -0,0 +1,273 @@ +.Overlay { + padding: 0; + color: var(--fgColor-default); + border: none; + + /* CSS variables values are passed in via styles */ + --max-height: 0; + --position-top: 0; + --position-left: 0; + + &[open] { + display: flex; /* to fit children */ + } + + &[data-variant='anchored'], + &[data-variant='full-screen'] { + /* stylelint-disable-next-line primer/spacing */ + top: var(--position-top); + /* stylelint-disable-next-line primer/spacing */ + left: var(--position-left); + margin: 0; + + &::backdrop { + background-color: transparent; + } + } + + &[data-variant='modal']::backdrop { + background-color: var(--overlay-backdrop-bgColor); + } + + &[data-variant='full-screen'] { + top: 0; + left: 0; + width: 100%; + max-width: 100vw; + height: 100%; + max-height: 100vh; + margin: 0; + border-radius: unset; + } + + &[data-variant='bottom-sheet'] { + top: auto; + bottom: 0; + left: 0; + width: 100%; + max-width: 100vw; + max-height: calc(100vh - 64px); + margin: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; + } +} + +.Form { + display: flex; + width: 100%; + flex-direction: column; +} + +.Container { + display: flex; + overflow: hidden; + flex-direction: column; + flex-shrink: 1; + flex-grow: 1; + justify-content: space-between; + + ul { + overflow-y: auto; + flex-grow: 1; + } +} + +.HeaderContent { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 0; + + &:where([data-description]) { + align-items: flex-start; + } + + &:where([data-search-input]) { + margin-bottom: var(--base-size-8); + } +} + +.TitleWrapper { + margin-top: 0; + margin-left: var(--base-size-8); + + &:where([data-description]) { + /* stylelint-disable-next-line primer/spacing */ + margin-top: 2px; + } + + &:where([data-on-back]) { + margin-left: var(--base-size-4); + } +} + +.TextInput { + padding-left: var(--base-size-8); + + &:has(input:placeholder-shown) :global(.TextInput-action) { + display: none; + } +} + +.Checkbox { + margin-top: 0; +} + +.FlexBox { + display: flex; +} + +.Title { + font-size: var(--text-body-size-medium); + font-weight: var(--base-text-weight-semibold); +} + +.Description { + display: block; + font-size: var(--text-body-size-small); + color: var(--fgColor-muted); +} + +.ClearAction { + color: var(--fgColor-muted); + background: none; +} + +.Footer { + display: flex; + min-height: 44px; + padding: var(--base-size-16); + border-color: var(--borderColor-default); + border-top: var(--borderWidth-thin) solid; + justify-content: space-between; + align-items: center; + flex-shrink: 0; + + &:where([data-hide-primary-actions]) { + padding: var(--base-size-8); + } +} + +.FooterContent { + flex-grow: 0; + + &:where([data-hide-primary-actions]) { + flex-grow: 1; + } +} + +.FooterActions { + display: flex; + gap: var(--stack-gap-condensed); +} + +.SecondaryCheckbox { + display: flex; + align-items: center; + gap: var(--stack-gap-condensed); +} + +.SmallText { + font-size: var(--text-body-size-small); +} + +.SelectPanelLoading { + display: flex; + height: 100%; + + /* maxHeight of dialog - (header & footer) */ + min-height: min(calc(var(--max-height) - 150px), 324px); + flex-direction: column; + justify-content: center; + align-items: center; + gap: var(--stack-gap-normal); +} + +.LoadingText { + font-size: var(--text-body-size-medium); + color: var(--fgColor-muted); +} + +.MessageFull { + display: flex; + height: 100%; + + /* maxHeight of dialog - (header & footer) */ + min-height: min(calc(var(--max-height) - 150px), 324px); + padding-right: var(--base-size-24); + padding-left: var(--base-size-24); + text-align: center; + flex-direction: column; + justify-content: center; + align-items: center; + flex-grow: 1; + gap: var(--base-size-4); + + a { + color: inherit; + text-decoration: underline; + } +} + +.Octicon { + margin-bottom: var(--base-size-8); + + &:where([data-variant='error']) { + color: var(--fgColor-danger); + } + + &:where([data-variant='warning']) { + color: var(--fgColor-attention); + } +} + +.MessageTitle { + font-size: var(--text-body-size-medium); + font-weight: var(--base-text-weight-medium); +} + +.MessageContent { + display: flex; + font-size: var(--text-body-size-medium); + color: var(--fgColor-muted); + flex-direction: column; + gap: var(--stack-gap-condensed); + align-items: center; +} + +.MessageInline { + display: flex; + padding-top: var(--base-size-12); + padding-right: var(--base-size-16); + padding-bottom: var(--base-size-12); + padding-left: var(--base-size-16); + font-size: var(--text-body-size-small); + border-bottom: var(--borderWidth-thin) solid; + gap: var(--stack-gap-condensed); + + a { + color: inherit; + text-decoration: underline; + } + + &:where([data-variant='error']) { + color: var(--fgColor-danger); + background-color: var(--bgColor-danger-muted); + border-color: var(--borderColor-danger-muted); + } + + &:where([data-variant='warning']) { + color: var(--fgColor-attention); + background-color: var(--bgColor-attention-muted); + border-color: var(--borderColor-attention-muted); + } +} + +.Header { + display: flex; + padding: var(--base-size-8); + flex-direction: column; + border-color: var(--borderColor-default); + border-bottom: var(--borderWidth-thin) solid; +} diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index ac53c6a4aac..ce3bc8dc661 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -6,7 +6,6 @@ import { Button, IconButton, Heading, - Box, TextInput, Spinner, Text, @@ -26,6 +25,8 @@ import {AriaStatus} from '../../live-region' import {useResponsiveValue} from '../../hooks/useResponsiveValue' import type {ResponsiveValue} from '../../hooks/useResponsiveValue' +import classes from './SelectPanel.module.css' + const SelectPanelContext = React.createContext<{ title: string description?: string @@ -231,6 +232,13 @@ const Panel: React.FC = ({ */ const onClickOutside = onInternalCancel + let maxHeightValue = heightMap[maxHeight] + if (currentVariant === 'bottom-sheet') { + maxHeightValue = 'calc(100vh - 64px)' + } else if (currentVariant === 'full-screen') { + maxHeightValue = '100vh' + } + return ( <> {Anchor} @@ -244,47 +252,13 @@ const Panel: React.FC = ({ height="fit-content" maxHeight={maxHeight} data-variant={currentVariant} - sx={{ - '--max-height': heightMap[maxHeight], - // reset dialog default styles - border: 'none', - padding: 0, - color: 'fg.default', - '&[open]': {display: 'flex'}, // to fit children - - '&[data-variant="anchored"], &[data-variant="full-screen"]': { - margin: 0, - top: position?.top, - left: position?.left, - '::backdrop': {backgroundColor: 'transparent'}, - }, - '&[data-variant="modal"]': { - '::backdrop': {backgroundColor: 'primer.canvas.backdrop'}, - }, - '&[data-variant="full-screen"]': { - margin: 0, - top: 0, - left: 0, - width: '100%', - maxWidth: '100vw', - height: '100%', - maxHeight: '100vh', - '--max-height': '100vh', - borderRadius: 'unset', - }, - '&[data-variant="bottom-sheet"]': { - margin: 0, - top: 'auto', - bottom: 0, - left: 0, - width: '100%', - maxWidth: '100vw', - maxHeight: 'calc(100vh - 64px)', - '--max-height': 'calc(100vh - 64px)', - borderBottomRightRadius: 0, - borderBottomLeftRadius: 0, - }, - }} + style={ + { + '--max-height': maxHeightValue, + '--position-top': position?.top, + '--position-left': position?.left, + } as React.CSSProperties + } {...props} onClick={event => { if (event.target === event.currentTarget) onClickOutside() @@ -305,26 +279,10 @@ const Panel: React.FC = ({ moveFocusToList, }} > - +
{slots.header ?? /* render default header as fallback */ } - +
= ({ > {childrenInBody} - +
{slots.footer} -
+ )} @@ -380,26 +338,13 @@ const SelectPanelHeader: React.FC void const {title, description, panelId, onCancel, onClearSelection} = React.useContext(SelectPanelContext) return ( - - +
- +
{onBack ? ( void /> ) : null} - +
{/* heading element is intentionally hardcoded to h1, it is not customisable see https://github.com/github/primer/issues/2578 for context */} - + {title} {description ? ( - + {description} ) : null} - - +
+
- +
{onClearSelection ? ( void /> ) : null} onCancel()} /> - - +
+
{slots.searchInput} {childrenWithoutSlots} -
+ ) } @@ -482,7 +431,7 @@ const SelectPanelSearchInput: React.FC = ({ icon={XCircleFillIcon} aria-label="Clear" tooltipDirection="w" - sx={{color: 'fg.subtle', bg: 'none'}} + className={classes.ClearAction} onClick={() => { if (inputRef.current) inputRef.current.value = '' if (typeof propsOnChange === 'function') { @@ -492,10 +441,7 @@ const SelectPanelSearchInput: React.FC = ({ }} /> } - sx={{ - paddingLeft: 2, // align with list checkboxes - '&:has(input:placeholder-shown) .TextInput-action': {display: 'none'}, - }} + className={classes.TextInput} onChange={internalOnChange} onKeyDown={internalKeyDown} {...props} @@ -518,31 +464,22 @@ const SelectPanelFooter = ({...props}) => { return ( - - {props.children} +
+
+ {props.children} +
{hidePrimaryActions ? null : ( - +
- +
)} -
+
) } @@ -556,7 +493,7 @@ const SecondaryLink: React.FC = props => { const size = useResponsiveValue(responsiveButtonSizes, 'small') return ( // @ts-ignore TODO: is as prop is not recognised by button? - ) @@ -573,12 +510,12 @@ const SecondaryCheckbox: React.FC = ({id, children, ...props}) => ) return ( - - - +
+ + {children} - +
) } @@ -603,21 +540,9 @@ const SelectPanelSecondaryAction: React.FC = ({ const SelectPanelLoading = ({children = 'Fetching items...'}: React.PropsWithChildren) => { return ( - + - {children} + {children} ) } @@ -643,66 +568,22 @@ const SelectPanelMessage: React.FC = ({ }) => { if (size === 'full') { return ( - - {variant !== 'empty' ? ( - - ) : null} - {title} - - {children} - - +
+ {variant !== 'empty' ? : null} + {title} + {children} +
) } else { - const inlineVariantStyles = { - empty: {}, - warning: { - backgroundColor: 'attention.subtle', - color: 'attention.fg', - borderBottomColor: 'attention.muted', - }, - error: { - backgroundColor: 'danger.subtle', - color: 'danger.fg', - borderColor: 'danger.muted', - }, - } - return ( - - {children} - +
{children}
+ ) } } From 05a46dc64708f2e031e773c2654d24ca3cddeb76 Mon Sep 17 00:00:00 2001 From: Hussam Ghazzi Date: Thu, 21 Nov 2024 23:15:46 +0000 Subject: [PATCH 2/6] update changeset --- .changeset/cyan-boxes-peel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cyan-boxes-peel.md b/.changeset/cyan-boxes-peel.md index 351dabb95aa..2331fb6e904 100644 --- a/.changeset/cyan-boxes-peel.md +++ b/.changeset/cyan-boxes-peel.md @@ -2,4 +2,4 @@ "@primer/react": minor --- -Convert SelectPanel2 to CSS modules behind feature flag +Convert SelectPanel2 to CSS modules From 1e2eda039f21a0c8178fcb0c064c9766d67d133f Mon Sep 17 00:00:00 2001 From: Hussam Ghazzi Date: Fri, 22 Nov 2024 00:10:42 +0000 Subject: [PATCH 3/6] style fixes --- .../SelectPanel2/SelectPanel.module.css | 18 +++++++++--------- .../experimental/SelectPanel2/SelectPanel.tsx | 9 +++++---- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css b/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css index 25e61289d13..cd227d9afdc 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css @@ -8,12 +8,12 @@ --position-top: 0; --position-left: 0; - &[open] { + &:where([open]) { display: flex; /* to fit children */ } - &[data-variant='anchored'], - &[data-variant='full-screen'] { + &:where([data-variant='anchored']), + &:where([data-variant='full-screen']) { /* stylelint-disable-next-line primer/spacing */ top: var(--position-top); /* stylelint-disable-next-line primer/spacing */ @@ -25,11 +25,11 @@ } } - &[data-variant='modal']::backdrop { + &:where([data-variant='modal'])::backdrop { background-color: var(--overlay-backdrop-bgColor); } - &[data-variant='full-screen'] { + &:where([data-variant='full-screen']) { top: 0; left: 0; width: 100%; @@ -40,7 +40,7 @@ border-radius: unset; } - &[data-variant='bottom-sheet'] { + &:where([data-variant='bottom-sheet']) { top: auto; bottom: 0; left: 0; @@ -103,7 +103,7 @@ } .TextInput { - padding-left: var(--base-size-8); + padding-left: var(--base-size-8) !important; &:has(input:placeholder-shown) :global(.TextInput-action) { display: none; @@ -138,8 +138,8 @@ display: flex; min-height: 44px; padding: var(--base-size-16); - border-color: var(--borderColor-default); border-top: var(--borderWidth-thin) solid; + border-top-color: var(--borderColor-default); justify-content: space-between; align-items: center; flex-shrink: 0; @@ -268,6 +268,6 @@ display: flex; padding: var(--base-size-8); flex-direction: column; - border-color: var(--borderColor-default); border-bottom: var(--borderWidth-thin) solid; + border-bottom-color: var(--borderColor-default); } diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index ce3bc8dc661..b9d2850dd5a 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -255,10 +255,11 @@ const Panel: React.FC = ({ style={ { '--max-height': maxHeightValue, - '--position-top': position?.top, - '--position-left': position?.left, + '--position-top': `${position?.top ?? 0}px`, + '--position-left': `${position?.left ?? 0}px`, } as React.CSSProperties } + className={classes.Overlay} {...props} onClick={event => { if (event.target === event.currentTarget) onClickOutside() @@ -464,8 +465,8 @@ const SelectPanelFooter = ({...props}) => { return ( -
-
+
+
{props.children}
From 0cf233613dc9eff5929ea8b2b5c9a799c91cd1c1 Mon Sep 17 00:00:00 2001 From: Hussam Ghazzi Date: Fri, 22 Nov 2024 00:25:17 +0000 Subject: [PATCH 4/6] fix icon color --- .../experimental/SelectPanel2/SelectPanel.module.css | 4 ++-- .../src/experimental/SelectPanel2/SelectPanel.tsx | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css b/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css index cd227d9afdc..4a7feda9c3d 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.module.css @@ -213,11 +213,11 @@ .Octicon { margin-bottom: var(--base-size-8); - &:where([data-variant='error']) { + &.Error { color: var(--fgColor-danger); } - &:where([data-variant='warning']) { + &.Warning { color: var(--fgColor-attention); } } diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index b9d2850dd5a..a02377202ec 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -26,6 +26,7 @@ import {useResponsiveValue} from '../../hooks/useResponsiveValue' import type {ResponsiveValue} from '../../hooks/useResponsiveValue' import classes from './SelectPanel.module.css' +import {clsx} from 'clsx' const SelectPanelContext = React.createContext<{ title: string @@ -570,7 +571,16 @@ const SelectPanelMessage: React.FC = ({ if (size === 'full') { return (
- {variant !== 'empty' ? : null} + {variant !== 'empty' ? ( + + ) : null} {title} {children}
From 94820fefee921415268ee269b902cbd61b4c7a14 Mon Sep 17 00:00:00 2001 From: Hussam Ghazzi Date: Fri, 22 Nov 2024 19:24:37 +0000 Subject: [PATCH 5/6] readd sx --- .../experimental/SelectPanel2/SelectPanel.tsx | 366 +++++++++++++++--- 1 file changed, 315 insertions(+), 51 deletions(-) diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index a02377202ec..a0501ebe826 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -12,6 +12,7 @@ import { Link, Checkbox, useFormControlForwardedProps, + Box, } from '../../index' import Octicon from '../../Octicon' import {ActionListContainerContext} from '../../ActionList/ActionListContainerContext' @@ -27,6 +28,9 @@ import type {ResponsiveValue} from '../../hooks/useResponsiveValue' import classes from './SelectPanel.module.css' import {clsx} from 'clsx' +import {useFeatureFlag} from '../../FeatureFlags' + +const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team' const SelectPanelContext = React.createContext<{ title: string @@ -95,6 +99,7 @@ const Panel: React.FC = ({ ...props }) => { const [internalOpen, setInternalOpen] = React.useState(defaultOpen) + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) const responsiveVariants = Object.assign( {regular: 'anchored', narrow: 'full-screen'}, // defaults @@ -254,13 +259,60 @@ const Panel: React.FC = ({ maxHeight={maxHeight} data-variant={currentVariant} style={ - { - '--max-height': maxHeightValue, - '--position-top': `${position?.top ?? 0}px`, - '--position-left': `${position?.left ?? 0}px`, - } as React.CSSProperties + enabled + ? ({ + '--max-height': maxHeightValue, + '--position-top': `${position?.top ?? 0}px`, + '--position-left': `${position?.left ?? 0}px`, + } as React.CSSProperties) + : undefined + } + className={enabled ? classes.Overlay : undefined} + sx={ + enabled + ? undefined + : { + '--max-height': heightMap[maxHeight], + // reset dialog default styles + border: 'none', + padding: 0, + color: 'fg.default', + '&[open]': {display: 'flex'}, // to fit children + + '&[data-variant="anchored"], &[data-variant="full-screen"]': { + margin: 0, + top: position?.top, + left: position?.left, + '::backdrop': {backgroundColor: 'transparent'}, + }, + '&[data-variant="modal"]': { + '::backdrop': {backgroundColor: 'primer.canvas.backdrop'}, + }, + '&[data-variant="full-screen"]': { + margin: 0, + top: 0, + left: 0, + width: '100%', + maxWidth: '100vw', + height: '100%', + maxHeight: '100vh', + '--max-height': '100vh', + borderRadius: 'unset', + }, + '&[data-variant="bottom-sheet"]': { + margin: 0, + top: 'auto', + bottom: 0, + left: 0, + width: '100%', + maxWidth: '100vw', + maxHeight: 'calc(100vh - 64px)', + '--max-height': 'calc(100vh - 64px)', + borderBottomRightRadius: 0, + borderBottomLeftRadius: 0, + }, + } } - className={classes.Overlay} {...props} onClick={event => { if (event.target === event.currentTarget) onClickOutside() @@ -281,10 +333,32 @@ const Panel: React.FC = ({ moveFocusToList, }} > -
+ {slots.header ?? /* render default header as fallback */ } -
+ = ({ > {childrenInBody} -
+
{slots.footer} -
+ )} @@ -332,21 +406,52 @@ const SelectPanelButton = React.forwardRef((prop } }) -const SelectPanelHeader: React.FC void}> = ({children, onBack, ...props}) => { +const SelectPanelHeader: React.FC & {onBack?: () => void}> = ({ + children, + onBack, + className, + ...props +}) => { const [slots, childrenWithoutSlots] = useSlots(children, { searchInput: SelectPanelSearchInput, }) const {title, description, panelId, onCancel, onClearSelection} = React.useContext(SelectPanelContext) + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) return ( -
-
+ -
+ {onBack ? ( void /> ) : null} -
{/* heading element is intentionally hardcoded to h1, it is not customisable see https://github.com/github/primer/issues/2578 for context */} - + {title} {description ? ( - + {description} ) : null} -
-
+
+
{onClearSelection ? ( @@ -388,21 +503,23 @@ const SelectPanelHeader: React.FC void ) : null} onCancel()} />
-
+ {slots.searchInput} {childrenWithoutSlots} -
+ ) } const SelectPanelSearchInput: React.FC = ({ onChange: propsOnChange, onKeyDown: propsOnKeyDown, + className, ...props }) => { // TODO: use forwardedRef const inputRef = React.createRef() + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) const {setSearchQuery, moveFocusToList} = React.useContext(SelectPanelContext) @@ -433,7 +550,8 @@ const SelectPanelSearchInput: React.FC = ({ icon={XCircleFillIcon} aria-label="Clear" tooltipDirection="w" - className={classes.ClearAction} + sx={enabled ? undefined : {color: 'fg.subtle', bg: 'none'}} + className={enabled ? classes.ClearAction : undefined} onClick={() => { if (inputRef.current) inputRef.current.value = '' if (typeof propsOnChange === 'function') { @@ -443,7 +561,15 @@ const SelectPanelSearchInput: React.FC = ({ }} /> } - className={classes.TextInput} + sx={ + enabled + ? undefined + : { + paddingLeft: 2, // align with list checkboxes + '&:has(input:placeholder-shown) .TextInput-action': {display: 'none'}, + } + } + className={clsx(enabled ? classes.TextInput : undefined, className)} onChange={internalOnChange} onKeyDown={internalKeyDown} {...props} @@ -457,6 +583,7 @@ const SelectPanelFooter = ({...props}) => { const hidePrimaryActions = selectionVariant === 'instant' const buttonSize = useResponsiveValue(responsiveButtonSizes, 'small') + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) if (hidePrimaryActions && !props.children) { // nothing to render @@ -466,22 +593,46 @@ const SelectPanelFooter = ({...props}) => { return ( -
-
+ + {props.children} -
+ {hidePrimaryActions ? null : ( -
+ -
+ )} -
+
) } @@ -491,19 +642,30 @@ const SecondaryButton: React.FC = props => { return ) } -const SecondaryCheckbox: React.FC = ({id, children, ...props}) => { +const SecondaryCheckbox: React.FC = ({id, children, className, ...props}) => { const checkboxId = useId(id) const {selectionVariant} = React.useContext(SelectPanelContext) + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) // Checkbox should not be used with instant selection invariant( @@ -512,12 +674,24 @@ const SecondaryCheckbox: React.FC = ({id, children, ...props}) => ) return ( -
- - + + + {children} -
+ ) } @@ -541,10 +715,34 @@ const SelectPanelSecondaryAction: React.FC = ({ } const SelectPanelLoading = ({children = 'Fetching items...'}: React.PropsWithChildren) => { + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + return ( - + - {children} + + {children} + ) } @@ -568,33 +766,99 @@ const SelectPanelMessage: React.FC = ({ title, children, }) => { + const enabled = useFeatureFlag(CSS_MODULES_FEATURE_FLAG) + if (size === 'full') { return ( -
+ {variant !== 'empty' ? ( ) : null} - {title} - {children} -
+ + {title} + + + {children} + + ) } else { + const inlineVariantStyles = { + empty: {}, + warning: { + backgroundColor: 'attention.subtle', + color: 'attention.fg', + borderBottomColor: 'attention.muted', + }, + error: { + backgroundColor: 'danger.subtle', + color: 'danger.fg', + borderColor: 'danger.muted', + }, + } + return ( -
-
{children}
-
+ {children} + ) } } From 09de06044be55a3b4d844861a66699041138418e Mon Sep 17 00:00:00 2001 From: Hussam Ghazzi Date: Fri, 22 Nov 2024 19:27:51 +0000 Subject: [PATCH 6/6] update order --- .../experimental/SelectPanel2/SelectPanel.tsx | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx index a0501ebe826..6cffe9375e3 100644 --- a/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx +++ b/packages/react/src/experimental/SelectPanel2/SelectPanel.tsx @@ -6,13 +6,13 @@ import { Button, IconButton, Heading, + Box, TextInput, Spinner, Text, Link, Checkbox, useFormControlForwardedProps, - Box, } from '../../index' import Octicon from '../../Octicon' import {ActionListContainerContext} from '../../ActionList/ActionListContainerContext' @@ -25,11 +25,11 @@ import {invariant} from '../../utils/invariant' import {AriaStatus} from '../../live-region' import {useResponsiveValue} from '../../hooks/useResponsiveValue' import type {ResponsiveValue} from '../../hooks/useResponsiveValue' - -import classes from './SelectPanel.module.css' import {clsx} from 'clsx' import {useFeatureFlag} from '../../FeatureFlags' +import classes from './SelectPanel.module.css' + const CSS_MODULES_FEATURE_FLAG = 'primer_react_css_modules_team' const SelectPanelContext = React.createContext<{ @@ -258,16 +258,6 @@ const Panel: React.FC = ({ height="fit-content" maxHeight={maxHeight} data-variant={currentVariant} - style={ - enabled - ? ({ - '--max-height': maxHeightValue, - '--position-top': `${position?.top ?? 0}px`, - '--position-left': `${position?.left ?? 0}px`, - } as React.CSSProperties) - : undefined - } - className={enabled ? classes.Overlay : undefined} sx={ enabled ? undefined @@ -313,6 +303,16 @@ const Panel: React.FC = ({ }, } } + style={ + enabled + ? ({ + '--max-height': maxHeightValue, + '--position-top': `${position?.top ?? 0}px`, + '--position-left': `${position?.left ?? 0}px`, + } as React.CSSProperties) + : undefined + } + className={enabled ? classes.Overlay : undefined} {...props} onClick={event => { if (event.target === event.currentTarget) onClickOutside()