Skip to content

Commit e895fa5

Browse files
authored
Merge pull request #2457 from system-ui/filter-scale-tuples
Filter scale tuples in Theme type inside .sx prop
2 parents 20e17a9 + 0a7330c commit e895fa5

File tree

15 files changed

+1447
-702
lines changed

15 files changed

+1447
-702
lines changed

.github/workflows/ci.yml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ jobs:
1313
build:
1414
runs-on: ubuntu-latest
1515
steps:
16-
- uses: actions/checkout@v3
16+
- uses: actions/checkout@v4
1717

1818
- uses: pnpm/action-setup@v2
1919
with:
20-
version: 7
20+
version: 8
2121

2222
- uses: actions/setup-node@v3
2323
with:
24-
node-version: 18.x
24+
node-version: 20.x
2525
cache: 'pnpm'
2626

2727
- name: Install
@@ -74,18 +74,18 @@ jobs:
7474
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
7575
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
7676
steps:
77-
- uses: actions/checkout@v3
78-
79-
- name: Prepare repository
80-
run: git fetch --unshallow --tags
77+
- uses: actions/checkout@v4
78+
with:
79+
fetch-depth: 100
80+
fetch-tags: true
8181

8282
- uses: pnpm/action-setup@v2
8383
with:
84-
version: 7
84+
version: 8
8585

8686
- uses: actions/setup-node@v3
8787
with:
88-
node-version: 18.x
88+
node-version: 20.x
8989
cache: 'pnpm'
9090
registry-url: 'https://registry.npmjs.org'
9191

@@ -105,6 +105,7 @@ jobs:
105105
# continue-on-error: true
106106
env:
107107
GITHUB_TOKEN: ${{ secrets.AUTO_RELEASE_GH_TOKEN }}
108+
BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
108109
run: pnpm release
109110

110111
- name: Check published prerelease

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@theme-ui/monorepo",
3-
"version": "0.16.1",
3+
"version": "0.16.2-scale-tuples.0",
44
"private": true,
55
"scripts": {
66
"build": "preconstruct build",

packages/components/src/Box.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
ArrayInterpolation,
33
CSSObject,
44
Interpolation,
5-
jsx,
65
useTheme,
76
} from '@emotion/react'
87
import React, { forwardRef } from 'react'
@@ -12,6 +11,7 @@ import {
1211
ThemeUICSSProperties,
1312
ThemeUIStyleObject,
1413
} from '@theme-ui/css'
14+
import { Theme } from '@theme-ui/core'
1515
import type { Assign, ForwardRef } from './types'
1616
import type { __ThemeUIComponentsInternalProps } from './util'
1717

@@ -59,7 +59,7 @@ export interface BoxOwnProps extends BoxSystemProps {
5959
as?: React.ElementType
6060
variant?: string
6161
css?: Interpolation<any>
62-
sx?: ThemeUIStyleObject
62+
sx?: ThemeUIStyleObject<Theme>
6363
}
6464

6565
export interface BoxProps

