mirror of
https://github.com/supabase/supabase.git
synced 2026-09-06 18:11:51 +08:00
## What kind of change does this PR introduce? Bug fix and internal tooling update. Resolves FE-3472. ## What is the current behavior? Custom Studio icons use inconsistent source stroke widths, and some child-level styling prevents component props from overriding them. Mixed custom and Lucide icon sets can therefore appear uneven. ## What is the new behavior? Custom stroke icons use a root-level `stroke-width="1.5"`; fill-only logos use `stroke="none"`. The build validates that contract and regenerated components preserve existing exports and props. Studio applies the same `1.5` weight across Reports categories and uses one shared destination icon mapping in the replication selector, destination rows and diagram. | Before | After | | --- | --- | | <img width="418" height="516" alt="56398" src="https://github.com/user-attachments/assets/6afa7042-e6be-40e7-9911-af2f61238c9d" /> | <img width="390" height="550" alt="CleanShot 2026-07-30 at 17 12 37@2x" src="https://github.com/user-attachments/assets/870f49cf-c8fa-40db-8be8-2eb5f264ff4a" /> | | <img width="510" height="734" alt="CleanShot 2026-07-30 at 17 19 28@2x" src="https://github.com/user-attachments/assets/a5b2c088-dcd2-4907-976b-5820794d06e3" /> | <img width="554" height="742" alt="CleanShot 2026-07-30 at 17 16 06@2x" src="https://github.com/user-attachments/assets/ed3a77c4-5d94-4ca7-b9e4-1403b725a981" /> | ## Testing At 100% zoom, compare custom and Lucide icon weight in: - Reports: **Add your first chart** and **Add block** - Database > Replication: the destination selector, destination rows and replication diagram - Command menu (`⌘K`): **Search Database Tables**, **Search RLS Policies**, **Search Edge Functions** and **Search Storage** - Authentication > Users: right-click a user row and compare the context-menu icons - Database > Schema Visualizer: open a table node overflow menu - A paused project: **Export your data > Download backups** <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added consistent destination icons across replication panels, rows, and diagrams. * Updated instance health and metric icons for clearer identification. * Standardized icon stroke weight and reduced default icon stroke thickness. * **Documentation** * Clarified custom icon requirements, default properties, and validation guidance. * **Bug Fixes** * Improved consistency of icon rendering across replication destinations and reports. * **Tests** * Added coverage for icon SVG validation and replication destination icon rendering. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
|
|
import { validateIconSource } from './validateIcons.mjs'
|
|
|
|
test('accepts a canonical stroke icon', () => {
|
|
const source = `
|
|
<svg fill="none" stroke="currentColor" stroke-width="1.5">
|
|
<path d="M2 2L22 22" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source), [])
|
|
})
|
|
|
|
test('accepts a fill-only icon', () => {
|
|
const source = `
|
|
<svg fill="none" stroke="none">
|
|
<path d="M2 2H22V22H2Z" fill="currentColor" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source), [])
|
|
})
|
|
|
|
test('rejects a non-canonical stroke width', () => {
|
|
const source = `
|
|
<svg fill="none" stroke="currentColor" stroke-width="1">
|
|
<path d="M2 2L22 22" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source, 'thin.svg'), [
|
|
'thin.svg: stroke icons must use stroke-width="1.5" on the root <svg>',
|
|
])
|
|
})
|
|
|
|
test('rejects child-level stroke styling', () => {
|
|
const source = `
|
|
<svg fill="none" stroke="currentColor" stroke-width="1.5">
|
|
<path d="M2 2L22 22" stroke="currentColor" stroke-width="1.5" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source, 'fixed.svg'), [
|
|
'fixed.svg: move shared stroke, stroke-width attributes to the root <svg>',
|
|
])
|
|
})
|
|
|
|
test('rejects inline styles on the root icon', () => {
|
|
const source = `
|
|
<svg fill="none" stroke="currentColor" stroke-width="1.5" style="stroke: none">
|
|
<path d="M2 2L22 22" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source, 'root-style.svg'), [
|
|
'root-style.svg: inline style attributes are not allowed on the root <svg>',
|
|
])
|
|
})
|
|
|
|
test('rejects inline styles on child elements', () => {
|
|
const source = `
|
|
<svg fill="none" stroke="currentColor" stroke-width="1.5">
|
|
<path d="M2 2L22 22" style="stroke-width: 2" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source, 'child-style.svg'), [
|
|
'child-style.svg: inline style attributes are not allowed on child elements',
|
|
])
|
|
})
|
|
|
|
test('rejects the legacy zero-width fill-only convention', () => {
|
|
const source = `
|
|
<svg fill="currentColor" stroke="currentColor" stroke-width="0">
|
|
<path d="M2 2H22V22H2Z" />
|
|
</svg>
|
|
`
|
|
|
|
assert.deepEqual(validateIconSource(source, 'logo.svg'), [
|
|
'logo.svg: stroke icons must use fill="none" on the root <svg>',
|
|
'logo.svg: stroke icons must use stroke-width="1.5" on the root <svg>',
|
|
])
|
|
})
|