@workday/canvas-kit-react 10.0.0-alpha.444-next.0 → 10.0.0-alpha.447-next.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 (94) hide show
  1. package/button/lib/BaseButton.tsx +4 -4
  2. package/checkbox/lib/Checkbox.tsx +18 -12
  3. package/dist/commonjs/button/lib/BaseButton.d.ts +1 -1
  4. package/dist/commonjs/button/lib/BaseButton.d.ts.map +1 -1
  5. package/dist/commonjs/button/lib/BaseButton.js +4 -4
  6. package/dist/commonjs/checkbox/lib/Checkbox.d.ts.map +1 -1
  7. package/dist/commonjs/checkbox/lib/Checkbox.js +11 -11
  8. package/dist/commonjs/popup/lib/Popper.d.ts +8 -0
  9. package/dist/commonjs/popup/lib/Popper.d.ts.map +1 -1
  10. package/dist/commonjs/popup/lib/Popper.js +32 -8
  11. package/dist/commonjs/popup/lib/PopupPopper.d.ts +7 -0
  12. package/dist/commonjs/popup/lib/PopupPopper.d.ts.map +1 -1
  13. package/dist/commonjs/popup/lib/fallbackPlacements.d.ts +9 -0
  14. package/dist/commonjs/popup/lib/fallbackPlacements.d.ts.map +1 -0
  15. package/dist/commonjs/popup/lib/fallbackPlacements.js +94 -0
  16. package/dist/commonjs/popup/lib/hooks/usePopupPopper.d.ts.map +1 -1
  17. package/dist/commonjs/popup/lib/hooks/usePopupPopper.js +5 -2
  18. package/dist/commonjs/radio/lib/Radio.d.ts.map +1 -1
  19. package/dist/commonjs/radio/lib/Radio.js +13 -13
  20. package/dist/commonjs/select/lib/Select.d.ts.map +1 -1
  21. package/dist/commonjs/select/lib/Select.js +1 -1
  22. package/dist/commonjs/table/lib/TableRow.js +1 -1
  23. package/dist/commonjs/text-area/lib/TextArea.d.ts.map +1 -1
  24. package/dist/commonjs/text-area/lib/TextArea.js +3 -3
  25. package/dist/commonjs/text-input/lib/TextInput.js +1 -1
  26. package/dist/commonjs/tokens/index.d.ts.map +1 -1
  27. package/dist/commonjs/tokens/lib/depth.d.ts +6 -6
  28. package/dist/commonjs/tokens/lib/depth.d.ts.map +1 -1
  29. package/dist/commonjs/tokens/lib/depth.js +6 -6
  30. package/dist/commonjs/tokens/lib/space.d.ts +65 -27
  31. package/dist/commonjs/tokens/lib/space.d.ts.map +1 -1
  32. package/dist/commonjs/tokens/lib/space.js +61 -23
  33. package/dist/commonjs/tooltip/lib/OverflowTooltip.d.ts +8 -1
  34. package/dist/commonjs/tooltip/lib/OverflowTooltip.d.ts.map +1 -1
  35. package/dist/commonjs/tooltip/lib/OverflowTooltip.js +2 -2
  36. package/dist/commonjs/tooltip/lib/Tooltip.d.ts +7 -0
  37. package/dist/commonjs/tooltip/lib/Tooltip.d.ts.map +1 -1
  38. package/dist/commonjs/tooltip/lib/Tooltip.js +2 -2
  39. package/dist/commonjs/tooltip/lib/TooltipContainer.js +8 -8
  40. package/dist/es6/button/lib/BaseButton.d.ts +1 -1
  41. package/dist/es6/button/lib/BaseButton.d.ts.map +1 -1
  42. package/dist/es6/button/lib/BaseButton.js +4 -4
  43. package/dist/es6/checkbox/lib/Checkbox.d.ts.map +1 -1
  44. package/dist/es6/checkbox/lib/Checkbox.js +12 -12
  45. package/dist/es6/popup/lib/Popper.d.ts +8 -0
  46. package/dist/es6/popup/lib/Popper.d.ts.map +1 -1
  47. package/dist/es6/popup/lib/Popper.js +31 -7
  48. package/dist/es6/popup/lib/PopupPopper.d.ts +7 -0
  49. package/dist/es6/popup/lib/PopupPopper.d.ts.map +1 -1
  50. package/dist/es6/popup/lib/fallbackPlacements.d.ts +9 -0
  51. package/dist/es6/popup/lib/fallbackPlacements.d.ts.map +1 -0
  52. package/dist/es6/popup/lib/fallbackPlacements.js +72 -0
  53. package/dist/es6/popup/lib/hooks/usePopupPopper.d.ts.map +1 -1
  54. package/dist/es6/popup/lib/hooks/usePopupPopper.js +5 -2
  55. package/dist/es6/radio/lib/Radio.d.ts.map +1 -1
  56. package/dist/es6/radio/lib/Radio.js +14 -14
  57. package/dist/es6/select/lib/Select.d.ts.map +1 -1
  58. package/dist/es6/select/lib/Select.js +2 -2
  59. package/dist/es6/table/lib/TableRow.js +1 -1
  60. package/dist/es6/text-area/lib/TextArea.d.ts.map +1 -1
  61. package/dist/es6/text-area/lib/TextArea.js +4 -4
  62. package/dist/es6/text-input/lib/TextInput.js +1 -1
  63. package/dist/es6/tokens/index.d.ts.map +1 -1
  64. package/dist/es6/tokens/index.js +1 -1
  65. package/dist/es6/tokens/lib/depth.d.ts +6 -6
  66. package/dist/es6/tokens/lib/depth.d.ts.map +1 -1
  67. package/dist/es6/tokens/lib/depth.js +6 -6
  68. package/dist/es6/tokens/lib/space.d.ts +65 -27
  69. package/dist/es6/tokens/lib/space.d.ts.map +1 -1
  70. package/dist/es6/tokens/lib/space.js +61 -23
  71. package/dist/es6/tooltip/lib/OverflowTooltip.d.ts +8 -1
  72. package/dist/es6/tooltip/lib/OverflowTooltip.d.ts.map +1 -1
  73. package/dist/es6/tooltip/lib/OverflowTooltip.js +3 -3
  74. package/dist/es6/tooltip/lib/Tooltip.d.ts +7 -0
  75. package/dist/es6/tooltip/lib/Tooltip.d.ts.map +1 -1
  76. package/dist/es6/tooltip/lib/Tooltip.js +3 -3
  77. package/dist/es6/tooltip/lib/TooltipContainer.js +8 -8
  78. package/package.json +3 -3
  79. package/popup/lib/Popper.tsx +39 -6
  80. package/popup/lib/PopupPopper.tsx +7 -0
  81. package/popup/lib/fallbackPlacements.ts +90 -0
  82. package/popup/lib/hooks/usePopupPopper.ts +6 -2
  83. package/radio/lib/Radio.tsx +20 -14
  84. package/select/lib/Select.tsx +2 -9
  85. package/table/lib/TableRow.tsx +1 -1
  86. package/text-area/lib/TextArea.tsx +10 -4
  87. package/text-input/lib/TextInput.tsx +1 -1
  88. package/tokens/README.md +19 -19
  89. package/tokens/index.ts +1 -2
  90. package/tokens/lib/depth.ts +16 -12
  91. package/tokens/lib/space.ts +84 -46
  92. package/tooltip/lib/OverflowTooltip.tsx +15 -2
  93. package/tooltip/lib/Tooltip.tsx +15 -2
  94. package/tooltip/lib/TooltipContainer.tsx +8 -8
