Skip to content

Commit b7b2076

Browse files
authored
Merge branch 'main' into mp/rm-sx/misc-components
2 parents b9d3c4c + 3dfcf30 commit b7b2076

File tree

16 files changed

+236
-143
lines changed

16 files changed

+236
-143
lines changed

.changeset/lucky-facts-obey.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

contributor-docs/adrs/adr-007-experimental-components.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
## Status
44

5-
| Stage | Status |
6-
| -------- | ------ |
7-
| Approved ||
8-
| Adopted | 🚧 |
5+
| Stage | Status |
6+
| -------- | ------------------------------------------------------------------------------------ |
7+
| Approved | |
8+
| Adopted | [Abandoned](https://github.com/github/primer/issues/2534#issuecomment-3227363552) |
99

1010
 
1111

e2e/components/SelectPanel.test.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ const scenarios = matrix({
4040
id: 'components-selectpanel-dev--with-css',
4141
name: 'With Css',
4242
},
43-
{
44-
id: 'components-selectpanel-dev--with-sx',
45-
name: 'With Sx',
46-
},
47-
{
48-
id: 'components-selectpanel-dev--with-sx-and-css',
49-
name: 'With Sx and Css',
50-
},
5143
],
5244
})
5345

packages/react/src/ActionList/Description.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export const Description: React.FC<React.PropsWithChildren<ActionListDescription
6161
ref={containerRef}
6262
id={inlineDescriptionId}
6363
className={clsx(className, classes.Description)}
64+
sx={sx}
6465
title={effectiveTitle}
6566
inline={true}
6667
maxWidth="100%"

