Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/__tests__/panels/selectorsPanel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,21 @@ describe('SelectorsPanel', () => {
expect(within(panel).queryByRole('button', { name: /edit selector \.cta-button/i })).toBeNull()
})

it('filters to only used selectors', () => {
loadSiteWithSelectors()
render(<SelectorsPanel variant="docked" />)

const panel = screen.getByTestId('selectors-panel')
fireEvent.click(within(panel).getByRole('button', { name: /^used$/i }))

// hero-title and cta-button are referenced by page nodes; unused-card and
// text-m have no nodes referencing them.
expect(within(panel).getByRole('button', { name: /edit selector \.hero-title/i })).toBeDefined()
expect(within(panel).getByRole('button', { name: /edit selector \.cta-button/i })).toBeDefined()
expect(within(panel).queryByRole('button', { name: /edit selector \.unused-card/i })).toBeNull()
expect(within(panel).queryByRole('button', { name: /edit selector \.text-m/i })).toBeNull()
})

it('searches selector property names and values, not just names', () => {
loadSiteWithSelectors()
render(<SelectorsPanel variant="docked" />)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ interface SelectorsPanelProps {
variant?: 'docked'
}

type SelectorFilter = 'all' | 'user' | 'utility' | 'unused'
type SelectorFilter = 'all' | 'user' | 'utility' | 'used' | 'unused'

/**
* How many selector rows to mount per batch. A generated framework (e.g. the
Expand All @@ -55,6 +55,7 @@ const SELECTOR_FILTER_ITEMS: FilterBarItem<SelectorFilter>[] = [
{ value: 'all', label: 'All' },
{ value: 'user', label: 'User' },
{ value: 'utility', label: 'Utility' },
{ value: 'used', label: 'Used' },
{ value: 'unused', label: 'Unused' },
]

Expand All @@ -77,6 +78,7 @@ function getEmptyFilterMessage(filter: SelectorFilter, query: string): string {
if (normalized) return `No selectors match “${normalized}”.`
if (filter === 'user') return 'No user selectors yet.'
if (filter === 'utility') return 'No utility selectors yet.'
if (filter === 'used') return 'No used selectors yet.'
if (filter === 'unused') return 'No unused selectors — every selector is in use.'
return 'No selectors match the current filters.'
}
Expand Down Expand Up @@ -136,6 +138,8 @@ export function SelectorsPanel({ variant = 'docked' }: SelectorsPanelProps) {
const filteredClasses = reusableClasses.filter((cls) => {
if (filter === 'user' && isGeneratedClass(cls)) return false
if (filter === 'utility' && !isGeneratedClass(cls)) return false
if (filter === 'used' && resolveSelectorUsage(cls, usageMap, classTokenUsage).unused)
return false
if (filter === 'unused' && !resolveSelectorUsage(cls, usageMap, classTokenUsage).unused)
return false
// Search matches the selector name AND its declared CSS (property names and
Expand Down
Loading