@@ -1,32 +1,70 @@
1
- /** An object of space keys and px values (strings) */
1
+ /**
2
+ * An object of space keys and rem values (strings)
3
+ *
4
+ * Below is a table to show the equivalent values from `px` to `rem`.
5
+ * This is based on the default browser font size which is `16px`.
6
+ *
7
+ * | px Value | rem Value | space token |
8
+ * | --------- | --------- | ----------- |
9
+ * | 0 | 0 | zero |
10
+ * | 4px | 0.25rem | xxxs |
11
+ * | 8px | 0.5rem | xxs |
12
+ * | 12px | 0.75rem | xs |
13
+ * | 16px | 1rem | s |
14
+ * | 24px | 1.5rem | m |
15
+ * | 32px | 2rem | l |
16
+ * | 40px | 2.5rem | xl |
17
+ * | 64px | 4rem | xxl |
18
+ * | 80px | 5rem | xxxl |
19
+ *
20
+ * */
2
21
  export const space = {
3
- zero: '0px',
4
- xxxs: '4px',
5
- xxs: '8px',
6
- xs: '12px',
7
- s: '16px',
8
- m: '24px',
9
- l: '32px',
10
- xl: '40px',
11
- xxl: '64px',
12
- xxxl: '80px',
22
+ zero: '0',
23
+ xxxs: '0.25rem',
24
+ xxs: '0.5rem',
25
+ xs: '0.75rem',
26
+ s: '1rem',
27
+ m: '1.5rem',
28
+ l: '2rem',
29
+ xl: '2.5rem',
30
+ xxl: '4rem',
31
+ xxxl: '5rem',
13
32
  };
14
33
  /**
15
- * An object of space keys and their numeric px values (numbers)
16
- * - These are helpful when you need a raw numeric px value.
34
+ * An object of space keys and their numeric rem values (numbers)
35
+ * - These are helpful when you need a raw numeric rem value.
17
36
  * - Here's an example usage to perform calculations:
18
37
  * @example
19
- * const buttonPaddingLeft = spaceNumbers.s + iconSize;
38
+ * ```tsx
39
+ * const buttonPaddingLeft = `${spaceNumbers.s + iconSize}rem`;
40
+ * ```
41
+ *
42
+ * Below is a table to show the equivalent values from `px` to `rem`.
43
+ * This is based on the default browser font size which is `16px`.
44
+ *
45
+ * | px Value | rem Value | space token |
46
+ * | --------- | --------- | ----------- |
47
+ * | 0 | 0 | zero |
48
+ * | 4px | 0.25rem | xxxs |
49
+ * | 8px | 0.5rem | xxs |
50
+ * | 12px | 0.75rem | xs |
51
+ * | 16px | 1rem | s |
52
+ * | 24px | 1.5rem | m |
53
+ * | 32px | 2rem | l |
54
+ * | 40px | 2.5rem | xl |
55
+ * | 64px | 4rem | xxl |
56
+ * | 80px | 5rem | xxxl |
57
+ *
20
58
  */
