@planningcenter/tapestry-react 2.6.0-rc.8 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/cjs/Button/Button.js +8 -1
  2. package/dist/cjs/Button/Button.test.js +51 -8
  3. package/dist/cjs/DataTable/DataTable.js +3 -3
  4. package/dist/cjs/DataTable/components/BodyRow.js +2 -2
  5. package/dist/cjs/DataTable/components/BodyRows.js +2 -2
  6. package/dist/cjs/DataTable/components/BodySubRows.js +2 -2
  7. package/dist/cjs/DataTable/components/CheckboxCell.js +4 -4
  8. package/dist/cjs/DataTable/hooks/useCollapsibleRows.js +2 -2
  9. package/dist/cjs/Dropdown/Dropdown.js +5 -3
  10. package/dist/cjs/Dropdown/Dropdown.test.js +3 -3
  11. package/dist/cjs/Dropdown/Link.js +2 -4
  12. package/dist/cjs/Input/InputLabel.js +40 -63
  13. package/dist/cjs/Modal/Modal.js +15 -7
  14. package/dist/cjs/Modal/Modal.test.js +2 -2
  15. package/dist/cjs/Popover/Popover.js +10 -2
  16. package/dist/cjs/Scrim/Scrim.js +16 -4
  17. package/dist/cjs/Table/Table.js +5 -3
  18. package/dist/cjs/ThemeProvider/ThemeProvider.js +14 -5
  19. package/dist/cjs/ThemeProvider/styles.js +1 -1
  20. package/dist/cjs/TimeField/TimeField.js +1 -1
  21. package/dist/cjs/Tooltip/Tooltip.js +27 -23
  22. package/dist/cjs/system/split-styles.js +1 -1
  23. package/dist/cjs/system/utils.js +2 -2
  24. package/dist/cjs/utils.js +3 -3
  25. package/dist/esm/Button/Button.js +8 -1
  26. package/dist/esm/Button/Button.test.js +67 -9
  27. package/dist/esm/DataTable/DataTable.js +3 -3
  28. package/dist/esm/DataTable/components/BodyRow.js +2 -2
  29. package/dist/esm/DataTable/components/BodyRows.js +2 -2
  30. package/dist/esm/DataTable/components/BodySubRows.js +2 -2
  31. package/dist/esm/DataTable/components/CheckboxCell.js +4 -4
  32. package/dist/esm/DataTable/hooks/useCollapsibleRows.js +1 -1
  33. package/dist/esm/Dropdown/Dropdown.js +6 -4
  34. package/dist/esm/Dropdown/Dropdown.test.js +1 -1
  35. package/dist/esm/Dropdown/Link.js +1 -2
  36. package/dist/esm/Input/InputLabel.js +40 -63
  37. package/dist/esm/Modal/Modal.js +13 -7
  38. package/dist/esm/Modal/Modal.test.js +1 -1
  39. package/dist/esm/Popover/Popover.js +8 -2
  40. package/dist/esm/Scrim/Scrim.js +15 -4
  41. package/dist/esm/Table/Table.js +2 -1
  42. package/dist/esm/ThemeProvider/ThemeProvider.js +14 -5
  43. package/dist/esm/ThemeProvider/styles.js +1 -1
  44. package/dist/esm/TimeField/TimeField.js +1 -1
  45. package/dist/esm/Tooltip/Tooltip.js +29 -24
  46. package/dist/esm/system/split-styles.js +1 -1
  47. package/dist/esm/system/utils.js +1 -1
  48. package/dist/esm/utils.js +1 -1
  49. package/dist/types/Button/Button.d.ts +4 -0
  50. package/dist/types/ThemeProvider/ThemeProvider.d.ts +3 -3
  51. package/dist/types/index.d.ts +1 -1
  52. package/package.json +4 -4
  53. package/src/Button/Button.test.tsx +30 -0
  54. package/src/Button/Button.tsx +14 -1
  55. package/src/DataTable/DataTable.js +10 -4
  56. package/src/DataTable/components/BodyRow.js +1 -1
  57. package/src/DataTable/components/BodyRows.js +5 -2
  58. package/src/DataTable/components/BodySubRows.js +5 -2
  59. package/src/DataTable/components/CheckboxCell.js +4 -4
  60. package/src/DataTable/hooks/useCollapsibleRows.js +1 -1
  61. package/src/Dropdown/Dropdown.js +7 -4
  62. package/src/Dropdown/Dropdown.mdx +3 -3
  63. package/src/Dropdown/Dropdown.test.tsx +1 -1
  64. package/src/Dropdown/Link.js +1 -7
  65. package/src/Input/InputLabel.js +39 -36
  66. package/src/Input/InputLabel.mdx +1 -0
  67. package/src/Modal/Modal.js +12 -4
  68. package/src/Modal/Modal.mdx +2 -1
  69. package/src/Modal/Modal.test.tsx +1 -1
  70. package/src/Popover/Popover.mdx +1 -0
  71. package/src/Popover/Popover.tsx +8 -2
  72. package/src/Scrim/Scrim.mdx +1 -0
  73. package/src/Scrim/Scrim.tsx +11 -6
  74. package/src/Sidebar/Sidebar.mdx +0 -1
  75. package/src/Table/Table.js +2 -1
  76. package/src/ThemeProvider/ThemeProvider.tsx +15 -10
  77. package/src/ThemeProvider/styles.ts +18 -8
  78. package/src/TimeField/TimeField.js +1 -1
  79. package/src/Tooltip/Tooltip.js +19 -21
  80. package/src/index.d.ts +1 -1
  81. package/src/system/split-styles.js +3 -1
  82. package/src/system/utils.js +1 -1
  83. package/src/utils.js +1 -1
