Skip to content

Commit bbb367a

Browse files
committed
slimmer output by ensuring defaults are not printed, again
1 parent 01e907d commit bbb367a

1 file changed

Lines changed: 70 additions & 17 deletions

File tree

src/utils/gradientString.ts

Lines changed: 70 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import Color from 'colorjs.io'
2-
import { linearAngleToString } from './linear'
32
import { isCylindricalSpace } from './colorspace'
43

54
export type LayerSnapshot = {
@@ -19,23 +18,33 @@ function spaceToString(space: string, interpolation: string) {
1918
}
2019

2120
function radialPositionToString(radial: LayerSnapshot['radial']) {
21+
const named = (radial as any).named_position
22+
if (named && named !== '--') {
23+
if (named === 'center') return ''
24+
return named
25+
}
2226
if (radial.position?.x != null) {
27+
const x = radial.position.x
2328
const y = radial.position.y ?? '50'
24-
return radial.position.x + '% ' + y + '%'
25-
}
26-
else {
27-
return radial.named_position
29+
if (String(x) === '50' && String(y) === '50') return ''
30+
return x + '% ' + y + '%'
2831
}
32+
return ''
2933
}
3034

3135
function conicPositionToString(conic: LayerSnapshot['conic']) {
36+
const named = (conic as any).named_position
37+
if (named && named !== '--') {
38+
if (named === 'center') return ''
39+
return named
40+
}
3241
if (conic.position?.x != null) {
42+
const x = conic.position.x
3343
const y = conic.position.y ?? '50'
34-
return conic.position.x + '% ' + y + '%'
35-
}
36-
else {
37-
return conic.named_position
44+
if (String(x) === '50' && String(y) === '50') return ''
45+
return x + '% ' + y + '%'
3846
}
47+
return ''
3948
}
4049

4150
function maybeConvertColor(color: string, convert_colors?: boolean) {
@@ -74,14 +83,23 @@ function stopsToStrings(stops: any[], { convert_colors, new_lines }: { convert_c
7483
return !!(m && Number(m[1]) === 100)
7584
}
7685

86+
function isPctFifty(p: any) {
87+
if (p == null) return false
88+
const m = String(p).match(/^(-?\d+(?:\.\d+)?)%$/)
89+
return !!(m && Number(m[1]) === 50)
90+
}
91+
7792
return stops
7893
.map((s, i) => {
7994
if (s.kind === 'stop') {
8095
let p1 = s.position1
8196
let p2 = s.position2
8297

98+
// If position equals computed auto position, omit it
8399
if (p1 != null && s.auto != null && p1 == s.auto) p1 = null
100+
if (p2 != null && s.auto != null && p2 == s.auto) p2 = null
84101

102+
// Omit default endpoints
85103
if (i === firstStopIdx && isPctZero(p1)) p1 = null
86104
if (i === lastStopIdx && isPctHundred(p2)) p2 = null
87105

@@ -105,36 +123,71 @@ function stopsToStrings(stops: any[], { convert_colors, new_lines }: { convert_c
105123
return maybeConvertColor(s.color, convert_colors)
106124
}
107125
else if (s.kind === 'hint') {
108-
if (s.percentage == null) return null
109-
return s.percentage + '%'
126+
// Omit default/auto hints (like 50%)
127+
const pct = s.percentage
128+
if (pct == null) return null
129+
if (s.auto != null && String(pct) == String(s.auto)) return null
130+
if (isPctFifty(pct)) return null
131+
return pct + '%'
110132
}
111133
return null
112134
})
113135
.filter(Boolean)
114136
.join(new_lines === true ? ',\n ' : ', ')
115137
}
116138

139+
function linearAngleToken(linear: LayerSnapshot['linear']) {
140+
// Omit default 'to bottom' or 180deg
141+
const named = linear.named_angle
142+
const ang = linear.angle
143+
if (named && named !== '--') {
144+
if (named === 'to bottom') return ''
145+
return named
146+
}
147+
if (ang != null) {
148+
const n = Number(ang)
149+
if (!Number.isNaN(n) && (n % 360 === 180)) return ''
150+
return String(ang) + 'deg'
151+
}
152+
return ''
153+
}
154+
117155
function modernString(layer: LayerSnapshot) {
118156
if (layer.type === 'linear') {
119-
return `linear-gradient(\n ${linearAngleToString(layer.linear.angle as any, layer.linear.named_angle as any)} ${spaceToString(layer.space, layer.interpolation)},\n ${stopsToStrings(layer.stops, { new_lines: false })}\n )`
157+
const tokens = [linearAngleToken(layer.linear), spaceToString(layer.space, layer.interpolation)].filter(Boolean).join(' ')
158+
return `linear-gradient(\n ${tokens},\n ${stopsToStrings(layer.stops, { new_lines: false })}\n )`
120159
}
121160
else if (layer.type === 'radial') {
122-
return `radial-gradient(\n ${layer.radial.size} ${layer.radial.shape} at ${radialPositionToString(layer.radial)} ${spaceToString(layer.space, layer.interpolation)},\n ${stopsToStrings(layer.stops, { new_lines: false })}\n )`
161+
const pos = radialPositionToString(layer.radial)
162+
const posPart = pos && pos !== 'center' ? 'at ' + pos : ''
163+
const tokens = [layer.radial.size, layer.radial.shape, posPart, spaceToString(layer.space, layer.interpolation)].filter(Boolean).join(' ')
164+
return `radial-gradient(\n ${tokens},\n ${stopsToStrings(layer.stops, { new_lines: false })}\n )`
123165
}
124166
else {
125-
return `conic-gradient(\n from ${layer.conic.angle}deg at ${conicPositionToString(layer.conic)} ${spaceToString(layer.space, layer.interpolation)},\n ${stopsToStrings(layer.stops, { new_lines: false })}\n )`
167+
const pos = conicPositionToString(layer.conic)
168+
const posPart = pos && pos !== 'center' ? 'at ' + pos : ''
169+
const fromPart = (Number(layer.conic.angle) || 0) % 360 === 0 ? '' : `from ${layer.conic.angle}deg`
170+
const tokens = [fromPart, posPart, spaceToString(layer.space, layer.interpolation)].filter(Boolean).join(' ')
171+
return `conic-gradient(\n ${tokens},\n ${stopsToStrings(layer.stops, { new_lines: false })}\n )`
126172
}
127173
}
128174

129175
function classicString(layer: LayerSnapshot) {
130176
if (layer.type === 'linear') {
131-
return `linear-gradient(${linearAngleToString(layer.linear.angle as any, layer.linear.named_angle as any)}, ${stopsToStrings(layer.stops, { convert_colors: true, new_lines: false })})`
177+
const angleToken = linearAngleToken(layer.linear)
178+
const header = angleToken ? angleToken + ', ' : ''
179+
return `linear-gradient(${header}${stopsToStrings(layer.stops, { convert_colors: true, new_lines: false })})`
132180
}
133181
else if (layer.type === 'radial') {
134-
return `radial-gradient(\n ${layer.radial.size} ${layer.radial.shape} at ${radialPositionToString(layer.radial)},\n ${stopsToStrings(layer.stops, { convert_colors: true, new_lines: false })}\n )`
182+
const pos = radialPositionToString(layer.radial)
183+
const posPart = pos && pos !== 'center' ? ' at ' + pos : ''
184+
return `radial-gradient(${layer.radial.size} ${layer.radial.shape}${posPart}, ${stopsToStrings(layer.stops, { convert_colors: true, new_lines: false })})`
135185
}
136186
else {
137-
return `conic-gradient(\n from ${layer.conic.angle}deg at ${conicPositionToString(layer.conic)},\n ${stopsToStrings(layer.stops, { convert_colors: true, new_lines: false })}\n )`
187+
const pos = conicPositionToString(layer.conic)
188+
const posPart = pos && pos !== 'center' ? ' at ' + pos : ''
189+
const fromPart = (Number(layer.conic.angle) || 0) % 360 === 0 ? '' : `from ${layer.conic.angle}deg `
190+
return `conic-gradient(${fromPart.trim()}${posPart}, ${stopsToStrings(layer.stops, { convert_colors: true, new_lines: false })})`
138191
}
139192
}
140193

0 commit comments

Comments
 (0)