21
59
  export const spaceNumbers = {
22
60
  zero: 0,
23
- xxxs: 4,
24
- xxs: 8,
25
- xs: 12,
26
- s: 16,
27
- m: 24,
28
- l: 32,
29
- xl: 40,
30
- xxl: 64,
31
- xxxl: 80,
61
+ xxxs: 0.25,
62
+ xxs: 0.5,
63
+ xs: 0.75,
64
+ s: 1,
65
+ m: 1.5,
66
+ l: 2,
67
+ xl: 2.5,
68
+ xxl: 4,
69
+ xxxl: 5,
32
70
  };
@@ -25,6 +25,13 @@ export interface OverflowTooltipProps extends Omit<React.HTMLAttributes<HTMLDivE
25
25
  * @default 'top'
26
26
  */
27
27
  placement?: Placement;
28
+ /**
29
+ * Define fallback placements by providing a list of {@link Placement} in array (in order of preference).
30
+ * The default preference is following the order of `top`, `right`, `bottom`, and `left`. Once the initial
31
+ * and opposite placements are not available, the fallback placements will be in use. Use an empty array to
32
+ * disable the fallback placements.
33
+ */
34
+ fallbackPlacements?: Placement[];
28
35
  }
29
- export declare const OverflowTooltip: ({ placement, children, ...elemProps }: OverflowTooltipProps) => JSX.Element;
36
+ export declare const OverflowTooltip: ({ placement, fallbackPlacements, children, ...elemProps }: OverflowTooltipProps) => JSX.Element;
30
37
  //# sourceMappingURL=OverflowTooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OverflowTooltip.d.ts","sourceRoot":"","sources":["../../../../tooltip/lib/OverflowTooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAA4B,SAAS,EAAS,MAAM,iCAAiC,CAAC;AAM7F;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAa,OAAO,KAAG,OAAO,GAAG,IAmBhE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAa,OAAO,KAAG,OAAO,GAAG,IAahE,CAAC;AAcF,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAC/F;;;;;;;OAOG;IACH,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAiBD,eAAO,MAAM,eAAe,0CAIzB,oBAAoB,gBAwCtB,CAAC"}
