diff --git a/README.md b/README.md index 08c9217e8fc..ca91d25ac97 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,49 @@ export default () => ( This will set the `color`, `font-family`, and `line-height` CSS properties to the same ones used in [primer-base](https://github.com/primer/primer/blob/master/modules/primer-base/lib/base.scss#L15). +#### Theming + +Components are styled using Primer's [theme](https://github.com/primer/components/blob/master/src/theme.js) by default, but you can provide your own theme by using [styled-component's][styled-components] ``. If you'd like to fully replace the Primer [theme](https://github.com/primer/components/blob/master/src/theme.js) with your custom theme, pass your theme to the `` in the root of your application like so: + +```jsx +import {ThemeProvider} from 'styled-components' + +const theme = { ... } + +const App = (props) => { + return ( +
+ +
your app here
+
+
+ ) +} + +``` + +If you'd like to merge the Primer theme with your theme, you can do so importing the Primer theme and merging using Object.assign: + +```jsx +import {ThemeProvider} from 'styled-components' +import {theme} from '@primer/components' + +const customTheme = { ... } + + +const App = (props) => { + return ( +
+ // matching keys in customTheme will override keys in the Primer theme +
your app here
+
+
+ ) +} +``` + +*Note that using `Object.assign` will only create a shallow merge. This means that if both themes have a `color` object, the _entire_ `color` object will be replaced with the new `color` object, instead of only replacing duplicate values from the original theme's color object. + #### Static CSS rendering If you're rendering React components both server-side _and_ client-side, we suggest following [styled-component's server-side rendering instructions](https://www.styled-components.com/docs/advanced#server-side-rendering) to avoid the flash of unstyled content for server-rendered components. This repo's [documentation template component](https://github.com/primer/components/blob/master/pages/_document.js) demonstrates how to do this in [Next.js]. diff --git a/contributing.md b/contributing.md index 91a2879bbb3..f3e6f78ba99 100644 --- a/contributing.md +++ b/contributing.md @@ -63,7 +63,7 @@ Default values for system props can be set in `Component.defaultProps`. Prop Types from system props such as `COMMON` or `TYPOGRAPHY` as well as styled-system functions can be spread in the component's prop types declaration (see example below). - ⚠️ **Make sure to always set the default `theme` prop to our theme! This allows consumers of our components to access our theme values without a ThemeProvider.** + ⚠️ **Make sure to always set the default `theme` prop to our [theme](https://github.com/primer/components/blob/master/src/theme.js)! This allows consumers of our components to access our theme values without a ThemeProvider.** ```jsx diff --git a/package.json b/package.json index 92ba83f5ff1..8881901f619 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@primer/components", - "version": "8.2.0-beta", + "version": "9.0.0-beta", "description": "Primer react components", "main": "dist/index.umd.js", "module": "dist/index.esm.js", diff --git a/pages/components/docs/Dropdown.md b/pages/components/docs/Dropdown.md index 63a0691322c..9f5f28d3546 100644 --- a/pages/components/docs/Dropdown.md +++ b/pages/components/docs/Dropdown.md @@ -3,26 +3,41 @@ The Dropdown component is a lightweight context menu for housing navigation and actions. +Dropdown.Button is used to trigger opening and closing the dropdown. + +Dropdown.Menu wraps your menu content. Be sure to pass a `direction` prop to this component to position the menu in relation to the Dropdown.Button. + ## Default example ```.jsx - - Item 1 - Item 2 - Item 3 - + Dropdown + + Item 1 + Item 2 + Item 3 + ``` ## System props -Dropdown components get `COMMON` system props. Read our [System Props](/components/docs/system-props) doc page for a full list of available props. +Dropdown, Dropdown.Menu, Dropdown.Button, and Dropdown.Item all get `COMMON` system props. Read our [System Props](/components/docs/system-props) doc page for a full list of available props. ## Component props +#### Dropdown.Menu | Name | Type | Default | Description | | :- | :- | :-: | :- | -| scheme | String | | Button scheme used to style the component, can be one of `danger`, `outline` or `primary` | -| title | String | | Optional prop to set the text in the Dropdown button +| direction | String | 'sw' | Sets the direction of the dropdown menu. | + +#### Dropdown.Item +No additional props. + +#### Dropdown.Button +No additional props. + +#### Dropdown +No additional props. + export const meta = {displayName: 'Dropdown'} diff --git a/pages/components/docs/index.js b/pages/components/docs/index.js index bc38be78abc..a4942e8406e 100644 --- a/pages/components/docs/index.js +++ b/pages/components/docs/index.js @@ -7,6 +7,7 @@ export {meta as CircleBadge} from './CircleBadge.md' export {meta as CircleOcticon} from './CircleOcticon.md' export {meta as CounterLabel} from './CounterLabel.md' export {meta as Details} from './Details.md' +export {meta as Dropdown} from './Dropdown.md' export {meta as Donut} from './Donut.md' export {meta as FilterList} from './FilterList.md' export {meta as Flash} from './Flash.md' diff --git a/pages/components/docs/primer-theme.md b/pages/components/docs/primer-theme.md index ced802cbf7c..d1463de2663 100644 --- a/pages/components/docs/primer-theme.md +++ b/pages/components/docs/primer-theme.md @@ -20,7 +20,7 @@ Custom theming is an optional way to override the Primer values that control col There are two ways to change the theme of Primer components: -1. You can override the theme for an entire tree of components using the `` from [styled-components]: +1. You can override the entire theme for an entire tree of components using the `` from [styled-components]: ```jsx import {Block, Button, Text, theme as primer} from '@primer/components' @@ -46,8 +46,27 @@ There are two ways to change the theme of Primer components: ``` **⚠️ Note: [styled-components]'s `` only allows exactly one child.** +2. You can merge the Primer theme with your custom theme using Object.assign: -1. You can theme individual components by passing the `theme` prop directly: +```jsx +import {ThemeProvider} from `styled-components` +import {theme} from '@primer/components' + +const customTheme = { ... } + + +const App = (props) => { + return ( +
+ // matching keys in customTheme will override keys in the Primer theme +
your app here
+
+
+ ) +} +``` + +3. You can theme individual components by passing the `theme` prop directly: ```jsx import {Text} from '@primer/components' @@ -65,6 +84,7 @@ There are two ways to change the theme of Primer components: **☝️ This is an intentionally convoluted example, since you can use `` out of the box.** + Read the [styled-system docs](http://jxnblk.com/styled-system/getting-started#theming) for more information on theming in styled-system. [styled-components]: https://styled-components.com/ diff --git a/src/Avatar.js b/src/Avatar.js index ffb2922bffd..e6cf8894311 100644 --- a/src/Avatar.js +++ b/src/Avatar.js @@ -1,6 +1,7 @@ import PropTypes from 'prop-types' import styled from 'styled-components' -import {themeGet, space} from 'styled-system' +import {get} from './constants' +import {space} from 'styled-system' import theme from './theme' function borderRadius({size}) { @@ -15,7 +16,7 @@ const Avatar = styled.img.attrs(props => ({ }))` display: inline-block; overflow: hidden; // Ensure page layout in Firefox should images fail to load - line-height: ${themeGet('lineHeights.condensedUltra', 1)}; + line-height: ${get('lineHeights.condensedUltra')}; vertical-align: middle; ${borderRadius}; ${space}; diff --git a/src/AvatarPair.js b/src/AvatarPair.js index fdbf8f068ad..87c374e0254 100644 --- a/src/AvatarPair.js +++ b/src/AvatarPair.js @@ -1,11 +1,11 @@ import React from 'react' import PropTypes from 'prop-types' import styled from 'styled-components' -import {themeGet} from 'styled-system' +import {get} from './constants' import Avatar from './Avatar' import theme from './theme' -const getBackgroundColor = themeGet('colors.white', '#fff') +const getBackgroundColor = get('colors.white') const Wrapper = styled('div')` display: inline-flex; @@ -15,7 +15,7 @@ const Wrapper = styled('div')` const childStyles = props => ({ display: 'inline-block', overflow: 'hidden', // Ensure page layout in Firefox should images fail to load - lineHeight: `${themeGet('lineHeights.condensedUltra', 1)}`, + lineHeight: `${get('lineHeights.condensedUltra')}`, verticalAlign: 'middle', borderRadius: '2px', position: 'absolute', diff --git a/src/BranchName.js b/src/BranchName.js index fa433843081..baff86cece1 100644 --- a/src/BranchName.js +++ b/src/BranchName.js @@ -1,14 +1,13 @@ import PropTypes from 'prop-types' import styled from 'styled-components' -import {themeGet} from 'styled-system' import theme from './theme' -import {COMMON, Base} from './constants' +import {COMMON, Base, get} from './constants' const BranchName = styled(Base)` display: inline-block; padding: 2px 6px; - font-size: ${themeGet('fontSizes.0', theme.fontSizes[0])}px; - font-family: ${themeGet('fonts.mono', theme.fonts.mono)}; + font-size: ${get('fontSizes.0')}px; + font-family: ${get('fonts.mono')}; color: rgba(27, 31, 35, 0.6); background-color: #eaf5ff; border-radius: 3px; diff --git a/src/Button.js b/src/Button.js index 176dbaf4a2d..34e6ed06b5f 100644 --- a/src/Button.js +++ b/src/Button.js @@ -12,7 +12,7 @@ function fontSize({size = '14px', ...props}) { } } -const ButtonBase = ({is: Tag = 'div', onClick, disabled, theme, ...rest}) => { +const ButtonBase = ({is: Tag, onClick, disabled, theme, ...rest}) => { return } diff --git a/src/Donut.js b/src/Donut.js index 548734fad8a..44e5c361f24 100644 --- a/src/Donut.js +++ b/src/Donut.js @@ -2,11 +2,12 @@ import React from 'react' import PropTypes from 'prop-types' import {arc as Arc, pie as Pie} from 'd3-shape' import styled from 'styled-components' -import {themeGet, space} from 'styled-system' +import {space} from 'styled-system' +import {get} from './constants' import theme from './theme' const defaultColor = '#666' -const getStateColors = themeGet('colors.state', {}) +const getStateColors = get('colors.state') function DonutBase(props) { const {className, data, children = mapData(data), size} = props diff --git a/src/Dropdown.js b/src/Dropdown.js index d29032c67ee..1fd1dbae5b9 100644 --- a/src/Dropdown.js +++ b/src/Dropdown.js @@ -1,60 +1,132 @@ import React from 'react' import PropTypes from 'prop-types' -import classnames from 'classnames' import styled from 'styled-components' -import StyledOcticon from './StyledOcticon' -import {TriangleDown} from '@githubprimer/octicons-react' import Button from './Button' -import BorderBox from './BorderBox' -import Caret from './Caret' import Details from './Details' -import Flex from './Flex' -import {COMMON} from './constants' +import {COMMON, get} from './constants' +import getDirectionStyles from './DropdownStyles' import theme from './theme' -function DropdownBase({title, scheme, children, theme, className, ...rest}) { - const {minWidth} = rest +const Dropdown = styled(Details)` + position: relative; + display: inline-block; + ${COMMON}; +` + +const DropdownCaret = styled.div` + border: ${get('space.1')}px solid transparent; + border-top-color: currentcolor; + content: ''; + display: inline-block; + height: 0; + vertical-align: middle; + width: 0; +` + +const DropdownButton = ({children, ...rest}) => { return ( -
- - {({toggle}) => ( - - - - {children} - - - - )} - -
+ ) } -const Dropdown = styled(DropdownBase)(COMMON) +const DropdownMenu = styled.ul` + background-clip: padding-box; + background-color: ${get('colors.white')}; + border: 1px solid rgba(27, 31, 35, 0.15); + border-radius: ${get('space.1')}px; + box-shadow: 0 3px 12px rgba(27, 31, 35, 0.15); + left: 0; + list-style: none; + margin-top: 2px; + padding: 5px 0 5px 0 !important; //TODO: fix this override on our markdown styles + position: absolute; + top: 100%; + width: 160px; + z-index: 100; + + &::before { + position: absolute; + display: inline-block; + content: ''; + } + + &::after { + position: absolute; + display: inline-block; + content: ''; + } + + &::before { + border: ${get('space.2')}px solid transparent; + border-bottom-color: ${get('colors.blackfade15')}; + } + + &::after { + border: 7px solid transparent; + border-bottom-color: ${get('colors.white')}; + } + + // stylelint-disable-next-line selector-max-type + > ul { + list-style: none; + } + ${props => (props.direction ? getDirectionStyles(props.theme, props.direction) : '')}; + ${COMMON}; +` + +const DropdownItem = styled.li` + display: block; + padding: ${get('space.1')}px 10px ${get('space.1')}px 15px; + overflow: hidden; + color: $get('colors.gray.9'); + text-overflow: ellipsis; + white-space: nowrap; + + &:focus { + color: ${get('colors.white')}; + text-decoration: none; + background-color: ${get('colors.blue.5')}; + } + + &:hover { + color: ${get('colors.white')} + text-decoration: none; + background-color: ${get('colors.blue.5')}; + outline: none; + } + ${COMMON} +` -Dropdown.defaultProps = { +Dropdown.Button = styled(DropdownButton)(COMMON) +Dropdown.Menu = DropdownMenu +Dropdown.Item = DropdownItem + +Dropdown.Menu.propTypes = { + direction: PropTypes.oneOf(['ne', 'e', 'se', 's', 'sw', 'w']), + ...COMMON.propTypes +} + +Dropdown.Menu.defaultProps = { + direction: 'sw', theme } +Dropdown.defaultProps = {theme} Dropdown.propTypes = { children: PropTypes.node, - scheme: Button.propTypes.scheme, - title: PropTypes.string, + ...COMMON.propTypes +} + +Dropdown.Button.defaultProps = {theme} +Dropdown.Button.propTypes = { + ...COMMON.propTypes +} + +Dropdown.Item.defaultProps = {theme} +Dropdown.Item.propTypes = { ...COMMON.propTypes } diff --git a/src/DropdownStyles.js b/src/DropdownStyles.js new file mode 100644 index 00000000000..bc22fce969c --- /dev/null +++ b/src/DropdownStyles.js @@ -0,0 +1,127 @@ +import {get} from './constants' + +const getDirectionStyles = (theme, direction) => { + const map = { + w: ` + top: 0; + right: 100%; + left: auto; + width: auto; + margin-top: 0; + margin-right: 10px; + + &::before { + top: 10px; + right: -16px; + left: auto; + border-color: transparent; + border-left-color: ${get('colors.blackfade15')(theme)}; + } + + &::after { + top: 11px; + right: -14px; + left: auto; + border-color: transparent; + border-left-color: ${get('colors.white')(theme)}; + } + `, + e: ` + top: 0; + left: 100%; + width: auto; + margin-top: 0; + margin-left: 10px; + + &::before { + top: 10px; + left: -16px; + border-color: transparent; + border-right-color: ${get('colors.blackfade15')(theme)}; + } + + &::after { + top: 11px; + left: -14px; + border-color: transparent; + border-right-color: ${get('colors.white')(theme)}; + } + `, + ne: ` + top: auto; + bottom: 100%; + left: 0; + margin-bottom: 3px; + + &::before, + &::after { + top: auto; + right: auto; + } + + &::before { + bottom: -8px; + left: 9px; + border-top: 8px solid ${get('colors.blackfade15')(theme)} + border-bottom: 0; + border-left: 8px solid transparent; + } + + &::after { + bottom: -7px; + left: 10px; + border-top: 7px solid ${get('colors.white')(theme)}; + border-right: 7px solid transparent; + border-bottom: 0; + border-left: 7px solid transparent; + } + `, + s: ` + right: 50%; + left: auto; + transform: translateX(50%); + + &::before { + top: -16px; + right: 50%; + transform: translateX(50%); + } + + &::after { + top: -14px; + right: 50%; + transform: translateX(50%); + } + `, + sw: ` + right: 0; + left: auto; + + &::before { + top: -16px; + right: 9px; + left: auto; + } + + &::after { + top: -14px; + right: 10px; + left: auto; + } + `, + se: ` + &::before { + top: -16px; + left: 9px; + } + + &::after { + top: -14px; + left: 10px; + } + ` + } + return map[direction] +} + +export default getDirectionStyles diff --git a/src/__tests__/Donut.js b/src/__tests__/Donut.js index a4b16544938..74eb3c5a64c 100644 --- a/src/__tests__/Donut.js +++ b/src/__tests__/Donut.js @@ -74,10 +74,6 @@ describe('Donut', () => { expect(render().props.fill).toEqual(state.unknown) }) - it('renders the fallback color when no state color is found in the theme', () => { - expect(render().props.fill).toEqual('#666') - }) - it('respects the fill attribute', () => { expect(render().props.fill).toEqual('pink') }) diff --git a/src/__tests__/Dropdown.js b/src/__tests__/Dropdown.js index fd62bd23d84..223ed41fd4c 100644 --- a/src/__tests__/Dropdown.js +++ b/src/__tests__/Dropdown.js @@ -9,12 +9,6 @@ describe('Dropdown', () => { expect(render(hello!)).toMatchSnapshot() }) - it('renders a
with "BtnGroup" class', () => { - const rendered = render() - expect(rendered.type).toEqual('div') - expect(rendered.props.className).toContain('BtnGroup') - }) - it('implements system props', () => { expect(Dropdown).toImplementSystemProps(COMMON) }) @@ -23,3 +17,64 @@ describe('Dropdown', () => { expect(Dropdown).toSetDefaultTheme() }) }) + +describe('Dropdown.Item', () => { + it('matches the snapshots', () => { + expect(render(hi)).toMatchSnapshot() + expect(render(hello!)).toMatchSnapshot() + }) + + it('implements system props', () => { + expect(Dropdown.Item).toImplementSystemProps(COMMON) + }) + + it('has default theme', () => { + expect(Dropdown.Item).toSetDefaultTheme() + }) +}) + +describe('Dropdown.Menu', () => { + it('matches the snapshots', () => { + expect( + render( + +
  • 1
  • +
  • 2
  • +
  • 3
  • +
    + ) + ).toMatchSnapshot() + expect( + render( + +
  • 1
  • +
  • 2
  • +
  • 3
  • +
    + ) + ).toMatchSnapshot() + }) + + it('implements system props', () => { + expect(Dropdown.Menu).toImplementSystemProps(COMMON) + }) + + it('has default theme', () => { + expect(Dropdown.Menu).toSetDefaultTheme() + }) +}) + +describe('Dropdown.Button', () => { + it('matches the snapshots', () => { + expect(render(hi)).toMatchSnapshot() + expect(render(hello!)).toMatchSnapshot() + }) + + it('implements system props', () => { + expect(Dropdown.Button).toImplementSystemProps(COMMON) + }) + + it('has default theme', () => { + expect(Dropdown.Button).toSetDefaultTheme() + }) +}) diff --git a/src/__tests__/Heading.js b/src/__tests__/Heading.js index 07ac2fd1015..27cc0ce97a7 100644 --- a/src/__tests__/Heading.js +++ b/src/__tests__/Heading.js @@ -82,6 +82,11 @@ describe('Heading', () => { } }) + it('respects the "fontStyle" prop', () => { + expect(render()).toHaveStyleRule('font-style', 'italic') + expect(render()).toHaveStyleRule('font-style', 'normal') + }) + xit('renders fontSize with f* classes using inverse scale', () => { expect(render()).toEqual(render()) expect(render()).toEqual(render()) diff --git a/src/__tests__/Link.js b/src/__tests__/Link.js index 98658a1261e..8c352134fa9 100644 --- a/src/__tests__/Link.js +++ b/src/__tests__/Link.js @@ -29,4 +29,9 @@ describe('Link', () => { it('respects hoverColor prop', () => { expect(render()).toMatchSnapshot() }) + + it('respects the "fontStyle" prop', () => { + expect(render()).toHaveStyleRule('font-style', 'italic') + expect(render()).toHaveStyleRule('font-style', 'normal') + }) }) diff --git a/src/__tests__/Text.js b/src/__tests__/Text.js index 429ceb14d2a..c3037936c23 100644 --- a/src/__tests__/Text.js +++ b/src/__tests__/Text.js @@ -22,7 +22,7 @@ describe('Text', () => { expect(render().type).toEqual('b') }) - it('renders font-size', () => { + it('renders fontSize', () => { for (const fontSize of theme.fontSizes) { expect(render()).toHaveStyleRule('font-size', px(fontSize)) } @@ -51,6 +51,11 @@ describe('Text', () => { expect(render()).toHaveStyleRule('font-weight', '400') }) + it('respects the "fontStyle" prop', () => { + expect(render()).toHaveStyleRule('font-style', 'italic') + expect(render()).toHaveStyleRule('font-style', 'normal') + }) + it('respects lineHeight', () => { for (const [name, value] of Object.entries(theme.lineHeights)) { expect(render()).toHaveStyleRule('line-height', String(value)) diff --git a/src/__tests__/__snapshots__/Dropdown.js.snap b/src/__tests__/__snapshots__/Dropdown.js.snap index 51d3325f350..f3a1164eb9b 100644 --- a/src/__tests__/__snapshots__/Dropdown.js.snap +++ b/src/__tests__/__snapshots__/Dropdown.js.snap @@ -1,11 +1,60 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Dropdown matches the snapshots 1`] = ` -.c3 { - margin-left: 0px; +.c1 > summary { + list-style: none; +} + +.c1 > summary::before { + display: none; +} + +.c1 > summary::-webkit-details-marker { + display: none; +} + +.c0 { + position: relative; + display: inline-block; +} + +
    + hi +
    +`; + +exports[`Dropdown matches the snapshots 2`] = ` +.c1 > summary { + list-style: none; +} + +.c1 > summary::before { + display: none; +} + +.c1 > summary::-webkit-details-marker { + display: none; +} + +.c0 { + position: relative; + display: inline-block; } -.c2 { +
    + hello! +
    +`; + +exports[`Dropdown.Button matches the snapshots 1`] = ` +.c0 { position: relative; display: inline-block; padding: 6px 12px; @@ -33,7 +82,7 @@ exports[`Dropdown matches the snapshots 1`] = ` font-size: 14px; } -.c2:hover { +.c0:hover { background-color: rgb(230,235,241); background-image: linear-gradient(-180deg,rgb(239,243,246) 0%,rgb(230,235,241) 90%); background-position: -0.5em center; @@ -43,157 +92,55 @@ exports[`Dropdown matches the snapshots 1`] = ` background-repeat: repeat-x; } -.c2:active { +.c0:active { background-color: rgb(233,236,239); background-image: none; box-shadow: rgba(27,31,35,0.15) 0px 0.15em 0.3em inset; border-color: rgba(27,31,35,0.2); } -.c2:selected { +.c0:selected { background-color: rgb(233,236,239); background-image: none; box-shadow: rgba(27,31,35,0.15) 0px 0.15em 0.3em inset; border-color: rgba(27,31,35,0.2); } -.c2:disabled { +.c0:disabled { color: rgba(36,41,46,0.4); background-color: #f6f8fa; background-image: none; border-color: rgba(27,31,35,0.20) box-shadow:none; } -.c2:focus { +.c0:focus { outline: none; box-shadow: rgba(3,102,214,0.3) 0px 0px 0px 0.2em; } -.c4 { - background-color: #fff; - margin-top: 4px; - padding-left: 16px; - padding-right: 16px; - padding-top: 8px; - padding-bottom: 8px; - border: 1px solid; - border-color: #e1e4e8; - box-shadow: 0 1px 1px rgba(27,31,35,0.1); - border-radius: 3px; -} - -.c1 > summary { - list-style: none; -} - -.c1 > summary::before { - display: none; -} - -.c1 > summary::-webkit-details-marker { - display: none; -} - -.c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; +.c1 { + border: 4px solid transparent; + border-top-color: currentcolor; + content: ''; + display: inline-block; + height: 0; + vertical-align: middle; + width: 0; } -
    -
    - - - -
    - hi - - - - - - -
    -
    -
    + hi +
    + `; -exports[`Dropdown matches the snapshots 2`] = ` -.c3 { - margin-left: 8px; -} - -.c2 { +exports[`Dropdown.Button matches the snapshots 2`] = ` +.c0 { position: relative; display: inline-block; padding: 6px 12px; @@ -221,7 +168,7 @@ exports[`Dropdown matches the snapshots 2`] = ` font-size: 14px; } -.c2:hover { +.c0:hover { background-color: rgb(230,235,241); background-image: linear-gradient(-180deg,rgb(239,243,246) 0%,rgb(230,235,241) 90%); background-position: -0.5em center; @@ -231,148 +178,259 @@ exports[`Dropdown matches the snapshots 2`] = ` background-repeat: repeat-x; } -.c2:active { +.c0:active { background-color: rgb(233,236,239); background-image: none; box-shadow: rgba(27,31,35,0.15) 0px 0.15em 0.3em inset; border-color: rgba(27,31,35,0.2); } -.c2:selected { +.c0:selected { background-color: rgb(233,236,239); background-image: none; box-shadow: rgba(27,31,35,0.15) 0px 0.15em 0.3em inset; border-color: rgba(27,31,35,0.2); } -.c2:disabled { +.c0:disabled { color: rgba(36,41,46,0.4); background-color: #f6f8fa; background-image: none; border-color: rgba(27,31,35,0.20) box-shadow:none; } -.c2:focus { +.c0:focus { outline: none; box-shadow: rgba(3,102,214,0.3) 0px 0px 0px 0.2em; } -.c4 { +.c1 { + border: 4px solid transparent; + border-top-color: currentcolor; + content: ''; + display: inline-block; + height: 0; + vertical-align: middle; + width: 0; +} + + + hello! +
    +
    +`; + +exports[`Dropdown.Item matches the snapshots 1`] = ` +.c0 { + display: block; + padding: 4px 10px 4px 15px; + overflow: hidden; + color: $get('colors.gray.9'); + text-overflow: ellipsis; + white-space: nowrap; +} + +.c0:focus { + color: #fff; + -webkit-text-decoration: none; + text-decoration: none; + background-color: #0366d6; +} + +.c0:hover { + color: #fff; + -webkit-text-decoration: none; + text-decoration: none; + background-color: #0366d6; + outline: none; +} + +
  • + hi +
  • +`; + +exports[`Dropdown.Item matches the snapshots 2`] = ` +.c0 { + display: block; + padding: 4px 10px 4px 15px; + overflow: hidden; + color: $get('colors.gray.9'); + text-overflow: ellipsis; + white-space: nowrap; +} + +.c0:focus { + color: #fff; + -webkit-text-decoration: none; + text-decoration: none; + background-color: #0366d6; +} + +.c0:hover { + color: #fff; + -webkit-text-decoration: none; + text-decoration: none; + background-color: #0366d6; + outline: none; +} + +
  • + hello! +
  • +`; + +exports[`Dropdown.Menu matches the snapshots 1`] = ` +.c0 { + background-clip: padding-box; background-color: #fff; - margin-top: 4px; - padding-left: 16px; - padding-right: 16px; - padding-top: 8px; - padding-bottom: 8px; - border: 1px solid; - border-color: #e1e4e8; - box-shadow: 0 1px 1px rgba(27,31,35,0.1); - border-radius: 3px; + border: 1px solid rgba(27,31,35,0.15); + border-radius: 4px; + box-shadow: 0 3px 12px rgba(27,31,35,0.15); + left: 0; + list-style: none; + margin-top: 2px; + padding: 5px 0 5px 0 !important; + position: absolute; + top: 100%; + width: 160px; + z-index: 100; + right: 0; + left: auto; } -.c1 > summary { +.c0::before { + position: absolute; + display: inline-block; + content: ''; +} + +.c0::after { + position: absolute; + display: inline-block; + content: ''; +} + +.c0::before { + border: 8px solid transparent; + border-bottom-color: rgba(27,31,35,0.15); +} + +.c0::after { + border: 7px solid transparent; + border-bottom-color: #fff; +} + +.c0 > ul { list-style: none; } -.c1 > summary::before { - display: none; +.c0::before { + top: -16px; + right: 9px; + left: auto; } -.c1 > summary::-webkit-details-marker { - display: none; +.c0::after { + top: -14px; + right: 10px; + left: auto; } +
      +
    • + 1 +
    • +
    • + 2 +
    • +
    • + 3 +
    • +
    +`; + +exports[`Dropdown.Menu matches the snapshots 2`] = ` .c0 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; + background-clip: padding-box; + background-color: #fff; + border: 1px solid rgba(27,31,35,0.15); + border-radius: 4px; + box-shadow: 0 3px 12px rgba(27,31,35,0.15); + left: 0; + list-style: none; + margin-top: 2px; + padding: 5px 0 5px 0 !important; + position: absolute; + top: 100%; + width: 160px; + z-index: 100; + right: 0; + left: auto; +} + +.c0::before { + position: absolute; + display: inline-block; + content: ''; +} + +.c0::after { + position: absolute; + display: inline-block; + content: ''; +} + +.c0::before { + border: 8px solid transparent; + border-bottom-color: rgba(27,31,35,0.15); +} + +.c0::after { + border: 7px solid transparent; + border-bottom-color: #fff; +} + +.c0 > ul { + list-style: none; +} + +.c0::before { + top: -16px; + right: 9px; + left: auto; +} + +.c0::after { + top: -14px; + right: 10px; + left: auto; } -
    -
    - - hi - - -
    - hello! - - - - - - -
    -
    -
    +
  • + 1 +
  • +
  • + 2 +
  • +
  • + 3 +
  • + `; diff --git a/src/constants.js b/src/constants.js index 6c4b4fb8376..ff3d18e5a15 100644 --- a/src/constants.js +++ b/src/constants.js @@ -19,6 +19,7 @@ export const BORDER = compose( export const TYPOGRAPHY = compose( styles.fontFamily, styles.fontSize, + styles.fontStyle, styles.fontWeight, styles.lineHeight, styles.textAlign @@ -73,6 +74,7 @@ export const TYPOGRAPHY_LIST = [ // typography props 'fontFamily', 'fontSize', + 'fontStyle', 'fontWeight', 'lineHeight', 'textAlign'