Skip to content

Commit

Permalink
fix(types): more precise types for class bindings (#8012)
Browse files Browse the repository at this point in the history
  • Loading branch information
basil-gor authored Nov 10, 2023
1 parent fa65cb6 commit 46e3374
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 1 deletion.
36 changes: 36 additions & 0 deletions packages/dts-test/tsx.test-d.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,42 @@ expectType<JSX.Element>(
<div style={[{ color: 'red' }, [{ fontSize: '1em' }]]} />
)

// allow undefined, string, object, array and nested array classes
expectType<JSX.Element>(<div class={undefined} />)
expectType<JSX.Element>(<div class={'foo'} />)
expectType<JSX.Element>(<div class={['foo', undefined, 'bar']} />)
expectType<JSX.Element>(<div class={[]} />)
expectType<JSX.Element>(<div class={['foo', ['bar'], [['baz']]]} />)
expectType<JSX.Element>(<div class={{ foo: true, bar: false, baz: true }} />)
expectType<JSX.Element>(<div class={{}} />)
expectType<JSX.Element>(
<div class={['foo', ['bar'], { baz: true }, [{ qux: true }]]} />
)
expectType<JSX.Element>(
<div
class={[
{ foo: false },
{ bar: 0 },
{ baz: -0 },
{ qux: '' },
{ quux: null },
{ corge: undefined },
{ grault: NaN }
]}
/>
)
expectType<JSX.Element>(
<div
class={[
{ foo: true },
{ bar: 'not-empty' },
{ baz: 1 },
{ qux: {} },
{ quux: [] }
]}
/>
)

// #7955
expectType<JSX.Element>(<div style={[undefined, '', null, false]} />)

Expand Down
8 changes: 7 additions & 1 deletion packages/runtime-dom/src/jsx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,10 +252,16 @@ export type StyleValue =
| CSSProperties
| Array<StyleValue>

export type ClassValue =
| undefined
| string
| Record<string | number, unknown>
| Array<ClassValue>

export interface HTMLAttributes extends AriaAttributes, EventHandlers<Events> {
innerHTML?: string

class?: any
class?: ClassValue
style?: StyleValue

// Standard HTML Attributes
Expand Down
48 changes: 48 additions & 0 deletions packages/shared/__tests__/normalizeProp.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { normalizeClass, parseStringStyle } from '../src'

describe('normalizeClass', () => {
test('handles undefined correctly', () => {
expect(normalizeClass(undefined)).toEqual('')
})

test('handles string correctly', () => {
expect(normalizeClass('foo')).toEqual('foo')
})
Expand All @@ -11,12 +15,56 @@ describe('normalizeClass', () => {
)
})

test('handles empty array correctly', () => {
expect(normalizeClass([])).toEqual('')
})

test('handles nested array correctly', () => {
expect(normalizeClass(['foo', ['bar'], [['baz']]])).toEqual('foo bar baz')
})

test('handles object correctly', () => {
expect(normalizeClass({ foo: true, bar: false, baz: true })).toEqual(
'foo baz'
)
})

test('handles empty object correctly', () => {
expect(normalizeClass({})).toEqual('')
})

test('handles arrays and objects correctly', () => {
expect(
normalizeClass(['foo', ['bar'], { baz: true }, [{ qux: true }]])
).toEqual('foo bar baz qux')
})

test('handles array of objects with falsy values', () => {
expect(
normalizeClass([
{ foo: false },
{ bar: 0 },
{ baz: -0 },
{ qux: '' },
{ quux: null },
{ corge: undefined },
{ grault: NaN }
])
).toEqual('')
})

test('handles array of objects with truthy values', () => {
expect(
normalizeClass([
{ foo: true },
{ bar: 'not-empty' },
{ baz: 1 },
{ qux: {} },
{ quux: [] }
])
).toEqual('foo bar baz qux quux')
})

// #6777
test('parse multi-line inline style', () => {
expect(
Expand Down

0 comments on commit 46e3374

Please sign in to comment.