1
+ {"version":3,"file":"OverflowTooltip.d.ts","sourceRoot":"","sources":["../../../../tooltip/lib/OverflowTooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAEL,SAAS,EAGV,MAAM,iCAAiC,CAAC;AAMzC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAa,OAAO,KAAG,OAAO,GAAG,IAmBhE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,YAAa,OAAO,KAAG,OAAO,GAAG,IAahE,CAAC;AAcF,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAC/F;;;;;;;OAOG;IACH,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,SAAS,EAAE,CAAC;CAClC;AAiBD,eAAO,MAAM,eAAe,8DAKzB,oBAAoB,gBAwCtB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { getTransformFromPlacement, Popper } from '@workday/canvas-kit-react/popup';
2
+ import { getTransformFromPlacement, Popper, defaultFallbackPlacements, } from '@workday/canvas-kit-react/popup';
3
3
  import { mergeCallback } from '@workday/canvas-kit-react/common';
4
4
  import { TooltipContainer } from './TooltipContainer';
5
5
  import { useTooltip } from './useTooltip';
@@ -64,7 +64,7 @@ function mergeCallbacks(elemProps, componentProps, keys = Object.keys(componentP
64
64
  return mergedProps;
65
65
  }, {});
66
66
  }
67
- export const OverflowTooltip = ({ placement = 'top', children, ...elemProps }) => {
67
+ export const OverflowTooltip = ({ placement = 'top', fallbackPlacements = defaultFallbackPlacements, children, ...elemProps }) => {
68
68
  const [titleText, setTitleText] = React.useState('');
69
69
  const { targetProps, popperProps, tooltipProps } = useTooltip({ type: 'muted' });
70
70
  const onMouseEnter = (event) => {
@@ -89,7 +89,7 @@ export const OverflowTooltip = ({ placement = 'top', children, ...elemProps }) =
89
89
  'aria-label': undefined,
90
90
  ...mergeCallbacks({ ...targetProps, onMouseEnter, onFocus }, children.props),
91
91
  }),
92
- React.createElement(Popper, Object.assign({ placement: placement }, popperProps), ({ placement }) => {
92
+ React.createElement(Popper, Object.assign({ placement: placement, fallbackPlacements: fallbackPlacements }, popperProps), ({ placement }) => {
93
93
  const transformOrigin = getTransformFromPlacement(placement);
94
94
  return (React.createElement(TooltipContainer, Object.assign({ transformOrigin: transformOrigin }, tooltipProps, elemProps), titleText));
95
95
  })));
@@ -20,6 +20,13 @@ export interface TooltipProps extends Omit<React.HTMLAttributes<HTMLDivElement>,
20
20
  * @default 'top'
21
21
  */
22
22
  placement?: Placement;
23
+ /**
24
+ * Define fallback placements by providing a list of {@link Placement} in array (in order of preference).
25
+ * The default preference is following the order of `top`, `right`, `bottom`, and `left`. Once the initial
26
+ * and opposite placements are not available, the fallback placements will be in use. Use an empty array to
27
+ * disable the fallback placements.
28
+ */
29
+ fallbackPlacements?: Placement[];
23
30
  /**
24
31
  * Determines the tooltip type for accessibility.
25
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../../tooltip/lib/Tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAA4B,SAAS,EAAS,MAAM,iCAAiC,CAAC;AAM7F,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IACvF;;;OAGG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;;;;;OAOG;IACH,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;;;;;;;;;;OAeG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,eAAO,MAAM,OAAO,kFAyClB,CAAC"}
1
+ {"version":3,"file":"Tooltip.d.ts","sourceRoot":"","sources":["../../../../tooltip/lib/Tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAEL,SAAS,EAGV,MAAM,iCAAiC,CAAC;AAMzC,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IACvF;;;OAGG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB;;;;;;;OAOG;IACH,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,SAAS,EAAE,CAAC;IACjC;;;;;;;;;;;;;;;OAeG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;IACtC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,eAAO,MAAM,OAAO,kFA0ClB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import innerText from 'react-innertext';
3
- import { getTransformFromPlacement, Popper } from '@workday/canvas-kit-react/popup';
3
+ import { getTransformFromPlacement, Popper, defaultFallbackPlacements, } from '@workday/canvas-kit-react/popup';
4
4
  import { createComponent, mergeCallback } from '@workday/canvas-kit-react/common';
5
5
  import { TooltipContainer } from './TooltipContainer';
6
6
  import { useTooltip } from './useTooltip';
@@ -17,7 +17,7 @@ function mergeCallbacks(elemProps, componentProps, keys = Object.keys(componentP
17
17
  }
18
18
  export const Tooltip = createComponent('div')({
19
19
  displayName: 'Tooltip',
20
- Component({ type = 'label', placement = 'top', title, children, showDelay = 300, hideDelay = 100, ...elemProps }) {
20
+ Component({ type = 'label', placement = 'top', title, children, showDelay = 300, hideDelay = 100, fallbackPlacements = defaultFallbackPlacements, ...elemProps }) {
21
21
  const titleText = innerText(title);
22
22
  const { targetProps, popperProps, tooltipProps } = useTooltip({
23
23
  type,
@@ -33,7 +33,7 @@ export const Tooltip = createComponent('div')({
33
33
  ? { 'aria-label': children.props['aria-label'] }
34
34
  : {}),
35
35
  }),
36
- React.createElement(Popper, Object.assign({ placement: placement }, popperProps), ({ placement }) => {
36
+ React.createElement(Popper, Object.assign({ placement: placement, fallbackPlacements: fallbackPlacements }, popperProps), ({ placement }) => {
37
37
  const transformOrigin = getTransformFromPlacement(placement);
38
38
  return (React.createElement(TooltipContainer, Object.assign({ transformOrigin: transformOrigin }, elemProps, tooltipProps), title));
39
39
  })));
@@ -23,7 +23,7 @@ export const TooltipContainer = styled('div')({
23
23
  ...type.levels.subtext.medium,
24
24
  display: 'inline-flex',
25
25
  position: 'relative',
26
- padding: spaceNumbers.xxs + spaceNumbers.xxxs,
26
+ padding: space.xs,
27
27
  color: colors.frenchVanilla100,
28
28
  a: {
29
29
  color: colors.frenchVanilla100,
@@ -34,7 +34,7 @@ export const TooltipContainer = styled('div')({
34
34
  content: '""',
35
35
  borderRadius: borderRadius.m,
36
36
  zIndex: -1,
37
- margin: spaceNumbers.xxxs,
37
+ margin: space.xxxs,
38
38
  backgroundColor: 'rgba(0,0,0,.85)',
39
39
  position: 'absolute',
40
40
  top: 0,
@@ -44,9 +44,9 @@ export const TooltipContainer = styled('div')({
44
44
  },
45
45
  // offset tooltips by 2 pixels when a keyboard focus ring is detected
46
46
  '[data-whatinput=keyboard] &': {
47
- padding: spaceNumbers.xxs + spaceNumbers.xxxs + 2,
47
+ padding: `${spaceNumbers.s - 0.125}rem`,
48
48
  ':before': {
49
- margin: spaceNumbers.xxxs + 2,
49
+ margin: `${spaceNumbers.xxxs + 0.125}rem`,
50
50
  },
51
51
  },
52
52
  // Hide tooltip when the reference element is either clipped or fully hidden
@@ -56,16 +56,16 @@ export const TooltipContainer = styled('div')({
56
56
  },
57
57
  // Fix offsets based on placement
58
58
  '[data-popper-placement="top-start"] &, [data-popper-placement="bottom-start"] &': {
59
- left: -spaceNumbers.xxxs,
59
+ left: `-${space.xxxs}`,
60
60
  },
61
61
  '[data-popper-placement="top-end"] &, [data-popper-placement="bottom-end"] &': {
62
- right: -spaceNumbers.xxxs,
62
+ right: `-${space.xxxs}`,
63
63
  },
64
64
  '[data-popper-placement="left-start"] &, [data-popper-placement="right-start"] &': {
65
- top: -spaceNumbers.xxxs,
65
+ top: `-${space.xxxs}`,
66
66
  },
67
67
  '[data-popper-placement="left-end"] &, [data-popper-placement="right-end"] &': {
68
- bottom: -spaceNumbers.xxxs,
68
+ bottom: `-${space.xxxs}`,
69
69
  },
70
70
  }, ({ transformOrigin = defaultTransformOrigin }) => {
71
71
  if (transformOrigin === null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workday/canvas-kit-react",
3
- "version": "10.0.0-alpha.444-next.0",
3
+ "version": "10.0.0-alpha.447-next.0",
4
4
  "description": "The parent module that contains all Workday Canvas Kit React components",
5
5
  "author": "Workday, Inc. (https://www.workday.com)",
6
6
  "license": "Apache-2.0",
@@ -49,7 +49,7 @@
49
49
  "@emotion/styled": "^11.6.0",
50
50
  "@popperjs/core": "^2.5.4",
51
51
  "@workday/canvas-colors-web": "^2.0.0",
52
- "@workday/canvas-kit-popup-stack": "^10.0.0-alpha.444-next.0",
52
+ "@workday/canvas-kit-popup-stack": "^10.0.0-alpha.447-next.0",
53
53
  "@workday/canvas-system-icons-web": "^3.0.0",
54
54
  "@workday/design-assets-types": "^0.2.8",
55
55
  "chroma-js": "^2.1.0",
@@ -66,5 +66,5 @@
66
66
  "@workday/canvas-accent-icons-web": "^3.0.0",
67
67
  "@workday/canvas-applet-icons-web": "^2.0.0"
68
68
  },
69
- "gitHead": "83a14407728a4a1dd97d4cab22712a3522ce64e5"
69
+ "gitHead": "7fc0c577c5f944eabe967840a78fc77f781833ce"
70
70
  }
@@ -4,9 +4,11 @@ import * as PopperJS from '@popperjs/core';
4
4
 
5
5
  export type Placement = `${PopperJS.Placement}`; // Use template literals to make documentation list them out
6
6
  export type PopperOptions = PopperJS.Options;
7
+ export const defaultFallbackPlacements: Placement[] = ['top', 'right', 'bottom', 'left'];
7
8
 
8
9
  import {usePopupStack} from './hooks';
9
10
  import {useLocalRef} from '@workday/canvas-kit-react/common';
11
+ import {fallbackPlacementsModifier} from './fallbackPlacements';
10
12
 
11
13
  export interface PopperProps {
12
14
  /**
@@ -43,6 +45,13 @@ export interface PopperProps {
43
45
  * @default bottom
44
46
  */
45
47
  placement?: Placement;
48
+ /**
49
+ * Define fallback placements by providing a list of {@link Placement} in array (in order of preference).
50
+ * The default preference is following the order of `top`, `right`, `bottom`, and `left`. Once the initial
51
+ * and opposite placements are not available, the fallback placements will be in use. Use an empty array to
52
+ * disable the fallback placements.
53
+ */
54
+ fallbackPlacements?: Placement[];
46
55
  /**
47
56
  * A callback function that will be called whenever PopperJS chooses a placement that is different
48
57
  * from the provided `placement` preference. If a `placement` preference doesn't fit, PopperJS
@@ -117,6 +126,7 @@ const OpenPopper = React.forwardRef<HTMLDivElement, PopperProps>(
117
126
  getAnchorClientRect,
118
127
  popperOptions = defaultPopperOptions,
119
128
  placement: popperPlacement = 'bottom',
129
+ fallbackPlacements = defaultFallbackPlacements,
120
130
  onPlacementChange,
121
131
  children,
122
132
  portal,
@@ -129,14 +139,19 @@ const OpenPopper = React.forwardRef<HTMLDivElement, PopperProps>(
129
139
  const [placement, setPlacement] = React.useState(popperPlacement);
130
140
  const stackRef = usePopupStack(ref, anchorElement as HTMLElement);
131
141
 
142
+ const placementRef = React.useRef(popperPlacement);
143
+ placementRef.current = placement;
144
+
132
145
  const placementModifier = React.useMemo((): PopperJS.Modifier<any, any> => {
133
146
  return {
134
147
  name: 'setPlacement',
135
148
  enabled: true,
136
- phase: 'main',
149
+ phase: 'afterWrite',
137
150
  fn({state}) {
138
- setPlacement(state.placement);
139
- onPlacementChange?.(state.placement);
151
+ if (placementRef.current !== state.placement) {
152
+ setPlacement(state.placement);
153
+ onPlacementChange?.(state.placement);
154
+ }
140
155
  },
141
156
  };
142
157
  }, [setPlacement, onPlacementChange]);
@@ -157,7 +172,16 @@ const OpenPopper = React.forwardRef<HTMLDivElement, PopperProps>(
157
172
  const instance = PopperJS.createPopper(anchorEl, stackRef.current, {
158
173
  placement: popperPlacement,
159
174
  ...popperOptions,
160
- modifiers: [...(popperOptions.modifiers || []), placementModifier],
175
+ modifiers: [
176
+ placementModifier,
177
+ {
178
+ ...fallbackPlacementsModifier,
179
+ options: {
180
+ fallbackPlacements,
181
+ },
182
+ },
183
+ ...(popperOptions.modifiers || []),
184
+ ],
161
185
  });
162
186
  elementRef(instance); // update the ref with the instance
163
187
 
@@ -179,11 +203,20 @@ const OpenPopper = React.forwardRef<HTMLDivElement, PopperProps>(
179
203
  localRef.current?.setOptions({
180
204
  placement: popperPlacement,
181
205
  ...popperOptions,
182
- modifiers: [...(popperOptions.modifiers || []), placementModifier],
206
+ modifiers: [
207
+ placementModifier,
208
+ {
209
+ ...fallbackPlacementsModifier,
210
+ options: {
211
+ fallbackPlacements,
212
+ },
213
+ },
214
+ ...(popperOptions.modifiers || []),
215
+ ],
183
216
  });
184
217
  }
185
218
  firstRender.current = false;
186
- }, [popperOptions, popperPlacement, placementModifier, localRef]);
219
+ }, [popperOptions, popperPlacement, fallbackPlacements, placementModifier, localRef]);
187
220
 
188
221
  const contents = <>{isRenderProp(children) ? children({placement}) : children}</>;
189
222
 
@@ -13,6 +13,13 @@ export interface PopupPopperProps extends PopperProps {
13
13
  * @default bottom
14
14
  */
15
15
  placement?: Placement;
16
+ /**
17
+ * Define fallback placements by providing a list of {@link Placement} in array (in order of preference).
18
+ * The default preference is following the order of `top`, `right`, `bottom`, and `left`. Once the initial
19
+ * and opposite placements are not available, the fallback placements will be in use. Use an empty array to
20
+ * disable the fallback placements.
21
+ */
22
+ fallbackPlacements?: Placement[];
16
23
  /**
17
24
  * The additional options passed to the Popper's `popper.js` instance.
18
25
  */
@@ -0,0 +1,90 @@
1
+ import * as PopperJS from '@popperjs/core';
2
+
3
+ export type Placement = PopperJS.Placement; // Use template literals to make documentation list them out
4
+
5
+ const getOppositePlacement = (popperPlacement: Placement): Placement => {
6
+ const [first, second] = popperPlacement.split('-');
7
+ let oppositePlacement: Placement;
8
+ switch (first) {
9
+ case 'top':
10
+ oppositePlacement = 'bottom';
11
+ break;
12
+ case 'bottom':
13
+ oppositePlacement = 'top';
14
+ break;
15
+ case 'left':
16
+ oppositePlacement = 'right';
17
+ break;
18
+ case 'right':
19
+ oppositePlacement = 'left';
20
+ break;
21
+ default:
22
+ oppositePlacement = 'auto';
23
+ }
24
+ if (second) {
25
+ oppositePlacement =
26
+ PopperJS.placements.find(placement => placement.includes(`${oppositePlacement}-${second}`)) ??
27
+ oppositePlacement;
28
+ }
29
+ return oppositePlacement;
30
+ };
31
+
32
+ const choseAvailablePlacement = (
33
+ placements: Placement[],
34
+ state: PopperJS.State,
35
+ preferredPlacement: Placement
36
+ ): Placement => {
37
+ if (placements.length === 0 || placements[0].split('-')[0] === 'auto') {
38
+ return preferredPlacement;
39
+ }
40
+
41
+ const {reference, popper} = state.rects;
42
+ const overflow = PopperJS.detectOverflow({...state, placement: placements[0]});
43
+ const direction = /left|right/.test(placements[0].split('-')[0]) ? 'horizontal' : 'vertical';
44
+ const isOverflowed =
45
+ (overflow.top > 0 || overflow.bottom > 0 || overflow.left > 0 || overflow.right > 0) &&
46
+ (direction === 'horizontal'
47
+ ? popper.height / 2 - overflow.top < reference.height ||
48
+ popper.height / 2 - overflow.bottom < reference.height
49
+ : popper.width - overflow.left < reference.width ||
50
+ popper.width - overflow.right < reference.width);
51
+ const key = placements[0].split('-')[0] as keyof PopperJS.SideObject;
52
+
53
+ if (!isOverflowed && overflow[key] <= 0) {
54
+ return placements[0];
55
+ } else {
56
+ return choseAvailablePlacement(placements.slice(1), state, preferredPlacement);
57
+ }
58
+ };
59
+
60
+ export type Options = {
61
+ fallbackPlacements: Placement[];
62
+ };
63
+
64
+ const name = 'fallbackModifier';
65
+
66
+ export const fallbackPlacementsModifier: PopperJS.Modifier<typeof name, Options> = {
67
+ name: name,
68
+ enabled: true,
69
+ phase: 'main',
70
+ data: {
71
+ _skip: false,
72
+ },
73
+ fn({state, options}: PopperJS.ModifierArguments<Options>) {
74
+ const preferredPlacement = state.options.placement;
75
+ const {fallbackPlacements} = options;
76
+
77
+ const placements = [
78
+ preferredPlacement,
79
+ getOppositePlacement(preferredPlacement),
80
+ ...(fallbackPlacements || []),
81
+ ];
82
+
83
+ const placementOverride = choseAvailablePlacement(placements, state, preferredPlacement);
84
+ if (state.placement !== placementOverride) {
85
+ state.modifiersData[name]._skip = true;
86
+ state.placement = placementOverride;
87
+ state.reset = true;
88
+ }
89
+ },
90
+ };
@@ -9,14 +9,18 @@ import {Placement} from '../Popper';
9
9
  */
10
10
  export const usePopupPopper = createElemPropsHook(usePopupModel)(({state, events}, ref) => {
11
11
  const elementRef = useForkRef(ref, state.stackRef);
12
+
13
+ // Create a mutable ref of the placement to keep a stable `onPlacementChange` reference.
14
+ const placementRef = React.useRef(state.placement);
15
+ placementRef.current = state.placement;
12
16
  const onPlacementChange = React.useCallback(
13
17
  (placement: Placement) => {
14
- if (placement !== state.placement) {
18
+ if (placement !== placementRef.current) {
15
19
  // only update if the placement has changed
16
20
  events.updatePlacement({placement});
17
21
  }
18
22
  },
19
- [events, state.placement]
23
+ [events]
20
24
  );
21
25
 
22
26
  return {
@@ -8,7 +8,13 @@ import {
8
8
  Themeable,
9
9
  useUniqueId,
10
10
  } from '@workday/canvas-kit-react/common';
11
- import {borderRadius, colors, inputColors, spaceNumbers} from '@workday/canvas-kit-react/tokens';
11
+ import {
12
+ borderRadius,
13
+ colors,
14
+ inputColors,
15
+ space,
16
+ spaceNumbers,
17
+ } from '@workday/canvas-kit-react/tokens';
12
18
  import {LabelText} from '@workday/canvas-kit-react/text';
13
19
 
14
20
  export interface RadioProps extends Themeable {
@@ -47,13 +53,13 @@ export interface RadioProps extends Themeable {
47
53
  variant?: 'inverse' | undefined;
48
54
  }
49
55
 
50
- const radioBorderRadius = 9;
51
- const radioDot = 8;
52
- const radioHeight = 18;
53
- const radioTapArea = spaceNumbers.m;
56
+ const radioBorderRadius = `${spaceNumbers.xxs + 0.0625}rem`;
57
+ const radioDot = space.xxs;
58
+ const radioHeight = (spaceNumbers.xl - spaceNumbers.xxxs) / 2;
59
+ const radioTapArea = space.m;
54
60
  const radioContainerHeight = radioTapArea;
55
- const radioLabelDistance = spaceNumbers.xs;
56
- const radioWidth = 18;
61
+ const radioLabelDistance = space.xs;
62
+ const radioWidth = radioHeight;
57
63
  const rippleRadius = (spaceNumbers.l - radioWidth) / 2;
58
64
 
59
65
  const RadioContainer = styled('div')({
@@ -70,17 +76,17 @@ const RadioContainer = styled('div')({
70
76
  */
71
77
  const RadioInputWrapper = styled('div')<Pick<RadioProps, 'disabled'>>({
72
78
  display: 'flex',
73
- height: radioHeight,
74
- width: radioWidth,
79
+ height: `${radioHeight}rem`,
80
+ width: `${radioWidth}rem`,
75
81
  });
76
82
 
77
83
  const RadioRipple = styled('span')<Pick<RadioProps, 'disabled' | 'variant'>>(
78
84
  {
79
85
  borderRadius: borderRadius.circle,
80
86
  boxShadow: `0 0 0 0 ${colors.soap200}`,
81
- height: radioHeight,
87
+ height: `${radioHeight}rem`,
82
88
  transition: 'box-shadow 150ms ease-out',
83
- width: radioWidth,
89
+ width: `${radioWidth}rem`,
84
90
  position: 'absolute',
85
91
  pointerEvents: 'none', // This is a decorative element we don't want it to block clicks to input
86
92
  },
@@ -129,7 +135,7 @@ const RadioInput = styled('input')<RadioProps & StyledType>(
129
135
  // `span:first-of-type` refers to `RadioRipple`, the light grey
130
136
  // element that animates around the component on hover
131
137
  '&:hover ~ span:first-of-type': {
132
- boxShadow: disabled ? undefined : `0 0 0 ${rippleRadius}px ${colors.soap200}`,
138
+ boxShadow: disabled ? undefined : `0 0 0 ${rippleRadius}rem ${colors.soap200}`,
133
139
  },
134
140
 
135
141
  // `div:first-of-type` refers to the `RadioBackground`, the visual facade of the
@@ -212,13 +218,13 @@ const RadioBackground = styled('div')<RadioProps>(
212
218
  borderWidth: '1px',
213
219
  boxSizing: 'border-box',
214
220
  display: 'flex',
215
- height: radioHeight,
221
+ height: `${radioHeight}rem`,
216
222
  justifyContent: 'center',
217
223
  padding: '0px 2px',
218
224
  pointerEvents: 'none',
219
225
  position: 'absolute',
220
226
  transition: 'border 200ms ease, background 200ms',
221
- width: radioWidth,
227
+ width: `${radioWidth}rem`,
222
228
  },
223
229
  ({
224
230
  checked,
@@ -8,14 +8,7 @@ import {
8
8
  styled,
9
9
  Themeable,
10
10
  } from '@workday/canvas-kit-react/common';
11
- import {
12
- colors,
13
- borderRadius,
14
- inputColors,
15
- spaceNumbers,
16
- type,
17
- space,
18
- } from '@workday/canvas-kit-react/tokens';
11
+ import {colors, borderRadius, inputColors, type, space} from '@workday/canvas-kit-react/tokens';
19
12
  import {caretDownSmallIcon} from '@workday/canvas-system-icons-web';
20
13
  import {SystemIcon} from '@workday/canvas-kit-react/icon';
21
14
  import {SelectOption} from './SelectOption';
@@ -55,7 +48,7 @@ const StyledSelect = styled('select')<SelectProps & StyledType>(
55
48
  height: space.xl,
56
49
  minWidth: 280,
57
50
  transition: '0.2s box-shadow, 0.2s border-color',
58
- padding: spaceNumbers.xxs,
51
+ padding: space.xxs,
59
52
  margin: 0, // Fix Safari
60
53
  MozAppearance: 'none', // FF bugfix: hide arrow so it doesn't show under ours
61
54
  WebkitAppearance: 'none',
@@ -100,7 +100,7 @@ const StyledTableRow = styled('tr')<TableRowProps>(
100
100
  fontSize: 13,
101
101
  borderRight: cellBorder,
102
102
  borderBottom: cellBorder,
103
- height: spaceNumbers.xl + spaceNumbers.xxs,
103
+ height: `${spaceNumbers.xl + spaceNumbers.xxs}rem`,
104
104
  boxSizing: 'border-box',
105
105
  transition: 'background-color 0.2s',
106
106
  },
@@ -8,7 +8,13 @@ import {
8
8
  styled,
9
9
  Themeable,
10
10
  } from '@workday/canvas-kit-react/common';
11
- import {borderRadius, inputColors, spaceNumbers, type} from '@workday/canvas-kit-react/tokens';
11
+ import {
12
+ borderRadius,
13
+ inputColors,
14
+ space,
15
+ spaceNumbers,
16
+ type,
17
+ } from '@workday/canvas-kit-react/tokens';
12
18
 
13
19
  export interface TextAreaProps extends Themeable, GrowthBehavior {
14
20
  /**
@@ -59,10 +65,10 @@ const StyledTextArea = styled('textarea')<TextAreaProps & StyledType>(
59
65
  backgroundColor: inputColors.background,
60
66
  borderRadius: borderRadius.m,
61
67
  boxSizing: 'border-box',
62
- minHeight: 64,
63
- minWidth: 280,
68
+ minHeight: space.xxl,
69
+ minWidth: `${spaceNumbers.xxxl * 3 + spaceNumbers.xl}rem`,
64
70
  transition: '0.2s box-shadow, 0.2s border-color',
65
- padding: spaceNumbers.xxs, // Compensate for border
71
+ padding: space.xxs, // Compensate for border
66
72
  margin: 0, // Fix Safari
67
73
  '&::webkit-resizer': {
68
74
  display: 'none',
@@ -33,7 +33,7 @@ const StyledTextInput = styled('input')<
33
33
  boxSizing: 'border-box',
34
34
  height: 40,
35
35
  transition: '0.2s box-shadow, 0.2s border-color',
36
- padding: spaceNumbers.xxs, // Compensate for border
36
+ padding: `${spaceNumbers.xxs}rem`, // Compensate for border
37
37
  margin: 0, // Fix Safari
38
38
  '&::placeholder': {
39
39
  color: inputColors.placeholder,