@@ -9,7 +9,7 @@ import Popover from '../Popover'
9
9
  import { cloneChildren, generateId } from '../utils'
10
10
 
11
11
  import Item, { ITEM_DISPLAY_NAME } from './Item'
12
- import Link, { LINK_DISPLAY_NAME, LINK_DATA } from './Link'
12
+ import Link, { LINK_DISPLAY_NAME } from './Link'
13
13
 
14
14
  type Props = {
15
15
  children?: React.ReactNode,
@@ -125,7 +125,7 @@ class Dropdown extends Component<Props> {
125
125
  this.closePopover()
126
126
  this.popover.focusAnchor()
127
127
  }
128
- if (data === LINK_DATA) {
128
+ if (node.tagName === 'A' && event.type !== 'click') {
129
129
  node.click()
130
130
  } else if (this.props.onSelect) {
131
131
  this.props.onSelect(data)
@@ -215,18 +215,21 @@ class Dropdown extends Component<Props> {
215
215
  'aria-haspopup': true,
216
216
  'aria-expanded': isPopoverOpen,
217
217
  [arrowIconOnly ? 'icon' : 'iconRight']: {
218
- name: isPopoverOpen ? 'general.upCaret' : 'general.downCaret',
218
+ name: isPopoverOpen
219
+ ? 'general.upCaret'
220
+ : 'general.downCaret',
219
221
  size: 'sm',
220
222
  },
221
223
  title: arrowIconOnly ? 'arrow down' : restProps.title,
222
224
  tabIndex: 0,
223
225
  cursor: 'pointer',
224
226
  onBlur: requestBlur,
225
- onClick: () => {
227
+ onClick: (event) => {
226
228
  this.togglePopover()
227
229
  if (!isPopoverOpen) {
228
230
  this.popover.focusAnchor()
229
231
  }
232
+ onClick && onClick(event)
230
233
  },
231
234
  onKeyDown: (event) => {
232
235
  anchorProps.onKeyDown(event)
@@ -26,10 +26,10 @@ render(
26
26
  render(
27
27
  <Dropdown title="Links" size="sm" variant="outline">
28
28
  <Dropdown.Link to="http://planning.center" external>
29
- Planning Center
29
+ Planning Center (external)
30
30
  </Dropdown.Link>
31
- <Dropdown.Link to="https://reactjs.org" external>
32
- React Docs
31
+ <Dropdown.Link to="/button">
32
+ Tapestry React Button
33
33
  </Dropdown.Link>
34
34
  </Dropdown>
35
35
  )
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
2
2
  import { fireEvent, render, screen } from '@testing-library/react'
3
3
  import userEvent from '@testing-library/user-event'
4
4
  import '@testing-library/jest-dom/extend-expect'
5
- import { noop } from 'lodash'
5
+ import noop from 'lodash/noop'
6
6
  import { Box, Button, Text, ThemeProvider } from '..'
7
7
  import Dropdown from './Dropdown'
8
8
 
@@ -4,7 +4,6 @@ import { ItemListItem } from '../ItemList'
4
4
  import Menu from '../Menu'
5
5
 
6
6
  export const LINK_DISPLAY_NAME = 'Dropdown.Link'
7
- export const LINK_DATA = 'link'
8
7
 
9
8
  class Link extends Component {
10
9
  // Graphql wasn't picking up the correct displayName when this was
@@ -17,12 +16,7 @@ class Link extends Component {
17
16
  restProps.target = '_blank'
18
17
  }
19
18
  return (
20
- <ItemListItem
21
- data={LINK_DATA}
22
- text={text}
23
- disabled={disabled}
24
- index={index}
25
- >
19
+ <ItemListItem data="link" text={text} disabled={disabled} index={index}>
26
20
  {({ id, highlight, highlighted, clearHighlight, select }) => (
27
21
  <Menu.Item
28
22
  as="a"
@@ -1,8 +1,9 @@
1
1
  // @flow
2
- import React, { Component } from 'react'
2
+ import React, { useCallback, useRef, useEffect } from 'react'
3
3
 
4
4
  import { getColor } from '../system'
5
5
  import Text from '../Text'
6
+ import { useThemeProps } from '../system'
6
7
 
7
8
  import { inputs, inputLabels } from './utils'
8
9
 
@@ -10,54 +11,56 @@ export type InputLabelProps = {
10
11
  /**
11
12
  * The `id` of the input to control. Compatible with all Tapestry-React form components.
12
13
  */
13
- controls: string,
14
+ controls?: string,
14
15
 
15
16
  /**
16
17
  * The current state of the label. Should match corresponding `Input`'s state prop.
17
18
  */
18
- state: 'warning' | 'error' | 'success',
19
+ state?: 'warning' | 'error' | 'success',
19
20
  }
20
21
 
21
- class InputLabel extends Component<InputLabelProps> {
22
- componentDidMount() {
23
- this.input = inputs[this.props.controls]
24
- inputLabels[this.props.controls] = true
25
- }
22
+ function InputLabel({ controls, state, ...restProps }: InputLabelProps) {
23
+ const { ...themeProps } = useThemeProps('inputLabel', restProps)
26
24
 
27
- componentWillUnmount() {
28
- delete inputLabels[this.props.controls]
29
- }
25
+ const input = useRef(null)
30
26
 
31
- focusInput = () => {
32
- this.input && this.input.focus()
27
+ if (controls) {
28
+ themeProps.id = `${controls}-label`
33
29
  }
34
-
35
- handleMouseOver = () => {
36
- this.input && this.input.setState({ isHovered: true })
30
+ if (state) {
31
+ themeProps.color = getColor(state)
37
32
  }
38
33
 
39
- handleMouseOut = () => {
40
- this.input && this.input.setState({ isHovered: false })
41
- }
34
+ useEffect(() => {
35
+ input.current = inputs[controls]
36
+ inputLabels[controls] = true
42
37
 
43
- render() {
44
- const { controls, state, ...restProps } = this.props
45
- if (controls) {
46
- restProps.id = `${controls}-label`
47
- }
48
- if (state) {
49
- restProps.color = getColor(state)
38
+ return () => {
39
+ delete inputLabels[controls]
50
40
  }
51
- return (
52
- <Text
53
- as="label"
54
- onMouseOver={this.handleMouseOver}
55
- onMouseOut={this.handleMouseOut}
56
- onClick={this.focusInput}
57
- {...restProps}
58
- />
59
- )
60
- }
41
+ }, [])
42
+
43
+ const focusInput = useCallback(() => {
44
+ input.current && input.current.focus()
45
+ }, [input])
46
+
47
+ const handleMouseOver = useCallback(() => {
48
+ input.current && input.current.setState({ isHovered: true })
49
+ }, [input])
50
+
51
+ const handleMouseOut = useCallback(() => {
52
+ input.current && input.current.setState({ isHovered: false })
53
+ }, [input])
54
+
55
+ return (
56
+ <Text
57
+ as="label"
58
+ onMouseOver={handleMouseOver}
59
+ onMouseOut={handleMouseOut}
60
+ onClick={focusInput}
61
+ {...themeProps}
62
+ />
63
+ )
61
64
  }
62
65
 
63
66
  InputLabel.displayName = 'Input.InputLabel'
@@ -4,6 +4,7 @@ category: Forms
4
4
  summary: Provides accessibility as well as usability improvements for mouse users by allowing the user to click the <InputLabel/> component to focus the respective control. This mimics the browsers native label tag, but allows use with custom components like <Select/>.
5
5
  propsSummary: Accepts [Text](/text) props.
6
6
  parent: Input
7
+ themeKey: inputLabel
7
8
  ---
8
9
 
9
10
  ```jsx live
@@ -5,6 +5,7 @@ import Box from '../Box'
5
5
  import Scrim from '../Scrim'
6
6
  import { useDocumentEvent } from '../hooks'
7
7
  import { trapFocus } from '../utils'
8
+ import { useThemeProps } from '../system'
8
9
 
9
10
  export type ModalProps = {
10
11
  children?: any,
@@ -23,6 +24,11 @@ export type ModalProps = {
23
24
  * Determines whether the modal is open or not.
24
25
  */
25
26
  open: boolean,
27
+
28
+ /**
29
+ * Props passed to the internal [`<Scrim/>`](/scrim) component.
30
+ */
31
+ scrimProps?: object,
26
32
  }
27
33
 
28
34
  function Modal({
@@ -32,6 +38,7 @@ function Modal({
32
38
  open,
33
39
  ...restProps
34
40
  }: ModalProps) {
41
+ const { scrimProps = {}, ...themeProps } = useThemeProps('modal', restProps)
35
42
  const modalRef = useRef(null)
36
43
 
37
44
  useLayoutEffect(() => {
@@ -58,16 +65,17 @@ function Modal({
58
65
  onRequestClose()
59
66
  }
60
67
  }}
68
+ {...scrimProps}
61
69
  >
62
70
  <Box
71
+ backgroundColor="surface"
63
72
  innerRef={modalRef}
64
- width="100%"
73
+ margin={4}
65
74
  maxWidth={60}
66
75
  padding={2}
67
- margin={4}
68
- backgroundColor="surface"
69
76
  radius={3}
70
- {...restProps}
77
+ width="100%"
78
+ {...themeProps}
71
79
  >
72
80
  {children}
73
81
  </Box>
@@ -2,6 +2,7 @@
2
2
  title: Modal
3
3
  category: Overlays
4
4
  propsSummary: Accepts [Box](/box) props.
5
+ themeKey: modal
5
6
  ---
6
7
 
7
8
  ```jsx live
@@ -16,7 +17,7 @@ function MyModal(props) {
16
17
  return () => setLazyComponent(null)
17
18
  }, [props.open])
18
19
  return (
19
- <Modal id="modal" closeOnOutsideClick height={200} {...props}>
20
+ <Modal id="modal" closeOnOutsideClick height={25} {...props}>
20
21
  <StackView spacing={2}>
21
22
  {lazyComponent || <Text>Loading lazy component...</Text>}
22
23
  <Select
@@ -5,7 +5,7 @@ import '@testing-library/jest-dom/extend-expect'
5
5
  import Dropdown from '../Dropdown'
6
6
  import Select from '../Select'
7
7
  import { Button, Heading, Modal, ThemeProvider } from '../'
8
- import { noop } from 'lodash'
8
+ import noop from 'lodash/noop'
9
9
 
10
10
  describe('Modal', () => {
11
11
  const TestModal = () => {
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  title: Popover
3
3
  category: Overlays
4
+ themeKey: popover
4
5
  ---
5
6
 
6
7
  ```jsx live
@@ -7,6 +7,8 @@ import { lockScroll } from '../utils'
7
7
 
8
8
  import rewireTabOrder from './rewireTabOrder'
9
9
  import { getFixedParent, getModifiers } from './utils'
10
+ import { useThemeProps } from '../system'
11
+ import { useTheme } from '@emotion/react'
10
12
 
11
13
  type anchorCallbackProps = {
12
14
  innerRef(node: HTMLElement): void
@@ -116,6 +118,10 @@ export const Popover = React.forwardRef(
116
118
  }: PopoverProps,
117
119
  ref
118
120
  ) => {
121
+ const { zIndex = 10000, ...themeProps } = useThemeProps(
122
+ 'popover',
123
+ restProps
124
+ )
119
125
  const anchorRef = React.useRef(null)
120
126
  const popperRef = React.useRef(null)
121
127
  const unlockScroll = React.useRef(null)
@@ -253,8 +259,8 @@ export const Popover = React.forwardRef(
253
259
  }
254
260
  },
255
261
  // ideally this should be pulled out to something like ThemeProvider for predictable z indices
256
- style: { zIndex: 10000 },
257
- ...restProps,
262
+ style: { zIndex },
263
+ ...themeProps,
258
264
  })
259
265
  : null}
260
266
  </Portal>
@@ -3,6 +3,7 @@ title: Scrim
3
3
  category: Overlays
4
4
  summary: Scrims are used to display focused content like alerts, modals, or media previews.
5
5
  propsSummary: Accepts [StackView](/stackview) props.
6
+ themeKey: scrim
6
7
  ---
7
8
 
8
9
  ```jsx live
@@ -1,33 +1,38 @@
1
1
  import * as React from 'react'
2
2
 
3
3
  import StackView from '../StackView'
4
+ import { useThemeProps } from '../system'
4
5
 
5
6
  type ScrimProps = {
6
7
  /** Gain access to the internal ref. */
7
- ref?: any,
8
- children?: any,
8
+ ref?: any
9
+ children?: any
9
10
  }
10
11
 
11
- const Scrim = React.forwardRef(function (props: ScrimProps, _ref: any) {
12
+ const Scrim = React.forwardRef(function (
13
+ { ref, ...restProps }: ScrimProps,
14
+ _ref: any
15
+ ) {
12
16
  React.useLayoutEffect(() => {
13
17
  document.body.style.overflow = 'hidden'
14
18
  return () => {
15
19
  document.body.style.overflow = ''
16
20
  }
17
21
  }, [])
22
+ const { zIndex = 10000, ...themeProps } = useThemeProps('scrim', restProps)
18
23
  return (
19
24
  <StackView
20
- innerRef={props.ref}
25
+ innerRef={ref}
21
26
  position="fixed"
22
27
  top={0}
23
28
  right={0}
24
29
  bottom={0}
25
30
  left={0}
26
- zIndex={10000}
31
+ zIndex={zIndex}
27
32
  overflow="auto"
28
33
  // @ts-ignore
29
34
  backgroundColor="hsla(0,0%,0%,0.4)"
30
- {...props}
35
+ {...themeProps}
31
36
  />
32
37
  )
33
38
  })
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Sidebar
3
3
  category: General
4
- propsSummary: Accepts [StackView](/stackview) props.
5
4
  ---
6
5
 
7
6
  ```jsx live
@@ -1,7 +1,8 @@
1
1
  // @flow
2
2
  import React, { PureComponent, Children, Fragment } from 'react'
3
3
  import { Global } from '@emotion/react'
4
- import { camelCase, snakeCase } from 'lodash'
4
+ import camelCase from 'lodash/camelCase'
5
+ import snakeCase from 'lodash/snakeCase'
5
6
 
6
7
  import type { PaginationProps } from '../Pagination/Pagination'
7
8
 
@@ -2,7 +2,7 @@ import React, { useLayoutEffect, useState } from 'react'
2
2
  import { ThemeProvider as EmotionThemeProvider } from '@emotion/react'
3
3
  import { CacheProvider } from '@emotion/react'
4
4
  import createCache from '@emotion/cache'
5
- import { merge } from 'lodash'
5
+ import merge from 'lodash/merge'
6
6
  import { Box, BoxProps } from '../Box'
7
7
 
8
8
  import defaultTheme from '../system/default-theme'
@@ -17,6 +17,10 @@ export const cache = createCache({
17
17
  key: 'tapestry-react',
18
18
  })
19
19
 
20
+ function mergeIntoNewObject(...merges: object[]) {
21
+ return merge({}, ...merges)
22
+ }
23
+
20
24
  export const themeStorage = {
21
25
  get: () => window.localStorage.getItem(STORAGE_KEY),
22
26
  set: (value) => window.localStorage.setItem(STORAGE_KEY, value),
@@ -39,30 +43,31 @@ function mergeThemes(a: Theme = {}, b: Theme = {}) {
39
43
  button: {
40
44
  ...a.button,
41
45
  ...b.button,
42
- themes: merge(a.button?.themes || {}, b.button?.themes || {}),
46
+ themes: mergeIntoNewObject(a.button?.themes || {}, b.button?.themes || {}),
43
47
  },
44
- colors: merge(
48
+ colors: mergeIntoNewObject(
45
49
  flattenPalette(a.colors || {}),
46
50
  flattenPalette(b.colors || {})
47
51
  ),
48
52
  spinner: {
49
53
  ...a.spinner,
50
54
  ...b.spinner,
51
- sizes: merge(a.spinner?.sizes || {}, b.spinner?.sizes || {}),
52
- thickness: merge(a.spinner?.thickness || {}, b.spinner?.thickness || {}),
55
+ sizes: mergeIntoNewObject(a.spinner?.sizes || {}, b.spinner?.sizes || {}),
56
+ thickness: mergeIntoNewObject(a.spinner?.thickness || {}, b.spinner?.thickness || {}),
53
57
  },
54
58
  }
55
59
  }
56
60
 
61
+ type Props = {
62
+ theme?: Theme
63
+ children: React.ReactNode
64
+ } & BoxProps
65
+
57
66
  export function ThemeProvider({
58
67
  theme = emptyTheme,
59
68
  children,
60
69
  ...boxProps
61
- }: {
62
- theme?: Theme
63
- children: React.ReactNode
64
- boxProps?: BoxProps
65
- }) {
70
+ }: Props) {
66
71
  const [mergedTheme, setMergedTheme] = useState(() =>
67
72
  mergeThemes(defaultTheme, theme)
68
73
  )
@@ -37,7 +37,7 @@ export const defaultColorProperties = objectToCSSProperties(
37
37
  export const styleReset = `
38
38
  ${getRootStyles(null, defaultColorProperties)}
39
39
 
40
- .tapestry-react-reset * {
40
+ .tapestry-react-reset {
41
41
  appearance: none;
42
42
  background-color: transparent;
43
43
  border-width: 0px;
@@ -45,24 +45,34 @@ ${getRootStyles(null, defaultColorProperties)}
45
45
  border-color: transparent;
46
46
  box-sizing: border-box;
47
47
  color: inherit;
48
- font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
48
+ box-sizing: border-box;
49
49
  flex-grow: 0;
50
50
  flex-shrink: 0;
51
51
  flex-basis: auto;
52
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
52
53
  font-weight: 400;
53
- margin: 0px;
54
- min-height: 0px;
54
+ margin-top: 0;
55
+ margin-right: 0;
56
+ margin-bottom: 0;
57
+ margin-left: 0;
55
58
  min-width: 0px;
56
- padding: 0px;
59
+ min-height: 0px;
60
+ padding-top: 0;
61
+ padding-right: 0;
62
+ padding-bottom: 0;
63
+ padding-left: 0;
57
64
  text-decoration: none;
58
65
  }
59
66
 
60
- .tapestry-react-reset *::-moz-focus-inner {
67
+ .tapestry-react-reset::-moz-focus-inner {
68
+ padding-top: 0;
69
+ padding-right: 0;
70
+ padding-bottom: 0;
71
+ padding-left: 0;
61
72
  border: none;
62
- padding: 0px;
63
73
  }
64
74
 
65
- .tapestry-react-reset *:focus:not(.focus-visible) {
75
+ .tapestry-react-reset:focus:not(.focus-visible) {
66
76
  outline: 0px;
67
77
  }
68
78
  `
@@ -230,7 +230,7 @@ class TimeField extends Component<Props> {
230
230
  highlightOnInteraction
231
231
  value={this.state.meridiem}
232
232
  grow={0}
233
- width={3}
233
+ width="2em"
234
234
  textAlign="center"
235
235
  aria-label="AM/PM"
236
236
  onChange={noop} // prevent React warnings
@@ -5,7 +5,6 @@ import React, {
5
5
  forwardRef,
6
6
  useRef,
7
7
  useState,
8
- useCallback,
9
8
  useImperativeHandle,
10
9
  useEffect,
11
10
  } from 'react'
@@ -122,19 +121,18 @@ function Tooltip(props: Props, ref) {
122
121
  ...childProps
123
122
  } = useThemeProps('tooltip', props)
124
123
 
125
- let isPageInView = true
126
- let isFocused = false
127
- let isMouseDown = false
124
+ let isPageInView = useRef(true)
125
+ let isMouseDown = useRef(false)
128
126
  let openTimeoutId = useRef(null)
129
127
  let closeTimeoutId = useRef(null)
130
128
 
131
- // prevents tooltips showing when focused and navigating back to a page after leaving
132
- const cleanupPageViewChange = useCallback(
133
- pageViewChange((inView) => setTimeout(() => (isPageInView = inView)))
134
- )
135
129
  const [isPopoverOpen, setIsPopoverOpen] = useState(defaultOpen)
136
130
 
137
131
  useEffect(() => {
132
+ // prevents tooltips showing when focused and navigating back to a page after leaving
133
+ const cleanupPageViewChange = pageViewChange((inView) =>
134
+ setTimeout(() => (isPageInView.current = inView))
135
+ )
138
136
  emitter.on('CLOSE_OPEN_TOOLTIPS', close)
139
137
  return () => {
140
138
  emitter.off('CLOSE_OPEN_TOOLTIPS', close)
@@ -178,7 +176,7 @@ function Tooltip(props: Props, ref) {
178
176
  }
179
177
  }, [triggerOnHover])
180
178
 
181
- const createOpenTimeout = useCallback(() => {
179
+ const createOpenTimeout = () => {
182
180
  clearGlobalTimeout()
183
181
  if (openTimeoutId.current === null) {
184
182
  clearTimeout(closeTimeoutId.current)
@@ -191,31 +189,31 @@ function Tooltip(props: Props, ref) {
191
189
  )
192
190
  }
193
191
  }
194
- })
192
+ }
195
193
 
196
- const createCloseTimeout = useCallback(() => {
194
+ const createCloseTimeout = () => {
197
195
  startGlobalTimeout()
198
196
  if (closeTimeoutId.current === null) {
199
197
  clearTimeout(openTimeoutId.current)
200
198
  openTimeoutId.current = null
201
199
  closeTimeoutId.current = setTimeout(() => close(), closeDelay)
202
200
  }
203
- })
201
+ }
204
202
 
205
- const handleFocus = useCallback(() => {
206
- if (isPageInView && !isMouseDown) {
203
+ const handleFocus = () => {
204
+ if (isPageInView.current && !isMouseDown.current) {
207
205
  open()
208
206
  }
209
- })
207
+ }
210
208
 
211
- const handleMouseDown = useCallback(() => {
212
- isMouseDown = true
209
+ const handleMouseDown = () => {
210
+ isMouseDown.current = true
213
211
  close()
214
- })
212
+ }
215
213
 
216
- const handleMouseUp = useCallback(() => {
217
- isMouseDown = false
218
- })
214
+ const handleMouseUp = () => {
215
+ isMouseDown.current = false
216
+ }
219
217
 
220
218
  const child = Children.only(children)
221
219
  const {
package/src/index.d.ts CHANGED
@@ -350,7 +350,7 @@ export const Checkbox: HTMLInputWrapperComponent
350
350
  // Input
351
351
  // =====
352
352
 
353
- export const Input: CommonComponent & {
353
+ export const Input: HTMLInputWrapperComponent & {
354
354
  Inline: HTMLInputWrapperComponent
355
355
  Input: HTMLInputWrapperComponent
356
356
  InputBox: CommonComponent
@@ -26,7 +26,9 @@ export default function SplitStyles({
26
26
  }
27
27
  return {
28
28
  ...restProps,
29
- className,
29
+ className: className
30
+ ? `tapestry-react-reset ${className}`
31
+ : `tapestry-react-reset`,
30
32
  css: (theme) => {
31
33
  const propStyles = {}
32
34
  for (const prop in styleProps) {
@@ -1,7 +1,7 @@
1
1
  import { useContext, useCallback } from 'react'
2
2
  import { ThemeContext } from '@emotion/react'
3
3
  import { darken, getLuminance, lighten, parseToRgb } from 'polished'
4
- import { get } from 'lodash'
4
+ import get from 'lodash/get'
5
5
 
6
6
  import { getColor } from './colors'
7
7
  import defaultTheme from './default-theme'
package/src/utils.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Children, cloneElement } from 'react'
2
2
  import { tabbable } from 'tabbable'
3
- import { kebabCase } from 'lodash'
3
+ import kebabCase from 'lodash/kebabCase'
4
4
 
5
5
  /**
6
6
  * Returns true if user platform is an iOS device