packages/core/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ export type {
2323
Scale,
2424
StylePropertyValue,
2525
TLengthStyledSystem,
26-
Theme,
2726
ThemeDerivedStyles,
2827
ThemeStyles,
2928
ThemeUICSSObject,

packages/core/src/types.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
import { Interpolation } from '@emotion/react'
2-
import { ThemeUIStyleObject, Theme as ThemeUITheme } from '@theme-ui/css'
2+
import {
3+
Scale,
4+
ScaleDict,
5+
ThemeUIStyleObject,
6+
Theme as ThemeUITheme,
7+
} from '@theme-ui/css'
8+
9+
export interface UserThemes {}
10+
11+
/** @internal */
12+
export type _UserTheme = UserThemes[keyof UserThemes]
13+
14+
/** Theme without array scales, so it's easier to read from inside of .sx prop */
15+
export type WidenedTheme = {
16+
[P in keyof ThemeUITheme]: ThemeUITheme[P] extends Scale<infer R> | undefined
17+
? ScaleDict<R>
18+
: ThemeUITheme[P]
19+
} & ThemeUITheme
20+
21+
export type Theme<TTheme = {}> = _UserTheme extends never
22+
? ThemeUITheme<TTheme>
23+
: _UserTheme
24+
25+
/** @internal */
26+
export type _JSXTheme = _UserTheme extends never ? WidenedTheme : _UserTheme
327

428
export interface SxProp {
529
/**
@@ -8,7 +32,7 @@ export interface SxProp {
832
*
933
* @see https://theme-ui.com/sx-prop/
1034
*/
11-
sx?: ThemeUIStyleObject
35+
sx?: ThemeUIStyleObject<_JSXTheme>
1236
/**
1337
* Theme UI uses Emotion's JSX function. You can pass styles to it directly
1438
* using `css` prop.

packages/core/test/react-jsx.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
*/
55
/* eslint-disable no-lone-blocks */
66
import { renderJSON, NotHas, Assert, expecter } from '@theme-ui/test-utils'
7+
import { matchers } from '@emotion/jest'
78

8-
import { SxProp, ThemeUIJSX } from '../src'
9+
import { SxProp, ThemeProvider, ThemeUIJSX } from '../src'
10+
11+
expect.extend(matchers)
912

1013
describe('JSX', () => {
1114
test('accepts sx prop', () => {
@@ -30,6 +33,24 @@ describe('JSX', () => {
3033
).toMatchSnapshot()
3134
})
3235

36+
test('sx prop gives a theme that can be read as array or object', () => {
37+
const json = renderJSON(
38+
<ThemeProvider
39+
theme={{ shadows: { small: '0 0 4px rgba(0, 0, 0, .125)' } }}
40+
>
41+
<div
42+
sx={(t) => ({
43+
boxShadow: t.shadows?.small,
44+
'&:hover': {
45+
boxShadow: t.shadows?.[2],
46+
},
47+
})}
48+
/>
49+
</ThemeProvider>
50+
)
51+
expect(json).toHaveStyleRule('box-shadow', '0 0 4px rgba(0, 0, 0, .125)')
52+
})
53+
3354
test('accepts css prop', () => {
3455
const expectSnippet = expecter(
3556
`/** @jsxImportSource ./packages/core */

packages/css/src/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,9 +305,12 @@ const transforms = [
305305
)
306306

307307
const responsive =
308-
(styles: Exclude<ThemeUIStyleObject, ThemeDerivedStyles>) =>
308+
(styles: Exclude<ThemeUIStyleObject<Theme>, ThemeDerivedStyles<Theme>>) =>
309309
(theme?: Theme) => {
310-
const next: Exclude<ThemeUIStyleObject, ThemeDerivedStyles> = {}
310+
const next: Exclude<
311+
ThemeUIStyleObject<Theme>,
312+
ThemeDerivedStyles<Theme>
313+
> = {}
311314
const breakpoints =
312315
(theme && (theme.breakpoints as string[])) || defaultBreakpoints
313316
const mediaQueries = [
@@ -348,12 +351,12 @@ const responsive =
348351
type CssPropsArgument = { theme: Theme } | Theme
349352

350353
export const css =
351-
(args: ThemeUIStyleObject = {}) =>
354+
<TTheme extends Theme<{}>>(args: ThemeUIStyleObject<TTheme> = {}) =>
352355
(props: CssPropsArgument = {}): CSSObject => {
353-
const theme: Theme = {
356+
const theme = {
354357
...defaultTheme,
355358
...('theme' in props ? props.theme : props),
356-
}
359+
} as TTheme
357360
// insert variant props before responsive styles, so they can be merged
358361
// we need to maintain order of the style props, so if a variant is place in the middle
359362
// of other props, it will extends its props at that same location order.

0 commit comments

Comments
 (0)