Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow easy styling autofilled of Inputs #1811

Merged
merged 4 commits into from
Jun 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ module.exports = {
rules: {
'no-use-before-define': 'off',
'react/react-in-jsx-scope': 'off',
'@typescript-eslint/no-redeclare': 'off',
},
}
2 changes: 1 addition & 1 deletion packages/color-modes/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export function useColorMode<T extends string = string>(): [
}

// We're allowing the user to specify a narrower type for its color mode name.
return ([colorMode, setColorMode] as unknown) as [
return [colorMode, setColorMode] as unknown as [
T,
Dispatch<SetStateAction<T>>
]
Expand Down
54 changes: 40 additions & 14 deletions packages/components/src/Input.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,52 @@
import React from 'react'
import Box from './Box'

export const Input = React.forwardRef(function Input(props, ref) {
import { get } from '@theme-ui/css'

/** @type {import('theme-ui').ThemeUIStyleObject} */
const autofillStyles = {
boxShadow: 'inset 0 0 0 1000px var(--theme-ui-input-autofill-bg)',
fontSize: 'inherit',
':first-line': {
fontSize: '1rem',
},
}

/** @type {import('theme-ui').ThemeUIStyleObject} */
const defaultInputStyles = {
display: 'block',
width: '100%',
p: 2,
appearance: 'none',
fontSize: 'inherit',
lineHeight: 'inherit',
border: '1px solid',
borderRadius: 4,
color: 'inherit',
bg: 'transparent',

':autofill, :autofill:hover, :autofill:focus': autofillStyles,
':-webkit-autofill, :-webkit-autofill:hover, :-webkit-autofill:focus':
autofillStyles,
}

export const Input = React.forwardRef(function Input(
{ sx, autofillBackgroundColor = 'background', ...rest },
lachlanjc marked this conversation as resolved.
Show resolved Hide resolved
ref
) {
return (
<Box
ref={ref}
as="input"
variant="input"
{...props}
__themeKey="forms"
__css={{
display: 'block',
width: '100%',
p: 2,
appearance: 'none',
fontSize: 'inherit',
lineHeight: 'inherit',
border: '1px solid',
borderRadius: 4,
color: 'inherit',
bg: 'transparent',
sx={{
'--theme-ui-input-autofill-bg': (theme) =>
get(theme.colors, autofillBackgroundColor, null),
...sx,
}}
{...rest}
__themeKey="forms"
__css={defaultInputStyles}
/>
)
})
78 changes: 78 additions & 0 deletions packages/components/test/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,32 @@ exports[`Field renders 1`] = `
background-color: transparent;
}

.emotion-2:autofill,
.emotion-2:autofill:hover,
.emotion-2:autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-2:autofill:first-line,
.emotion-2:autofill:hover:first-line,
.emotion-2:autofill:focus:first-line {
font-size: 1rem;
}

.emotion-2:-webkit-autofill,
.emotion-2:-webkit-autofill:hover,
.emotion-2:-webkit-autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-2:-webkit-autofill:first-line,
.emotion-2:-webkit-autofill:hover:first-line,
.emotion-2:-webkit-autofill:focus:first-line {
font-size: 1rem;
}

<div
className="emotion-0"
>
Expand Down Expand Up @@ -666,6 +692,32 @@ exports[`Field renders with id prop 1`] = `
background-color: transparent;
}

.emotion-2:autofill,
.emotion-2:autofill:hover,
.emotion-2:autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-2:autofill:first-line,
.emotion-2:autofill:hover:first-line,
.emotion-2:autofill:focus:first-line {
font-size: 1rem;
}

.emotion-2:-webkit-autofill,
.emotion-2:-webkit-autofill:hover,
.emotion-2:-webkit-autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-2:-webkit-autofill:first-line,
.emotion-2:-webkit-autofill:hover:first-line,
.emotion-2:-webkit-autofill:focus:first-line {
font-size: 1rem;
}

<div
className="emotion-0"
>
Expand Down Expand Up @@ -947,6 +999,32 @@ exports[`Input renders 1`] = `
background-color: transparent;
}

.emotion-0:autofill,
.emotion-0:autofill:hover,
.emotion-0:autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-0:autofill:first-line,
.emotion-0:autofill:hover:first-line,
.emotion-0:autofill:focus:first-line {
font-size: 1rem;
}

.emotion-0:-webkit-autofill,
.emotion-0:-webkit-autofill:hover,
.emotion-0:-webkit-autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-0:-webkit-autofill:first-line,
.emotion-0:-webkit-autofill:hover:first-line,
.emotion-0:-webkit-autofill:focus:first-line {
font-size: 1rem;
}

<input
className="emotion-0"
/>
Expand Down
7 changes: 6 additions & 1 deletion packages/docs/src/components/head.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ export default (props) => {
.filter(Boolean)
.join(' – ')

const { theme } = useThemeUI()
const { theme, colorMode } = useThemeUI()

const isColorModeDark = ['dark', 'deep'].includes(colorMode)

return (
<Helmet htmlAttributes={{ lang: 'en-US' }}>
Expand All @@ -32,7 +34,10 @@ export default (props) => {
<meta name="twitter:image" content="https://theme-ui.com/card.png" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={pkg.description} />

<meta name="theme-color" content={theme.colors.background} />
<meta name="color-scheme" content={isColorModeDark ? 'dark' : 'light'} />

<script
src="https://unpkg.com/favicon-switcher@1.2.2/dist/index.js"
crossOrigin="anonymous"
Expand Down
12 changes: 11 additions & 1 deletion packages/docs/src/pages/components/input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,14 @@ import { Input } from 'theme-ui'

## Variants

Input variants can be defined in `theme.forms` and the component uses the `theme.forms.input` variant by default.
Input variants can be defined in `theme.forms` and the component uses the
`theme.forms.input` variant by default.

## Autocomplete styles

Background color of autofilled inputs defaults to `background`, and can be
changed by setting `autofillBackgroundColor` prop.

```js live=true
<Input autoComplete="given-name" autofillBackgroundColor="highlight" />
```
9 changes: 5 additions & 4 deletions packages/docs/src/pages/components/select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import { Select, Box } from 'theme-ui'
</Select>
```

## Variants

Select variants can be defined in `theme.forms` and the component uses the
`theme.forms.select` variant by default.

## Custom arrow icon

```jsx live=true
Expand Down Expand Up @@ -46,7 +51,3 @@ import { Select, Box } from 'theme-ui'
<option>Boop</option>
</Select>
```

## Variants

Select variants can be defined in `theme.forms` and the component uses the `theme.forms.select` variant by default.
26 changes: 26 additions & 0 deletions packages/editor/test/__snapshots__/Combobox.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,32 @@ exports[`renders 1`] = `
background-color: transparent;
}

.emotion-3:autofill,
.emotion-3:autofill:hover,
.emotion-3:autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-3:autofill:first-line,
.emotion-3:autofill:hover:first-line,
.emotion-3:autofill:focus:first-line {
font-size: 1rem;
}

.emotion-3:-webkit-autofill,
.emotion-3:-webkit-autofill:hover,
.emotion-3:-webkit-autofill:focus {
box-shadow: inset 0 0 0 1000px var(--theme-ui-input-autofill-bg);
font-size: inherit;
}

.emotion-3:-webkit-autofill:first-line,
.emotion-3:-webkit-autofill:hover:first-line,
.emotion-3:-webkit-autofill:focus:first-line {
font-size: 1rem;
}

.emotion-4 {
-webkit-appearance: none;
-moz-appearance: none;
Expand Down
20 changes: 10 additions & 10 deletions packages/theme-ui/test/color-modes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ test('converts color modes to css custom properties', () => {
test('uses default mode', () => {
let mode
const Button = () => {
const [colorMode, setMode] = useColorMode()
const [colorMode] = useColorMode()
mode = colorMode
return <button children="test" />
}
const tree = render(
render(
<ThemeProvider theme={{}}>
<Button />
</ThemeProvider>
Expand All @@ -209,11 +209,11 @@ test('initializes mode based on localStorage', () => {
window.localStorage.setItem(STORAGE_KEY, 'dark')
let mode
const Button = () => {
const [colorMode, setMode] = useColorMode()
const [colorMode] = useColorMode()
mode = colorMode
return <button children="test" />
}
const tree = render(
render(
<ThemeProvider theme={{}}>
<Button />
</ThemeProvider>
Expand Down Expand Up @@ -351,7 +351,7 @@ test('does not initialize mode from prefers-color-scheme media query when useCol
test('useColorMode throws when there is no theme context', () => {
expect(() => {
const Consumer = () => {
const _ = useColorMode()
useColorMode()
return null
}
render(<Consumer />)
Expand All @@ -367,7 +367,7 @@ test('useThemeUI returns current color mode colors', () => {
colors = theme.colors
return null
}
const root = render(
render(
<ThemeProvider
theme={{
config: {
Expand All @@ -392,7 +392,7 @@ test('useThemeUI returns current color mode colors', () => {
})

test('warns when initialColorModeName matches a key in theme.colors.modes', () => {
const root = render(
render(
<ThemeProvider
theme={{
config: {
Expand All @@ -416,7 +416,7 @@ test('warns when initialColorModeName matches a key in theme.colors.modes', () =

test('dot notation works with color modes', () => {
const Button = () => {
const [colorMode, setMode] = useColorMode()
const [, setMode] = useColorMode()
return (
<button
sx={{
Expand Down Expand Up @@ -458,7 +458,7 @@ test('dot notation works with color modes', () => {

test('dot notation works with color modes and custom properties', () => {
const Button = () => {
const [colorMode, setMode] = useColorMode()
const [, setMode] = useColorMode()
return (
<button
sx={{
Expand Down Expand Up @@ -509,7 +509,7 @@ test('raw color values are passed to theme-ui context when custom properties are
color = context.theme.rawColors!.primary
return null
}
const root = render(
render(
<ThemeProvider
theme={{
colors: {
Expand Down