packages/react/src/FilteredActionList/FilteredActionList.module.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
.Root {
2+
display: flex;
3+
flex-direction: column;
4+
overflow: hidden;
5+
}
6+
17
.Container {
28
display: flex;
39
height: 100%;

packages/react/src/FilteredActionList/FilteredActionList.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import type {KeyboardEventHandler} from 'react'
44
import type React from 'react'
55
import {useCallback, useEffect, useRef, useState} from 'react'
66
import styled from 'styled-components'
7-
import Box from '../Box'
87
import type {TextInputProps} from '../TextInput'
98
import TextInput from '../TextInput'
109
import {get} from '../constants'
@@ -27,6 +26,7 @@ import {isValidElementType} from 'react-is'
2726
import {useAnnouncements} from './useAnnouncements'
2827
import {clsx} from 'clsx'
2928
import {useFeatureFlag} from '../FeatureFlags'
29+
import {BoxWithFallback} from '../internal/components/BoxWithFallback'
3030

3131
const menuScrollMargins: ScrollIntoViewOptions = {startMargin: 0, endMargin: 8}
3232

@@ -349,13 +349,10 @@ export function FilteredActionList({
349349
}
350350

351351
return (
352-
<Box
352+
<BoxWithFallback
353353
ref={inputAndListContainerRef}
354-
display="flex"
355-
flexDirection="column"
356-
overflow="hidden"
357354
sx={sx}
358-
className={className}
355+
className={clsx(className, classes.Root)}
359356
data-testid="filtered-action-list"
360357
>
361358
<StyledHeader>
@@ -399,7 +396,7 @@ export function FilteredActionList({
399396
<div ref={scrollContainerRef} className={classes.Container}>
400397
{getBodyContent()}
401398
</div>
402-
</Box>
399+
</BoxWithFallback>
403400
)
404401
}
405402

packages/react/src/SelectPanel/SelectPanel.dev.stories.tsx

Lines changed: 68 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import {TriangleDownIcon} from '@primer/octicons-react'
22
import type {Meta} from '@storybook/react-vite'
33
import type React from 'react'
4-
import {useState} from 'react'
4+
import {useState, useEffect, useRef} from 'react'
55

6-
import Box from '../Box'
76
import {Button} from '../Button'
87
import {SelectPanel} from '.'
98
import type {ItemInput} from '../deprecated/ActionList/List'
109
import FormControl from '../FormControl'
1110
import Text from '../Text'
1211
import Select from '../Select/Select'
1312
import type {SelectPanelSecondaryAction} from './SelectPanel'
13+
import classes from './SelectPanel.stories.module.css'
1414

1515
const meta: Meta<typeof SelectPanel> = {
1616
title: 'Components/SelectPanel/Dev',
@@ -30,16 +30,11 @@ const NoResultsMessage = (filter: string): {variant: 'empty'; title: string; bod
3030
function getColorCircle(color: string) {
3131
return function () {
3232
return (
33-
<Box
34-
sx={{
33+
<div
34+
className={classes.ColorCircle}
35+
style={{
3536
backgroundColor: color,
3637
borderColor: color,
37-
width: 14,
38-
height: 14,
39-
borderRadius: 10,
40-
margin: 'auto',
41-
borderWidth: '1px',
42-
borderStyle: 'solid',
4338
}}
4439
/>
4540
)
@@ -113,85 +108,6 @@ export const WithCss = () => {
113108
)
114109
}
115110

116-
export const WithSx = () => {
117-
const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))
118-
const [filter, setFilter] = useState('')
119-
const filteredItems = items.filter(item => item.text?.toLowerCase().startsWith(filter.toLowerCase()))
120-
// design guidelines say to sort selected items first
121-
const selectedItemsSortedFirst = filteredItems.sort((a, b) => {
122-
const aIsSelected = selected.some(selectedItem => selectedItem.text === a.text)
123-
const bIsSelected = selected.some(selectedItem => selectedItem.text === b.text)
124-
if (aIsSelected && !bIsSelected) return -1
125-
if (!aIsSelected && bIsSelected) return 1
126-
return 0
127-
})
128-
const [open, setOpen] = useState(false)
129-
130-
return (
131-
<FormControl>
132-
<FormControl.Label>Labels</FormControl.Label>
133-
<SelectPanel
134-
title="Select labels"
135-
placeholder="Select labels" // button text when no items are selected
136-
subtitle="Use labels to organize issues and pull requests"
137-
renderAnchor={({children, ...anchorProps}) => (
138-
<Button trailingAction={TriangleDownIcon} {...anchorProps} aria-haspopup="dialog">
139-
{children}
140-
</Button>
141-
)}
142-
open={open}
143-
onOpenChange={setOpen}
144-
items={selectedItemsSortedFirst}
145-
selected={selected}
146-
onSelectedChange={setSelected}
147-
onFilterChange={setFilter}
148-
sx={{fontFamily: 'Times New Roman'}}
149-
message={selectedItemsSortedFirst.length === 0 ? NoResultsMessage(filter) : undefined}
150-
/>
151-
</FormControl>
152-
)
153-
}
154-
155-
export const WithSxAndCSS = () => {
156-
const [selected, setSelected] = useState<ItemInput[]>(items.slice(1, 3))
157-
const [filter, setFilter] = useState('')
158-
const filteredItems = items.filter(item => item.text?.toLowerCase().startsWith(filter.toLowerCase()))
159-
// design guidelines say to sort selected items first
160-
const selectedItemsSortedFirst = filteredItems.sort((a, b) => {
161-
const aIsSelected = selected.some(selectedItem => selectedItem.text === a.text)
162-
const bIsSelected = selected.some(selectedItem => selectedItem.text === b.text)
163-
if (aIsSelected && !bIsSelected) return -1
164-
if (!aIsSelected && bIsSelected) return 1
165-
return 0
166-
})
167-
const [open, setOpen] = useState(false)
168-
169-
return (
170-
<FormControl>
171-
<FormControl.Label>Labels</FormControl.Label>
172-
<SelectPanel
173-
title="Select labels"
174-
placeholder="Select labels" // button text when no items are selected
175-
subtitle="Use labels to organize issues and pull requests"
176-
renderAnchor={({children, ...anchorProps}) => (
177-
<Button trailingAction={TriangleDownIcon} {...anchorProps} aria-haspopup="dialog">
178-
{children}
179-
</Button>
180-
)}
181-
open={open}
182-
onOpenChange={setOpen}
183-
items={selectedItemsSortedFirst}
184-
selected={selected}
185-
onSelectedChange={setSelected}
186-
onFilterChange={setFilter}
187-
sx={{fontFamily: 'Times New Roman'}}
188-
className="testCustomClassnameMono"
189-
message={selectedItemsSortedFirst.length === 0 ? NoResultsMessage(filter) : undefined}
190-
/>
191-
</FormControl>
192-
)
193-
}
194-
195111
const simpleItems = [
196112
{leadingVisual: getColorCircle('#a2eeef'), text: 'enhancement', id: 1},
197113
{leadingVisual: getColorCircle('#d73a4a'), text: 'bug', id: 2},
@@ -406,3 +322,66 @@ export const AllVariants = () => {
406322
</>
407323
)
408324
}
325+
326+
const NUMBER_OF_ITEMS = 500
327+
const lotsOfItems = Array.from({length: NUMBER_OF_ITEMS}, (_, index) => {
328+
return {
329+
id: index,
330+
text: `Item ${index}`,
331+
description: `Description ${index}`,
332+
leadingVisual: getColorCircle('#a2eeef'),
333+
}
334+
})
335+
336+
export const LotsOfItems = () => {
337+
const [selected, setSelected] = useState<ItemInput[]>([])
338+
const [filter, setFilter] = useState('')
339+
const filteredItems = lotsOfItems.filter(item => item.text.toLowerCase().startsWith(filter.toLowerCase()))
340+
const [open, setOpen] = useState(false)
341+
const timeBeforeOpen = useRef<number>()
342+
const timeAfterOpen = useRef<number>()
343+
const [timeTakenToOpen, setTimeTakenToOpen] = useState<number>()
344+
345+
const onOpenChange = () => {
346+
timeBeforeOpen.current = performance.now()
347+
setOpen(!open)
348+
}
349+
350+
useEffect(() => {
351+
if (open) {
352+
timeAfterOpen.current = performance.now()
353+
if (timeBeforeOpen.current) setTimeTakenToOpen(timeAfterOpen.current - timeBeforeOpen.current)
354+
}
355+
}, [open])
356+
357+
return (
358+
<>
359+
<p>
360+
Time taken to render {NUMBER_OF_ITEMS} items: {timeTakenToOpen || '(click "Select Labels" to open)'}
361+
</p>
362+
363+
<FormControl>
364+
<FormControl.Label>Labels</FormControl.Label>
365+
<SelectPanel
366+
title="Select labels"
367+
placeholder="Select labels"
368+
subtitle="Use labels to organize issues and pull requests"
369+
renderAnchor={({children, ...anchorProps}) => (
370+
<Button trailingAction={TriangleDownIcon} {...anchorProps} aria-haspopup="dialog">
371+
{children}
372+
</Button>
373+
)}
374+
open={open}
375+
onOpenChange={onOpenChange}
376+
items={filteredItems}
377+
selected={selected}
378+
onSelectedChange={setSelected}
379+
onFilterChange={setFilter}
380+
width="medium"
381+
height="large"
382+
message={filteredItems.length === 0 ? NoResultsMessage(filter) : undefined}
383+
/>
384+
</FormControl>
385+
</>
386+
)
387+
}

packages/react/src/SelectPanel/SelectPanel.examples.stories.module.css

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,3 @@
1919
outline: 2px solid var(--focus-outlineColor, var(--color-accent-emphasis));
2020
outline-offset: -2px;
2121
}
22-
23-
.TruncatedText {
24-
overflow: hidden;
25-
white-space: nowrap;
26-
text-overflow: ellipsis;
27-
}

0 commit comments

Comments
 (0)