Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/old-schools-happen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@primer/react": patch
---

Add monospace prop to textinput
18 changes: 18 additions & 0 deletions docs/content/TextInput.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ TextInput is a form component to add default styling to the native text input.
<TextInput contrast aria-label="Zipcode" name="zipcode" placeholder="Find user" autoComplete="postal-code" />
```

## Monospace text input

```jsx live
<TextInput
monospace
aria-label="personal access token"
name="pat"
leadingVisual={CheckIcon}
placeholder="github_pat_abcdefg123456789"
/>
```

## Props

### TextInput
Expand All @@ -103,6 +115,12 @@ TextInput is a form component to add default styling to the native text input.
defaultValue="false"
description="Changes background color to a higher contrast color"
/>
<PropsTableRow
name="monospace"
type="boolean"
defaultValue="false"
description="Shows input in monospace font"
/>
<PropsTableRow name='size' type="'small' | 'medium' | 'large'" description="Creates a smaller or larger input than the default." />

<PropsTableRow
Expand Down
4 changes: 3 additions & 1 deletion src/TextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type NonPassthroughProps = {
trailingVisual?: string | React.ComponentType<{className?: string}>
} & Pick<
ComponentProps<typeof TextInputWrapper>,
'block' | 'contrast' | 'disabled' | 'sx' | 'width' | 'maxWidth' | 'minWidth' | 'variant' | 'size'
'block' | 'contrast' | 'disabled' | 'monospace' | 'sx' | 'width' | 'maxWidth' | 'minWidth' | 'variant' | 'size'
>

// Note: using ComponentProps instead of ComponentPropsWithoutRef here would cause a type issue where `css` is a required prop.
Expand All @@ -29,6 +29,7 @@ const TextInput = React.forwardRef<HTMLInputElement, TextInputInternalProps>(
className,
contrast,
disabled,
monospace,
validationStatus,
sx: sxProp,
size: sizeProp,
Expand All @@ -52,6 +53,7 @@ const TextInput = React.forwardRef<HTMLInputElement, TextInputInternalProps>(
validationStatus={validationStatus}
contrast={contrast}
disabled={disabled}
monospace={monospace}
sx={sxProp}
size={sizeProp}
width={widthProp}
Expand Down
7 changes: 7 additions & 0 deletions src/_TextInputWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export type StyledBaseWrapperProps = {
block?: boolean
contrast?: boolean
disabled?: boolean
monospace?: boolean
validationStatus?: FormValidationStatus
} & WidthProps &
MinWidthProps &
Expand Down Expand Up @@ -104,6 +105,12 @@ export const TextInputBaseWrapper = styled.span<StyledBaseWrapperProps>`
background-color: ${get('colors.input.disabledBg')};
border-color: ${get('colors.border.default')};
`}

${props =>
props.monospace &&
css`
font-family: ${get('fonts.mono')};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to tweak the size here too? the new type face looks a bit larger than usual inputs so may look odd adjacent to them. May just be the fixed-pitch of the the monospace font playing tricks on my eyes though. cc. @mperrotti
Screenshot 2022-03-08 at 12 43 37

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I feel the size issue too. Would appreciate help from @mperrotti on this design.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took another detailed look and it may just be how monospace fonts look. Its the same size as the one on the developer settings > PAT generator page. I think I'll go ahead with what we have.

`}

${props =>
props.validationStatus === 'error' &&
Expand Down
5 changes: 4 additions & 1 deletion src/__tests__/TextInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ describe('TextInput', () => {
})

it('renders contrast', () => {
expect(render(<TextInput name="zipcode" status="contrast" />)).toMatchSnapshot()
expect(render(<TextInput name="zipcode" contrast />)).toMatchSnapshot()
})
it('renders monospace', () => {
expect(render(<TextInput name="zipcode" monospace />)).toMatchSnapshot()
})

it('renders placeholder', () => {
Expand Down
106 changes: 106 additions & 0 deletions src/__tests__/__snapshots__/TextInput.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,7 @@ exports[`TextInput renders contrast 1`] = `
-ms-flex-align: stretch;
align-items: stretch;
min-height: 32px;
background-color: #f6f8fa;
background-repeat: no-repeat;
background-position: right 8px center;
padding-left: 0;
Expand Down Expand Up @@ -765,6 +766,111 @@ exports[`TextInput renders leadingVisual 1`] = `
</span>
`;

exports[`TextInput renders monospace 1`] = `
.c1 {
border: 0;
font-size: inherit;
font-family: inherit;
background-color: transparent;
-webkit-appearance: none;
color: inherit;
width: 100%;
}

.c1:focus {
outline: 0;
}

.c0 {
font-size: 14px;
line-height: 20px;
color: #24292f;
vertical-align: middle;
background-color: #ffffff;
border: 1px solid #d0d7de;
border-radius: 6px;
outline: none;
box-shadow: inset 0 1px 0 rgba(208,215,222,0.2);
cursor: text;
display: -webkit-inline-box;
display: -webkit-inline-flex;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-align-items: stretch;
-webkit-box-align: stretch;
-ms-flex-align: stretch;
align-items: stretch;
min-height: 32px;
font-family: SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;
background-repeat: no-repeat;
background-position: right 8px center;
padding-left: 0;
padding-right: 0;
}

.c0::-webkit-input-placeholder {
color: #6e7781;
}

.c0::-moz-placeholder {
color: #6e7781;
}

.c0:-ms-input-placeholder {
color: #6e7781;
}

.c0::placeholder {
color: #6e7781;
}

.c0:focus-within {
border-color: #0969da;
box-shadow: 0 0 0 3px rgba(9,105,218,0.3);
}

.c0 > textarea {
padding: 12px;
}

.c0 >:not(:last-child) {
margin-right: 8px;
}

.c0 .TextInput-icon {
-webkit-align-self: center;
-ms-flex-item-align: center;
align-self: center;
color: #57606a;
-webkit-flex-shrink: 0;
-ms-flex-negative: 0;
flex-shrink: 0;
}

.c0 > input,
.c0 > select {
padding-left: 12px;
padding-right: 12px;
}

@media (min-width:768px) {
.c0 {
font-size: 14px;
}
}

<span
className="c0 TextInput-wrapper"
>
<input
className="c1"
data-component="input"
name="zipcode"
type="text"
/>
</span>
`;

exports[`TextInput renders placeholder 1`] = `
.c1 {
border: 0;
Expand Down
7 changes: 7 additions & 0 deletions src/stories/TextInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ export default {
type: 'boolean'
}
},
monospace: {
name: 'Monospace',
defaultValue: false,
control: {
type: 'boolean'
}
},
variant: {
name: 'Variants',
options: ['small', 'medium', 'large'],
Expand Down