From 24c13297cb79d9ea4cb3b92f569b2938a4126313 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Wed, 26 May 2021 12:09:57 -0700 Subject: [PATCH 01/11] components: Add `BaseField` --- docs/manifest.json | 6 ++ packages/components/src/base-field/README.md | 75 ++++++++++++++ .../components/src/base-field/component.js | 14 +++ packages/components/src/base-field/hook.js | 74 ++++++++++++++ packages/components/src/base-field/index.js | 3 + packages/components/src/base-field/styles.js | 99 +++++++++++++++++++ .../test/__snapshots__/index.js.snap | 77 +++++++++++++++ .../components/src/base-field/test/index.js | 16 +++ packages/components/src/utils/browsers.js | 51 ++++++++++ .../components/src/utils/config-values.js | 7 ++ 10 files changed, 422 insertions(+) create mode 100644 packages/components/src/base-field/README.md create mode 100644 packages/components/src/base-field/component.js create mode 100644 packages/components/src/base-field/hook.js create mode 100644 packages/components/src/base-field/index.js create mode 100644 packages/components/src/base-field/styles.js create mode 100644 packages/components/src/base-field/test/__snapshots__/index.js.snap create mode 100644 packages/components/src/base-field/test/index.js create mode 100644 packages/components/src/utils/browsers.js diff --git a/docs/manifest.json b/docs/manifest.json index 27aaef43b208b..ac735f7c9e4b4 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -683,6 +683,12 @@ "markdown_source": "../packages/components/src/base-control/README.md", "parent": "components" }, + { + "title": "BaseField", + "slug": "base-field", + "markdown_source": "../packages/components/src/base-field/README.md", + "parent": "components" + }, { "title": "BoxControl", "slug": "box-control", diff --git a/packages/components/src/base-field/README.md b/packages/components/src/base-field/README.md new file mode 100644 index 0000000000000..32b4e3a849ddd --- /dev/null +++ b/packages/components/src/base-field/README.md @@ -0,0 +1,75 @@ +# BaseField + +
+This feature is still experimental. “Experimental” means this is an early implementation subject to drastic and breaking changes. +
+ +`BaseField` is an internal (i.e., not exported in the `index.js`) primitive component used for building more complex fields like `TextField`. It provides error handling and focus styles for field components. It does _not_ handle layout of the component aside from wrapping the field in a `Flex` wrapper. + +## Usage + +`BaseField` is primarily used as a hook rather than a component: + +```js +function useExampleField( props ) { + const { + as = 'input', + ...baseProps, + } = useBaseField( props ); + + const inputProps = { + as, + // more cool stuff here + } + + return { inputProps, ...baseProps }; +} + +function ExampleField( props, forwardRef ) { + const { + preFix, + affix, + disabled, + inputProps, + ...baseProps + } = useExampleField( props ); + + return ( + + {preFix} + + {affix} + + ); +} +``` + +## Props + +### `error`: `boolean` + +Renders an error style around the component. + +### `disabled`: `boolean` + +Whether the field is disabled. + +### `isClickable`: `boolean` + +Renders a `cursor: pointer` on hover; + +### `isFocused`: `boolean` + +Renders focus styles around the component. + +### `isInline`: `boolean` + +Renders a component that can be inlined in some text. + +### `isSubtle`: `boolean` + +Renders a subtle variant of the component. diff --git a/packages/components/src/base-field/component.js b/packages/components/src/base-field/component.js new file mode 100644 index 0000000000000..1fb0fcacb612b --- /dev/null +++ b/packages/components/src/base-field/component.js @@ -0,0 +1,14 @@ +/** + * Internal dependencies + */ +import { createComponent } from '../ui/utils'; +import { useBaseField } from './hook'; + +/** + * `BaseField` is a primitive component used to create form element components (e.g. `TextInput`). + */ +export default createComponent( { + as: 'div', + useHook: useBaseField, + name: 'BaseField', +} ); diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js new file mode 100644 index 0000000000000..ea8e106555d98 --- /dev/null +++ b/packages/components/src/base-field/hook.js @@ -0,0 +1,74 @@ +/** + * External dependencies + */ +import { cx } from 'emotion'; + +/** + * WordPress dependencies + */ +import { useMemo } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { useContextSystem } from '../ui/context'; +import { useControlGroupContext } from '../ui/control-group'; +import { useFlex } from '../flex'; +import * as styles from './styles'; + +/** + * @typedef OwnProps + * @property {boolean} [error=false] Renders an error. + * @property {boolean} [disabled] Whether the field is disabled. + * @property {boolean} [isClickable=false] Renders a `cursor: pointer` on hover. + * @property {boolean} [isFocused=false] Renders focus styles. + * @property {boolean} [isInline=false] Renders as an inline element (layout). + * @property {boolean} [isSubtle=false] Renders a subtle variant. + */ + +/** @typedef {import('../Flex/useFlex').FlexProps & OwnProps} Props */ + +/** + * @param {import('@wp-g2/create-styles').ViewOwnProps} props + */ +export function useBaseField( props ) { + const { + className, + error = false, + isClickable = false, + isFocused = false, + isInline = false, + isSubtle = false, + // eslint-disable-next-line no-unused-vars + defaultValue, // extract this because useFlex doesn't accept it + ...flexProps + } = useContextSystem( props, 'BaseField' ); + + const { styles: controlGroupStyles } = useControlGroupContext(); + + const classes = useMemo( + () => + cx( + styles.BaseField, + controlGroupStyles, + isClickable && styles.clickable, + isFocused && styles.focus, + isSubtle && styles.subtle, + error && styles.error, + error && isFocused && styles.errorFocus, + isInline && styles.inline, + className + ), + [ + className, + controlGroupStyles, + error, + isInline, + isClickable, + isFocused, + isSubtle, + ] + ); + + return useFlex( { ...flexProps, className: classes } ); +} diff --git a/packages/components/src/base-field/index.js b/packages/components/src/base-field/index.js new file mode 100644 index 0000000000000..6ceae5a2da465 --- /dev/null +++ b/packages/components/src/base-field/index.js @@ -0,0 +1,3 @@ +export { default as BaseField } from './component'; + +export { useBaseField } from './hook'; diff --git a/packages/components/src/base-field/styles.js b/packages/components/src/base-field/styles.js new file mode 100644 index 0000000000000..1856aa2b91c27 --- /dev/null +++ b/packages/components/src/base-field/styles.js @@ -0,0 +1,99 @@ +/** + * External dependencies + */ +import { css } from 'emotion'; + +/** + * Internal dependencies + */ +import { CONFIG, COLORS, reduceMotion } from '../utils'; +import { safariOnly } from '../utils/browsers'; + +export const BaseField = css` + background: ${ CONFIG.controlBackgroundColor }; + border-radius: ${ CONFIG.controlBorderRadius }; + border: 1px solid; + border-color: ${ CONFIG.controlBorderColor }; + box-shadow: ${ CONFIG.controlBoxShadow }; + display: flex; + flex: 1; + font-size: ${ CONFIG.fontSize }; + outline: none; + padding: 0 8px; + position: relative; + transition: border-color ${ CONFIG.transitionDurationFastest } ease; + ${ reduceMotion( 'transition' ) } + width: 100%; + + &[disabled] { + opacity: 0.6; + } + + &:hover { + border-color: ${ CONFIG.controlBorderColorHover }; + } + + &:focus, + &[data-focused='true'] { + border-color: ${ COLORS.admin }; + box-shadow: ${ CONFIG.controlBoxShadowFocus }; + } +`; + +export const clickable = css` + cursor: pointer; +`; + +export const focus = css` + border-color: ${ COLORS.admin }; + box-shadow: ${ CONFIG.controlBoxShadowFocus }; + + &:hover { + border-color: ${ COLORS.admin }; + } +`; + +export const subtle = css` + background-color: transparent; + + &:hover, + &:active, + &:focus, + &[data-focused='true'] { + background: ${ CONFIG.controlBackgroundColor }; + } +`; + +export const error = css` + border-color: ${ CONFIG.controlDestructiveBorderColor }; + + &:hover, + &:active { + border-color: ${ CONFIG.controlDestructiveBorderColor }; + } + + &:focus, + &[data-focused='true'] { + border-color: ${ CONFIG.controlDestructiveBorderColor }; + box-shadow: 0 0 0, 0.5px, ${ CONFIG.controlDestructiveBorderColor }; + } +`; + +export const errorFocus = css` + border-color: ${ CONFIG.controlDestructiveBorderColor }; + box-shadow: 0 0 0, 0.5px, ${ CONFIG.controlDestructiveBorderColor }; + + &:hover { + border-color: ${ CONFIG.controlDestructiveBorderColor }; + } +`; + +export const inline = css` + display: inline-flex; + vertical-align: baseline; + width: auto; + + ${ safariOnly` + vertical-align: middle; + ` } +`; diff --git a/packages/components/src/base-field/test/__snapshots__/index.js.snap b/packages/components/src/base-field/test/__snapshots__/index.js.snap new file mode 100644 index 0000000000000..1466895943f24 --- /dev/null +++ b/packages/components/src/base-field/test/__snapshots__/index.js.snap @@ -0,0 +1,77 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`props should render correctly 1`] = ` +.emotion-0 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; + width: 100%; + background: #fff; + border-radius: 2px; + border: 1px solid; + border-color: #757575; + box-shadow: transparent; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex: 1; + -ms-flex: 1; + flex: 1; + font-size: 13px; + outline: none; + padding: 0 8px; + position: relative; + -webkit-transition: border-color 100ms ease; + transition: border-color 100ms ease; + width: 100%; +} + +.emotion-0 > * + *:not(marquee) { + margin-left: calc(4px * 2); +} + +.emotion-0 > * { + min-width: 0; +} + +@media ( prefers-reduced-motion:reduce ) { + .emotion-0 { + -webkit-transition-duration: 0ms; + transition-duration: 0ms; + } +} + +.emotion-0[disabled] { + opacity: 0.6; +} + +.emotion-0:hover { + border-color: #757575; +} + +.emotion-0:focus, +.emotion-0[data-focused='true'] { + border-color: theme:var( --wp-admin-theme-color,#00669b); + theme-dark10: var( --wp-admin-theme-color-darker-10,#007cba); + box-shadow: 0 0 0,0.5px,[object Object]; +} + +
+`; diff --git a/packages/components/src/base-field/test/index.js b/packages/components/src/base-field/test/index.js new file mode 100644 index 0000000000000..713d4a4f4efbd --- /dev/null +++ b/packages/components/src/base-field/test/index.js @@ -0,0 +1,16 @@ +/** + * External dependencies + */ +import { render } from '@testing-library/react'; + +/** + * Internal dependencies + */ +import { BaseField } from '../index'; + +describe( 'props', () => { + test( 'should render correctly', () => { + const { container } = render( ); + expect( container.firstChild ).toMatchSnapshot(); + } ); +} ); diff --git a/packages/components/src/utils/browsers.js b/packages/components/src/utils/browsers.js new file mode 100644 index 0000000000000..f8e3cae9b4629 --- /dev/null +++ b/packages/components/src/utils/browsers.js @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { css } from 'emotion'; + +/* eslint-disable jsdoc/no-undefined-types */ +/** + * @param {TemplateStringsArray} strings + * @param {import('create-emotion').Interpolation[]} interpolations + */ +export function ieOnly( strings, ...interpolations ) { + const interpolatedStyles = css( strings, ...interpolations ); + + return css` + @media screen and ( -ms-high-contrast: active ), + ( -ms-high-contrast: none ) { + ${ interpolatedStyles }; + } + `; +} + +/** + * @param {TemplateStringsArray} strings + * @param {import('create-emotion').Interpolation[]} interpolations + */ +export function firefoxOnly( strings, ...interpolations ) { + const interpolatedStyles = css( strings, ...interpolations ); + + return css` + @-moz-document url-prefix() { + ${ interpolatedStyles }; + } + `; +} + +/** + * @param {TemplateStringsArray} strings + * @param {import('create-emotion').Interpolation[]} interpolations + */ +export function safariOnly( strings, ...interpolations ) { + const interpolatedStyles = css( strings, ...interpolations ); + + return css` + @media not all and ( min-resolution: 0.001dpcm ) { + @supports ( -webkit-appearance: none ) { + ${ interpolatedStyles } + } + } + `; +} +/* eslint-enable jsdoc/no-undefined-types */ diff --git a/packages/components/src/utils/config-values.js b/packages/components/src/utils/config-values.js index 5dc2245256e61..29885e949456f 100644 --- a/packages/components/src/utils/config-values.js +++ b/packages/components/src/utils/config-values.js @@ -40,6 +40,13 @@ export default { controlPaddingXLarge: `calc(${ CONTROL_PADDING_X } * 1.3334)`, controlPaddingXSmall: `calc(${ CONTROL_PADDING_X } / 1.3334)`, controlBorderRadius: '2px', + controlBackgroundColor: COLORS.white, + controlBorderRadius: '2px', + controlBorderColor: COLORS.gray[ 700 ], + controlBoxShadow: 'transparent', + controlBorderColorHover: COLORS.gray[ 700 ], + controlBoxShadowFocus: `0 0 0, 0.5px, ${ COLORS.admin }`, + controlDestructiveBorderColor: COLORS.alert.red, controlHeight: CONTROL_HEIGHT, controlHeightLarge: `calc( ${ CONTROL_HEIGHT } * 1.2 )`, controlHeightSmall: `calc( ${ CONTROL_HEIGHT } * 0.8 )`, From 665d3233c15dae5fec3ba2ce039c10f23ca5d280 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 27 May 2021 06:40:47 -0700 Subject: [PATCH 02/11] Give better tests and fix types --- packages/components/src/base-field/hook.js | 11 +- .../test/__snapshots__/index.js.snap | 119 +++++++++++++++++- .../components/src/base-field/test/index.js | 72 ++++++++++- packages/components/src/utils/browsers.js | 15 --- .../components/src/utils/config-values.js | 1 - packages/components/tsconfig.json | 1 + 6 files changed, 194 insertions(+), 25 deletions(-) diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index ea8e106555d98..d73c3d5ecadad 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -26,10 +26,10 @@ import * as styles from './styles'; * @property {boolean} [isSubtle=false] Renders a subtle variant. */ -/** @typedef {import('../Flex/useFlex').FlexProps & OwnProps} Props */ +/** @typedef {import('../flex/types').FlexProps & OwnProps} Props */ /** - * @param {import('@wp-g2/create-styles').ViewOwnProps} props + * @param {import('../ui/context').PolymorphicComponentProps} props */ export function useBaseField( props ) { const { @@ -41,6 +41,7 @@ export function useBaseField( props ) { isSubtle = false, // eslint-disable-next-line no-unused-vars defaultValue, // extract this because useFlex doesn't accept it + disabled, ...flexProps } = useContextSystem( props, 'BaseField' ); @@ -70,5 +71,9 @@ export function useBaseField( props ) { ] ); - return useFlex( { ...flexProps, className: classes } ); + return { + ...useFlex( { ...flexProps, className: classes } ), + disabled, + defaultValue, + }; } diff --git a/packages/components/src/base-field/test/__snapshots__/index.js.snap b/packages/components/src/base-field/test/__snapshots__/index.js.snap index 1466895943f24..609462dc96e20 100644 --- a/packages/components/src/base-field/test/__snapshots__/index.js.snap +++ b/packages/components/src/base-field/test/__snapshots__/index.js.snap @@ -1,6 +1,123 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`props should render correctly 1`] = ` +exports[`base field props should render clickable styles 1`] = ` +Snapshot Diff: +- Received styles ++ Base styles + +@@ -15,11 +15,10 @@ + "background": "#fff", + "border": "1px solid", + "border-color": "#757575", + "border-radius": "2px", + "box-shadow": "transparent", +- "cursor": "pointer", + "display": "flex", + "flex": "1", + "flex-direction": "row", + "font-size": "13px", + "justify-content": "space-between", +`; + +exports[`base field props should render error styles 1`] = ` +Snapshot Diff: +- Received styles ++ Base styles + +@@ -12,11 +12,11 @@ + "-webkit-justify-content": "space-between", + "-webkit-transition": "border-color 100ms ease", + "align-items": "center", + "background": "#fff", + "border": "1px solid", +- "border-color": "#d94f4f", ++ "border-color": "#757575", + "border-radius": "2px", + "box-shadow": "transparent", + "display": "flex", + "flex": "1", + "flex-direction": "row", +`; + +exports[`base field props should render focused styles 1`] = ` +Snapshot Diff: +- Received styles ++ Base styles + +@@ -12,21 +12,20 @@ + "-webkit-justify-content": "space-between", + "-webkit-transition": "border-color 100ms ease", + "align-items": "center", + "background": "#fff", + "border": "1px solid", +- "border-color": "theme:var( --wp-admin-theme-color,#00669b)", ++ "border-color": "#757575", + "border-radius": "2px", +- "box-shadow": "0 0 0,0.5px,[object Object]", ++ "box-shadow": "transparent", + "display": "flex", + "flex": "1", + "flex-direction": "row", + "font-size": "13px", + "justify-content": "space-between", + "outline": "none", + "padding": "0 8px", + "position": "relative", +- "theme-dark10": "var( --wp-admin-theme-color-darker-10,#007cba)", + "transition": "border-color 100ms ease", + "width": "100%", + }, + ] +`; + +exports[`base field props should render inline styles 1`] = ` +Snapshot Diff: +- Received styles ++ Base styles + +@@ -15,18 +15,17 @@ + "background": "#fff", + "border": "1px solid", + "border-color": "#757575", + "border-radius": "2px", + "box-shadow": "transparent", +- "display": "inline-flex", ++ "display": "flex", + "flex": "1", + "flex-direction": "row", + "font-size": "13px", + "justify-content": "space-between", + "outline": "none", + "padding": "0 8px", + "position": "relative", + "transition": "border-color 100ms ease", +- "vertical-align": "baseline", +- "width": "auto", ++ "width": "100%", + }, + ] +`; + +exports[`base field props should render subtle styles 1`] = ` +Snapshot Diff: +- Received styles ++ Base styles + +@@ -11,11 +11,10 @@ + "-webkit-flex-direction": "row", + "-webkit-justify-content": "space-between", + "-webkit-transition": "border-color 100ms ease", + "align-items": "center", + "background": "#fff", +- "background-color": "transparent", + "border": "1px solid", + "border-color": "#757575", + "border-radius": "2px", + "box-shadow": "transparent", + "display": "flex", +`; + +exports[`base field should render correctly 1`] = ` .emotion-0 { display: -webkit-box; display: -webkit-flex; diff --git a/packages/components/src/base-field/test/index.js b/packages/components/src/base-field/test/index.js index 713d4a4f4efbd..1a3233b983458 100644 --- a/packages/components/src/base-field/test/index.js +++ b/packages/components/src/base-field/test/index.js @@ -6,11 +6,73 @@ import { render } from '@testing-library/react'; /** * Internal dependencies */ -import { BaseField } from '../index'; +import { BaseField, useBaseField } from '../index'; -describe( 'props', () => { - test( 'should render correctly', () => { - const { container } = render( ); - expect( container.firstChild ).toMatchSnapshot(); +describe( 'base field', () => { + let base; + + beforeEach( () => { + base = render( ).container; + } ); + + it( 'should render correctly', () => { + expect( base.firstChild ).toMatchSnapshot(); + } ); + + describe( 'props', () => { + it( 'should render error styles', () => { + const { container } = render( ); + expect( container.firstChild ).toMatchStyleDiffSnapshot( + base.firstChild + ); + } ); + + it( 'should render clickable styles', () => { + const { container } = render( ); + expect( container.firstChild ).toMatchStyleDiffSnapshot( + base.firstChild + ); + } ); + + it( 'should render focused styles', () => { + const { container } = render( ); + expect( container.firstChild ).toMatchStyleDiffSnapshot( + base.firstChild + ); + } ); + + it( 'should render inline styles', () => { + const { container } = render( ); + expect( container.firstChild ).toMatchStyleDiffSnapshot( + base.firstChild + ); + } ); + + it( 'should render subtle styles', () => { + const { container } = render( ); + expect( container.firstChild ).toMatchStyleDiffSnapshot( + base.firstChild + ); + } ); + } ); + + describe( 'useBaseField', () => { + it( 'should pass through disabled and defaultValue props', () => { + // wrap this in a component so that `useContext` calls don't fail inside the hook + // assertions will still run as normal when we `render` the component :) + const Component = () => { + const disabled = Symbol.for( 'disabled' ); + const defaultValue = Symbol.for( 'defaultValue' ); + + const result = useBaseField( { disabled, defaultValue } ); + + expect( result.disabled ).toBe( disabled ); + expect( result.defaultValue ).toBe( defaultValue ); + + return null; + }; + + render( ); + } ); } ); } ); diff --git a/packages/components/src/utils/browsers.js b/packages/components/src/utils/browsers.js index f8e3cae9b4629..1960eccebfdf7 100644 --- a/packages/components/src/utils/browsers.js +++ b/packages/components/src/utils/browsers.js @@ -4,21 +4,6 @@ import { css } from 'emotion'; /* eslint-disable jsdoc/no-undefined-types */ -/** - * @param {TemplateStringsArray} strings - * @param {import('create-emotion').Interpolation[]} interpolations - */ -export function ieOnly( strings, ...interpolations ) { - const interpolatedStyles = css( strings, ...interpolations ); - - return css` - @media screen and ( -ms-high-contrast: active ), - ( -ms-high-contrast: none ) { - ${ interpolatedStyles }; - } - `; -} - /** * @param {TemplateStringsArray} strings * @param {import('create-emotion').Interpolation[]} interpolations diff --git a/packages/components/src/utils/config-values.js b/packages/components/src/utils/config-values.js index 29885e949456f..28bfb5885df69 100644 --- a/packages/components/src/utils/config-values.js +++ b/packages/components/src/utils/config-values.js @@ -39,7 +39,6 @@ export default { controlPaddingX: CONTROL_PADDING_X, controlPaddingXLarge: `calc(${ CONTROL_PADDING_X } * 1.3334)`, controlPaddingXSmall: `calc(${ CONTROL_PADDING_X } / 1.3334)`, - controlBorderRadius: '2px', controlBackgroundColor: COLORS.white, controlBorderRadius: '2px', controlBorderColor: COLORS.gray[ 700 ], diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index ca00ff32d3db9..12b75796ef73d 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -19,6 +19,7 @@ "include": [ "src/animate/**/*", "src/base-control/**/*", + "src/base-field/**/*", "src/dashicon/**/*", "src/disabled/**/*", "src/divider/**/*", From 871bc6055c95a4516fbc8fa70d998d07fda5c490 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 27 May 2021 06:41:28 -0700 Subject: [PATCH 03/11] Remove unnecessary eslint disable --- packages/components/src/base-field/hook.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index d73c3d5ecadad..bda8a9c5dd710 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -39,8 +39,8 @@ export function useBaseField( props ) { isFocused = false, isInline = false, isSubtle = false, - // eslint-disable-next-line no-unused-vars - defaultValue, // extract this because useFlex doesn't accept it + // extract these because useFlex doesn't accept it + defaultValue, disabled, ...flexProps } = useContextSystem( props, 'BaseField' ); From 4906b27b4071d073bc858ab1974eded39e2cf318 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 27 May 2021 08:13:08 -0700 Subject: [PATCH 04/11] Remove isFocused prop --- packages/components/src/base-field/hook.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index bda8a9c5dd710..c20afd4346baa 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -21,7 +21,6 @@ import * as styles from './styles'; * @property {boolean} [error=false] Renders an error. * @property {boolean} [disabled] Whether the field is disabled. * @property {boolean} [isClickable=false] Renders a `cursor: pointer` on hover. - * @property {boolean} [isFocused=false] Renders focus styles. * @property {boolean} [isInline=false] Renders as an inline element (layout). * @property {boolean} [isSubtle=false] Renders a subtle variant. */ @@ -36,7 +35,6 @@ export function useBaseField( props ) { className, error = false, isClickable = false, - isFocused = false, isInline = false, isSubtle = false, // extract these because useFlex doesn't accept it @@ -53,10 +51,8 @@ export function useBaseField( props ) { styles.BaseField, controlGroupStyles, isClickable && styles.clickable, - isFocused && styles.focus, isSubtle && styles.subtle, error && styles.error, - error && isFocused && styles.errorFocus, isInline && styles.inline, className ), @@ -66,7 +62,6 @@ export function useBaseField( props ) { error, isInline, isClickable, - isFocused, isSubtle, ] ); From ab7d26a7f0f88e6a8ac121d4f0813b26eff61835 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 27 May 2021 08:13:53 -0700 Subject: [PATCH 05/11] Rename error to include a verb --- packages/components/src/base-field/hook.js | 8 ++++---- packages/components/src/base-field/test/index.js | 9 +-------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index c20afd4346baa..8f168ac465061 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -18,7 +18,7 @@ import * as styles from './styles'; /** * @typedef OwnProps - * @property {boolean} [error=false] Renders an error. + * @property {boolean} [hasError=false] Renders an error. * @property {boolean} [disabled] Whether the field is disabled. * @property {boolean} [isClickable=false] Renders a `cursor: pointer` on hover. * @property {boolean} [isInline=false] Renders as an inline element (layout). @@ -33,7 +33,7 @@ import * as styles from './styles'; export function useBaseField( props ) { const { className, - error = false, + hasError = false, isClickable = false, isInline = false, isSubtle = false, @@ -52,14 +52,14 @@ export function useBaseField( props ) { controlGroupStyles, isClickable && styles.clickable, isSubtle && styles.subtle, - error && styles.error, + hasError && styles.error, isInline && styles.inline, className ), [ className, controlGroupStyles, - error, + hasError, isInline, isClickable, isSubtle, diff --git a/packages/components/src/base-field/test/index.js b/packages/components/src/base-field/test/index.js index 1a3233b983458..4b1be4deb4cd7 100644 --- a/packages/components/src/base-field/test/index.js +++ b/packages/components/src/base-field/test/index.js @@ -21,7 +21,7 @@ describe( 'base field', () => { describe( 'props', () => { it( 'should render error styles', () => { - const { container } = render( ); + const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot( base.firstChild ); @@ -34,13 +34,6 @@ describe( 'base field', () => { ); } ); - it( 'should render focused styles', () => { - const { container } = render( ); - expect( container.firstChild ).toMatchStyleDiffSnapshot( - base.firstChild - ); - } ); - it( 'should render inline styles', () => { const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot( From 94943caebb91383c7fb9b1d9fd10a2d8d96a6189 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 27 May 2021 08:59:57 -0700 Subject: [PATCH 06/11] Fix admin colors --- packages/components/src/base-field/styles.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/src/base-field/styles.js b/packages/components/src/base-field/styles.js index 1856aa2b91c27..0cbcffe46c98e 100644 --- a/packages/components/src/base-field/styles.js +++ b/packages/components/src/base-field/styles.js @@ -35,7 +35,7 @@ export const BaseField = css` &:focus, &[data-focused='true'] { - border-color: ${ COLORS.admin }; + border-color: ${ COLORS.admin.theme }; box-shadow: ${ CONFIG.controlBoxShadowFocus }; } `; @@ -45,11 +45,11 @@ export const clickable = css` `; export const focus = css` - border-color: ${ COLORS.admin }; + border-color: ${ COLORS.admin.theme }; box-shadow: ${ CONFIG.controlBoxShadowFocus }; &:hover { - border-color: ${ COLORS.admin }; + border-color: ${ COLORS.admin.theme }; } `; From e5f3cb681c3939416bfccd41e058361c93fadc5c Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Thu, 27 May 2021 09:02:10 -0700 Subject: [PATCH 07/11] Remove unused manual focus styles --- packages/components/src/base-field/styles.js | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/components/src/base-field/styles.js b/packages/components/src/base-field/styles.js index 0cbcffe46c98e..a1b90ec1f9ddd 100644 --- a/packages/components/src/base-field/styles.js +++ b/packages/components/src/base-field/styles.js @@ -44,15 +44,6 @@ export const clickable = css` cursor: pointer; `; -export const focus = css` - border-color: ${ COLORS.admin.theme }; - box-shadow: ${ CONFIG.controlBoxShadowFocus }; - - &:hover { - border-color: ${ COLORS.admin.theme }; - } -`; - export const subtle = css` background-color: transparent; From ebc21dca56fe17c1a294c37844e38ed3154f146b Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Fri, 28 May 2021 08:00:52 -0700 Subject: [PATCH 08/11] Fix README for removed/updated props --- packages/components/src/base-field/README.md | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/packages/components/src/base-field/README.md b/packages/components/src/base-field/README.md index 32b4e3a849ddd..228cd32842924 100644 --- a/packages/components/src/base-field/README.md +++ b/packages/components/src/base-field/README.md @@ -50,7 +50,7 @@ function ExampleField( props, forwardRef ) { ## Props -### `error`: `boolean` +### `hasError`: `boolean` Renders an error style around the component. @@ -58,14 +58,6 @@ Renders an error style around the component. Whether the field is disabled. -### `isClickable`: `boolean` - -Renders a `cursor: pointer` on hover; - -### `isFocused`: `boolean` - -Renders focus styles around the component. - ### `isInline`: `boolean` Renders a component that can be inlined in some text. From aaeb99aeff7f9f160d605fa4ece1c6d71680bd2c Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Fri, 28 May 2021 08:06:19 -0700 Subject: [PATCH 09/11] Remove component and update tests --- .../components/src/base-field/component.js | 14 -------- packages/components/src/base-field/index.js | 2 -- .../test/__snapshots__/index.js.snap | 34 +------------------ .../components/src/base-field/test/index.js | 17 ++++++---- 4 files changed, 12 insertions(+), 55 deletions(-) delete mode 100644 packages/components/src/base-field/component.js diff --git a/packages/components/src/base-field/component.js b/packages/components/src/base-field/component.js deleted file mode 100644 index 1fb0fcacb612b..0000000000000 --- a/packages/components/src/base-field/component.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Internal dependencies - */ -import { createComponent } from '../ui/utils'; -import { useBaseField } from './hook'; - -/** - * `BaseField` is a primitive component used to create form element components (e.g. `TextInput`). - */ -export default createComponent( { - as: 'div', - useHook: useBaseField, - name: 'BaseField', -} ); diff --git a/packages/components/src/base-field/index.js b/packages/components/src/base-field/index.js index 6ceae5a2da465..263e623dae316 100644 --- a/packages/components/src/base-field/index.js +++ b/packages/components/src/base-field/index.js @@ -1,3 +1 @@ -export { default as BaseField } from './component'; - export { useBaseField } from './hook'; diff --git a/packages/components/src/base-field/test/__snapshots__/index.js.snap b/packages/components/src/base-field/test/__snapshots__/index.js.snap index 609462dc96e20..8fcad90210405 100644 --- a/packages/components/src/base-field/test/__snapshots__/index.js.snap +++ b/packages/components/src/base-field/test/__snapshots__/index.js.snap @@ -39,37 +39,6 @@ Snapshot Diff: "flex-direction": "row", `; -exports[`base field props should render focused styles 1`] = ` -Snapshot Diff: -- Received styles -+ Base styles - -@@ -12,21 +12,20 @@ - "-webkit-justify-content": "space-between", - "-webkit-transition": "border-color 100ms ease", - "align-items": "center", - "background": "#fff", - "border": "1px solid", -- "border-color": "theme:var( --wp-admin-theme-color,#00669b)", -+ "border-color": "#757575", - "border-radius": "2px", -- "box-shadow": "0 0 0,0.5px,[object Object]", -+ "box-shadow": "transparent", - "display": "flex", - "flex": "1", - "flex-direction": "row", - "font-size": "13px", - "justify-content": "space-between", - "outline": "none", - "padding": "0 8px", - "position": "relative", -- "theme-dark10": "var( --wp-admin-theme-color-darker-10,#007cba)", - "transition": "border-color 100ms ease", - "width": "100%", - }, - ] -`; - exports[`base field props should render inline styles 1`] = ` Snapshot Diff: - Received styles @@ -181,8 +150,7 @@ exports[`base field should render correctly 1`] = ` .emotion-0:focus, .emotion-0[data-focused='true'] { - border-color: theme:var( --wp-admin-theme-color,#00669b); - theme-dark10: var( --wp-admin-theme-color-darker-10,#007cba); + border-color: var( --wp-admin-theme-color,#00669b); box-shadow: 0 0 0,0.5px,[object Object]; } diff --git a/packages/components/src/base-field/test/index.js b/packages/components/src/base-field/test/index.js index 4b1be4deb4cd7..f0916d70f0cab 100644 --- a/packages/components/src/base-field/test/index.js +++ b/packages/components/src/base-field/test/index.js @@ -6,13 +6,18 @@ import { render } from '@testing-library/react'; /** * Internal dependencies */ -import { BaseField, useBaseField } from '../index'; +import { useBaseField } from '../index'; +import { View } from '../../view'; + +const TestField = ( props ) => { + return ; +}; describe( 'base field', () => { let base; beforeEach( () => { - base = render( ).container; + base = render( ).container; } ); it( 'should render correctly', () => { @@ -21,28 +26,28 @@ describe( 'base field', () => { describe( 'props', () => { it( 'should render error styles', () => { - const { container } = render( ); + const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot( base.firstChild ); } ); it( 'should render clickable styles', () => { - const { container } = render( ); + const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot( base.firstChild ); } ); it( 'should render inline styles', () => { - const { container } = render( ); + const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot( base.firstChild ); } ); it( 'should render subtle styles', () => { - const { container } = render( ); + const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot( base.firstChild ); From c4349bff81d7000acc6a6f1cd822d3284da97d93 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Fri, 28 May 2021 09:37:52 -0700 Subject: [PATCH 10/11] Update packages/components/src/base-field/hook.js Co-authored-by: Marco Ciampini --- packages/components/src/base-field/hook.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index 8f168ac465061..6ebef7cd6fc81 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -20,7 +20,6 @@ import * as styles from './styles'; * @typedef OwnProps * @property {boolean} [hasError=false] Renders an error. * @property {boolean} [disabled] Whether the field is disabled. - * @property {boolean} [isClickable=false] Renders a `cursor: pointer` on hover. * @property {boolean} [isInline=false] Renders as an inline element (layout). * @property {boolean} [isSubtle=false] Renders a subtle variant. */ From 94a8378f5fc6ede598530992d4ff3eb30f25ca89 Mon Sep 17 00:00:00 2001 From: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com> Date: Fri, 28 May 2021 11:42:05 -0700 Subject: [PATCH 11/11] Fully remove isClickable --- packages/components/src/base-field/hook.js | 11 +---------- packages/components/src/base-field/styles.js | 4 ---- .../test/__snapshots__/index.js.snap | 19 ------------------- .../components/src/base-field/test/index.js | 7 ------- 4 files changed, 1 insertion(+), 40 deletions(-) diff --git a/packages/components/src/base-field/hook.js b/packages/components/src/base-field/hook.js index 6ebef7cd6fc81..479b545509e7e 100644 --- a/packages/components/src/base-field/hook.js +++ b/packages/components/src/base-field/hook.js @@ -33,7 +33,6 @@ export function useBaseField( props ) { const { className, hasError = false, - isClickable = false, isInline = false, isSubtle = false, // extract these because useFlex doesn't accept it @@ -49,20 +48,12 @@ export function useBaseField( props ) { cx( styles.BaseField, controlGroupStyles, - isClickable && styles.clickable, isSubtle && styles.subtle, hasError && styles.error, isInline && styles.inline, className ), - [ - className, - controlGroupStyles, - hasError, - isInline, - isClickable, - isSubtle, - ] + [ className, controlGroupStyles, hasError, isInline, isSubtle ] ); return { diff --git a/packages/components/src/base-field/styles.js b/packages/components/src/base-field/styles.js index a1b90ec1f9ddd..fb9ae36ae504f 100644 --- a/packages/components/src/base-field/styles.js +++ b/packages/components/src/base-field/styles.js @@ -40,10 +40,6 @@ export const BaseField = css` } `; -export const clickable = css` - cursor: pointer; -`; - export const subtle = css` background-color: transparent; diff --git a/packages/components/src/base-field/test/__snapshots__/index.js.snap b/packages/components/src/base-field/test/__snapshots__/index.js.snap index 8fcad90210405..0b96ea827142e 100644 --- a/packages/components/src/base-field/test/__snapshots__/index.js.snap +++ b/packages/components/src/base-field/test/__snapshots__/index.js.snap @@ -1,24 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`base field props should render clickable styles 1`] = ` -Snapshot Diff: -- Received styles -+ Base styles - -@@ -15,11 +15,10 @@ - "background": "#fff", - "border": "1px solid", - "border-color": "#757575", - "border-radius": "2px", - "box-shadow": "transparent", -- "cursor": "pointer", - "display": "flex", - "flex": "1", - "flex-direction": "row", - "font-size": "13px", - "justify-content": "space-between", -`; - exports[`base field props should render error styles 1`] = ` Snapshot Diff: - Received styles diff --git a/packages/components/src/base-field/test/index.js b/packages/components/src/base-field/test/index.js index f0916d70f0cab..b5ed5ef4b05fa 100644 --- a/packages/components/src/base-field/test/index.js +++ b/packages/components/src/base-field/test/index.js @@ -32,13 +32,6 @@ describe( 'base field', () => { ); } ); - it( 'should render clickable styles', () => { - const { container } = render( ); - expect( container.firstChild ).toMatchStyleDiffSnapshot( - base.firstChild - ); - } ); - it( 'should render inline styles', () => { const { container } = render( ); expect( container.firstChild ).toMatchStyleDiffSnapshot(