@zendeskgarden/react-theming 9.0.0-next.2 → 9.0.0-next.20
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.
- package/dist/esm/elements/ThemeProvider.js +24 -0
- package/dist/esm/elements/palette/index.js +259 -0
- package/dist/esm/elements/palette/v8.js +149 -0
- package/dist/esm/elements/theme/index.js +240 -0
- package/dist/esm/index.js +28 -0
- package/dist/esm/types/index.js +11 -0
- package/dist/esm/utils/StyledBaseIcon.js +22 -0
- package/dist/esm/utils/arrowStyles.js +45 -0
- package/dist/esm/utils/focusStyles.js +43 -0
- package/dist/esm/utils/getArrowPosition.js +35 -0
- package/dist/esm/utils/getCheckeredBackground.js +40 -0
- package/dist/esm/utils/getColor.js +245 -0
- package/dist/esm/utils/getColorV8.js +72 -0
- package/dist/esm/utils/getFloatingPlacements.js +58 -0
- package/dist/esm/utils/getFocusBoxShadow.js +45 -0
- package/dist/esm/utils/getLineHeight.js +22 -0
- package/dist/esm/utils/getMenuPosition.js +11 -0
- package/dist/esm/utils/mediaQuery.js +56 -0
- package/dist/esm/utils/menuStyles.js +70 -0
- package/dist/esm/utils/retrieveComponentStyles.js +19 -0
- package/dist/esm/utils/useDocument.js +21 -0
- package/dist/esm/utils/useText.js +29 -0
- package/dist/esm/utils/useWindow.js +21 -0
- package/dist/index.cjs.js +838 -198
- package/dist/typings/elements/ThemeProvider.d.ts +1 -1
- package/dist/typings/elements/palette/index.d.ts +134 -26
- package/dist/typings/elements/palette/v8.d.ts +149 -0
- package/dist/typings/elements/theme/index.d.ts +0 -1
- package/dist/typings/index.d.ts +6 -4
- package/dist/typings/types/index.d.ts +61 -16
- package/dist/typings/utils/StyledBaseIcon.d.ts +8 -0
- package/dist/typings/utils/arrowStyles.d.ts +0 -16
- package/dist/typings/utils/focusStyles.d.ts +3 -11
- package/dist/typings/utils/getCheckeredBackground.d.ts +20 -0
- package/dist/typings/utils/getColor.d.ts +14 -9
- package/dist/typings/utils/getColorV8.d.ts +27 -0
- package/dist/typings/utils/getFocusBoxShadow.d.ts +6 -21
- package/dist/typings/utils/menuStyles.d.ts +1 -1
- package/package.json +8 -7
- package/dist/index.esm.js +0 -714
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import styled from 'styled-components';
|
|
8
|
+
import React, { Children } from 'react';
|
|
9
|
+
|
|
10
|
+
const StyledBaseIcon = styled(_ref => {
|
|
11
|
+
let {
|
|
12
|
+
children,
|
|
13
|
+
theme,
|
|
14
|
+
...props
|
|
15
|
+
} = _ref;
|
|
16
|
+
return React.cloneElement(Children.only(children), props);
|
|
17
|
+
}).withConfig({
|
|
18
|
+
displayName: "StyledBaseIcon",
|
|
19
|
+
componentId: "sc-1moykgb-0"
|
|
20
|
+
})([""]);
|
|
21
|
+
|
|
22
|
+
export { StyledBaseIcon };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { css, keyframes } from 'styled-components';
|
|
8
|
+
import { stripUnit, math } from 'polished';
|
|
9
|
+
|
|
10
|
+
const animationStyles = (position, modifier) => {
|
|
11
|
+
const property = position.split('-')[0];
|
|
12
|
+
const animationName = keyframes(["0%,66%{", ":2px;border:transparent;}"], property);
|
|
13
|
+
return css(["&", "::before,&", "::after{animation:0.3s ease-in-out ", ";}"], modifier, modifier, animationName);
|
|
14
|
+
};
|
|
15
|
+
const positionStyles = (position, size, inset) => {
|
|
16
|
+
const margin = math(`${size} / -2`);
|
|
17
|
+
const placement = math(`${margin} + ${inset}`);
|
|
18
|
+
let transform;
|
|
19
|
+
let positionCss;
|
|
20
|
+
if (position.startsWith('top')) {
|
|
21
|
+
transform = 'rotate(-135deg)';
|
|
22
|
+
positionCss = css(["top:", ";right:", ";left:", ";margin-left:", ";"], placement, position === 'top-right' && size, position === 'top' ? '50%' : position === 'top-left' && size, position === 'top' && margin);
|
|
23
|
+
} else if (position.startsWith('right')) {
|
|
24
|
+
transform = 'rotate(-45deg)';
|
|
25
|
+
positionCss = css(["top:", ";right:", ";bottom:", ";margin-top:", ";"], position === 'right' ? '50%' : position === 'right-top' && size, placement, position === 'right-bottom' && size, position === 'right' && margin);
|
|
26
|
+
} else if (position.startsWith('bottom')) {
|
|
27
|
+
transform = 'rotate(45deg)';
|
|
28
|
+
positionCss = css(["right:", ";bottom:", ";left:", ";margin-left:", ";"], position === 'bottom-right' && size, placement, position === 'bottom' ? '50%' : position === 'bottom-left' && size, position === 'bottom' && margin);
|
|
29
|
+
} else if (position.startsWith('left')) {
|
|
30
|
+
transform = 'rotate(135deg)';
|
|
31
|
+
positionCss = css(["top:", ";bottom:", ";left:", ";margin-top:", ";"], position === 'left' ? '50%' : position === 'left-top' && size, size, placement, position === 'left' && margin);
|
|
32
|
+
}
|
|
33
|
+
return css(["&::before,&::after{transform:", ";", ";}"], transform, positionCss);
|
|
34
|
+
};
|
|
35
|
+
function arrowStyles(position) {
|
|
36
|
+
let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
37
|
+
const inset = options.inset || '0';
|
|
38
|
+
const size = options.size === undefined ? 6 : stripUnit(options.size);
|
|
39
|
+
const squareSize = `${Math.round(size * 2 / Math.sqrt(2))}px`;
|
|
40
|
+
const afterOffset = 0;
|
|
41
|
+
const beforeOffset = afterOffset + 2;
|
|
42
|
+
return css(["position:relative;&::before,&::after{position:absolute;border-width:inherit;border-style:inherit;width:", ";height:", ";content:'';box-sizing:inherit;}&::before{border-color:inherit;background-color:transparent;clip-path:polygon(100% ", "px,", "px 100%,100% 100%);}&::after{border-color:transparent;background-clip:content-box;background-color:inherit;clip-path:polygon(100% ", "px,", "px 100%,100% 100%);}", ";", ";"], squareSize, squareSize, beforeOffset, beforeOffset, afterOffset, afterOffset, positionStyles(position, squareSize, inset), options.animationModifier && animationStyles(position, options.animationModifier));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { arrowStyles as default };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { css } from 'styled-components';
|
|
8
|
+
import { math } from 'polished';
|
|
9
|
+
import { getFocusBoxShadow } from './getFocusBoxShadow.js';
|
|
10
|
+
|
|
11
|
+
const SELECTOR_FOCUS_VISIBLE = '&:focus-visible';
|
|
12
|
+
const focusStyles = _ref => {
|
|
13
|
+
let {
|
|
14
|
+
condition = true,
|
|
15
|
+
selector = SELECTOR_FOCUS_VISIBLE,
|
|
16
|
+
shadowWidth = 'md',
|
|
17
|
+
spacerWidth = 'xs',
|
|
18
|
+
styles: {
|
|
19
|
+
boxShadow,
|
|
20
|
+
...styles
|
|
21
|
+
} = {},
|
|
22
|
+
theme,
|
|
23
|
+
...options
|
|
24
|
+
} = _ref;
|
|
25
|
+
const _boxShadow = condition ? getFocusBoxShadow({
|
|
26
|
+
boxShadow,
|
|
27
|
+
shadowWidth,
|
|
28
|
+
spacerWidth,
|
|
29
|
+
theme,
|
|
30
|
+
...options
|
|
31
|
+
}) : boxShadow;
|
|
32
|
+
let outline;
|
|
33
|
+
let outlineOffset;
|
|
34
|
+
if (spacerWidth === null) {
|
|
35
|
+
outline = theme.shadowWidths[shadowWidth];
|
|
36
|
+
} else {
|
|
37
|
+
outline = `${math(`${theme.shadowWidths[shadowWidth]} - ${theme.shadowWidths[spacerWidth]}`)} solid transparent`;
|
|
38
|
+
outlineOffset = theme.shadowWidths[spacerWidth];
|
|
39
|
+
}
|
|
40
|
+
return css(["&:focus{outline:none;}", "{outline:", ";outline-offset:", ";box-shadow:", ";", "}"], selector, outline, outlineOffset, _boxShadow, styles);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export { SELECTOR_FOCUS_VISIBLE, focusStyles };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
const POSITION_MAP = {
|
|
8
|
+
top: 'bottom',
|
|
9
|
+
'top-start': 'bottom-left',
|
|
10
|
+
'top-end': 'bottom-right',
|
|
11
|
+
right: 'left',
|
|
12
|
+
'right-start': 'left-top',
|
|
13
|
+
'right-end': 'left-bottom',
|
|
14
|
+
bottom: 'top',
|
|
15
|
+
'bottom-start': 'top-left',
|
|
16
|
+
'bottom-end': 'top-right',
|
|
17
|
+
left: 'right',
|
|
18
|
+
'left-start': 'right-top',
|
|
19
|
+
'left-end': 'right-bottom'
|
|
20
|
+
};
|
|
21
|
+
const RTL_POSITION_MAP = {
|
|
22
|
+
'bottom-left': 'bottom-right',
|
|
23
|
+
'bottom-right': 'bottom-left',
|
|
24
|
+
'top-left': 'top-right',
|
|
25
|
+
'top-right': 'top-left'
|
|
26
|
+
};
|
|
27
|
+
const getArrowPosition = (theme, placement) => {
|
|
28
|
+
let retVal = POSITION_MAP[placement];
|
|
29
|
+
if (theme.rtl) {
|
|
30
|
+
retVal = RTL_POSITION_MAP[retVal] || retVal;
|
|
31
|
+
}
|
|
32
|
+
return retVal;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export { POSITION_MAP, RTL_POSITION_MAP, getArrowPosition };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { getColor } from './getColor.js';
|
|
8
|
+
|
|
9
|
+
const getCheckeredBackground = _ref => {
|
|
10
|
+
let {
|
|
11
|
+
theme,
|
|
12
|
+
size,
|
|
13
|
+
overlay,
|
|
14
|
+
positionY = 0,
|
|
15
|
+
repeat = 'repeat'
|
|
16
|
+
} = _ref;
|
|
17
|
+
const color = getColor({
|
|
18
|
+
theme,
|
|
19
|
+
variable: 'border.default'
|
|
20
|
+
});
|
|
21
|
+
const dimensions = `${size}px ${size}px`;
|
|
22
|
+
const positionX1 = theme.rtl ? '100%' : '0';
|
|
23
|
+
const positionX2 = theme.rtl ? `calc(100% - ${size / 2}px)` : `${size / 2}px`;
|
|
24
|
+
const position1 = `${positionX1} ${positionY}px`;
|
|
25
|
+
const position2 = `${positionX2} ${size / 2 + positionY}px`;
|
|
26
|
+
const position3 = `${positionX2} ${positionY}px`;
|
|
27
|
+
const position4 = `${positionX1} ${size / -2 + positionY}px`;
|
|
28
|
+
let retVal = `
|
|
29
|
+
linear-gradient(45deg, ${color} 25%, transparent 25%) ${position1} / ${dimensions} ${repeat},
|
|
30
|
+
linear-gradient(45deg, transparent 75%, ${color} 75%) ${position2} / ${dimensions} ${repeat},
|
|
31
|
+
linear-gradient(135deg, ${color} 25%, transparent 25%) ${position3} / ${dimensions} ${repeat},
|
|
32
|
+
linear-gradient(135deg, transparent 75%, ${color} 75%) ${position4} / ${dimensions} ${repeat}
|
|
33
|
+
`;
|
|
34
|
+
if (overlay) {
|
|
35
|
+
retVal = overlay.startsWith('linear-gradient') ? `${overlay}, ${retVal}` : `linear-gradient(${overlay}, ${overlay}), ${retVal}`;
|
|
36
|
+
}
|
|
37
|
+
return retVal;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { getCheckeredBackground };
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { getScale, parseToRgba } from 'color2k';
|
|
8
|
+
import { getContrast, rgba, darken, lighten } from 'polished';
|
|
9
|
+
import get from 'lodash.get';
|
|
10
|
+
import memoize from 'lodash.memoize';
|
|
11
|
+
import DEFAULT_THEME from '../elements/theme/index.js';
|
|
12
|
+
|
|
13
|
+
const adjust = (color, expected, actual) => {
|
|
14
|
+
if (expected !== actual) {
|
|
15
|
+
const amount = Math.abs(expected - actual) / 100 * 0.05;
|
|
16
|
+
return expected > actual ? darken(amount, color) : lighten(amount, color);
|
|
17
|
+
}
|
|
18
|
+
return color;
|
|
19
|
+
};
|
|
20
|
+
const toShade = (shade, offset, scheme) => {
|
|
21
|
+
let _shade;
|
|
22
|
+
if (shade === undefined) {
|
|
23
|
+
_shade = scheme === 'dark' ? 500 : 700;
|
|
24
|
+
} else {
|
|
25
|
+
_shade = parseInt(shade.toString(), 10);
|
|
26
|
+
if (isNaN(_shade)) {
|
|
27
|
+
throw new TypeError(`Error: unexpected '${typeof shade}' type for color shade "${shade}"`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return _shade + (offset || 0);
|
|
31
|
+
};
|
|
32
|
+
const toHex = (hue, shade, offset, scheme) => {
|
|
33
|
+
const _shade = toShade(shade, offset, scheme);
|
|
34
|
+
let retVal = hue[_shade];
|
|
35
|
+
if (!retVal) {
|
|
36
|
+
const closestShade = Object.keys(hue).map(hueShade => parseInt(hueShade, 10)).reduce((previous, current) => {
|
|
37
|
+
return Math.abs(current - _shade) < Math.abs(previous - _shade) ? current : previous;
|
|
38
|
+
});
|
|
39
|
+
retVal = adjust(hue[closestShade], _shade, closestShade);
|
|
40
|
+
}
|
|
41
|
+
return retVal;
|
|
42
|
+
};
|
|
43
|
+
const isValidColor = maybeColor => {
|
|
44
|
+
try {
|
|
45
|
+
return !!parseToRgba(maybeColor);
|
|
46
|
+
} catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function findNearestIndex(target, arr) {
|
|
51
|
+
let startIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
52
|
+
if (typeof target !== 'number' || isNaN(target)) {
|
|
53
|
+
throw new Error('Target must be a number.');
|
|
54
|
+
}
|
|
55
|
+
if (!Array.isArray(arr)) {
|
|
56
|
+
throw new Error('Second argument must be an array.');
|
|
57
|
+
}
|
|
58
|
+
let left = startIndex;
|
|
59
|
+
let right = arr.length - 1;
|
|
60
|
+
if (target < arr[left]) return left;
|
|
61
|
+
if (target > arr[right]) return right;
|
|
62
|
+
while (left <= right) {
|
|
63
|
+
const mid = Math.floor((left + right) / 2);
|
|
64
|
+
if (arr[mid] === target) {
|
|
65
|
+
return mid;
|
|
66
|
+
} else if (arr[mid] < target) {
|
|
67
|
+
left = mid + 1;
|
|
68
|
+
} else {
|
|
69
|
+
right = mid - 1;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return arr[left] - target < target - arr[right] ? left : right;
|
|
73
|
+
}
|
|
74
|
+
const OFFSET_TO_TARGET_RATIO = {
|
|
75
|
+
100: 1.08,
|
|
76
|
+
200: 1.2,
|
|
77
|
+
300: 1.35,
|
|
78
|
+
400: 2,
|
|
79
|
+
500: 2.8,
|
|
80
|
+
600: 3.3,
|
|
81
|
+
700: 5,
|
|
82
|
+
800: 10,
|
|
83
|
+
900: 13,
|
|
84
|
+
1000: 16,
|
|
85
|
+
1100: 17.5,
|
|
86
|
+
1200: 19
|
|
87
|
+
};
|
|
88
|
+
const generateColorScale = memoize(color => {
|
|
89
|
+
const scaleSize = 200;
|
|
90
|
+
const _scale = getScale('#FFF', color, '#000');
|
|
91
|
+
const scale = x => _scale(x / scaleSize);
|
|
92
|
+
const colors = [];
|
|
93
|
+
const contrastRatios = [];
|
|
94
|
+
for (let i = 0; i <= scaleSize; i++) {
|
|
95
|
+
const _color = scale(i);
|
|
96
|
+
colors.push(_color);
|
|
97
|
+
contrastRatios.push(getContrast('#FFF', _color));
|
|
98
|
+
}
|
|
99
|
+
const palette = {};
|
|
100
|
+
let startIndex = 0;
|
|
101
|
+
for (const offset in OFFSET_TO_TARGET_RATIO) {
|
|
102
|
+
if (Object.prototype.hasOwnProperty.call(OFFSET_TO_TARGET_RATIO, offset)) {
|
|
103
|
+
const ratio = OFFSET_TO_TARGET_RATIO[offset];
|
|
104
|
+
const nearestIndex = findNearestIndex(ratio, contrastRatios, startIndex);
|
|
105
|
+
startIndex = nearestIndex + 1;
|
|
106
|
+
palette[offset] = colors[nearestIndex];
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return palette;
|
|
110
|
+
});
|
|
111
|
+
const toColor = (colors, palette, opacity, scheme, hue, shade, offset, transparency) => {
|
|
112
|
+
let retVal;
|
|
113
|
+
let _hue = colors[hue] || hue;
|
|
114
|
+
if (Object.hasOwn(palette, _hue)) {
|
|
115
|
+
_hue = palette[_hue];
|
|
116
|
+
}
|
|
117
|
+
if (typeof _hue === 'object') {
|
|
118
|
+
retVal = toHex(_hue, shade, offset, scheme);
|
|
119
|
+
} else if (_hue === 'transparent' || isValidColor(_hue)) {
|
|
120
|
+
if (shade === undefined) {
|
|
121
|
+
retVal = _hue;
|
|
122
|
+
} else {
|
|
123
|
+
_hue = generateColorScale(_hue);
|
|
124
|
+
retVal = toHex(_hue, shade, offset, scheme);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (retVal && transparency) {
|
|
128
|
+
const alpha = transparency > 1 ? opacity[transparency] : transparency;
|
|
129
|
+
if (alpha === undefined) {
|
|
130
|
+
throw new Error('Error: invalid `transparency` parameter');
|
|
131
|
+
}
|
|
132
|
+
retVal = rgba(retVal, alpha);
|
|
133
|
+
}
|
|
134
|
+
return retVal;
|
|
135
|
+
};
|
|
136
|
+
const toProperty = (object, path) => {
|
|
137
|
+
const retVal = get(object, path);
|
|
138
|
+
if (typeof retVal === 'string') {
|
|
139
|
+
return retVal;
|
|
140
|
+
} else if (retVal === undefined) {
|
|
141
|
+
throw new ReferenceError(`Error: color variable '${path}' is not defined`);
|
|
142
|
+
} else {
|
|
143
|
+
throw new TypeError(`Error: unexpected '${typeof retVal}' type for color variable "${path}"`);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const fromRgba = value => {
|
|
147
|
+
let retVal;
|
|
148
|
+
const regex = /rgba\s*\(\s*(?<property>[#\w.]+)\s*,\s*(?<alpha>[\w.]+)\s*\)/gu;
|
|
149
|
+
const _rgba = regex.exec(value);
|
|
150
|
+
if (_rgba && _rgba.groups) {
|
|
151
|
+
const property = _rgba.groups.property;
|
|
152
|
+
const transparency = parseFloat(_rgba.groups.alpha);
|
|
153
|
+
retVal = {
|
|
154
|
+
property,
|
|
155
|
+
transparency
|
|
156
|
+
};
|
|
157
|
+
} else {
|
|
158
|
+
throw new Error(`Error: invalid \`rgba\` value "${value}"`);
|
|
159
|
+
}
|
|
160
|
+
return retVal;
|
|
161
|
+
};
|
|
162
|
+
const fromVariable = (variable, variables, palette) => {
|
|
163
|
+
const retVal = {};
|
|
164
|
+
let property = toProperty(variables, variable);
|
|
165
|
+
if (property.startsWith('rgba')) {
|
|
166
|
+
const value = fromRgba(property);
|
|
167
|
+
property = value.property;
|
|
168
|
+
retVal.transparency = value.transparency;
|
|
169
|
+
}
|
|
170
|
+
const [key, value] = property.split(/\.(?<value>.*)/u);
|
|
171
|
+
if (key === 'palette') {
|
|
172
|
+
retVal.hue = toProperty(palette, value);
|
|
173
|
+
} else {
|
|
174
|
+
retVal.hue = key;
|
|
175
|
+
if (value !== undefined) {
|
|
176
|
+
retVal.shade = parseInt(value, 10);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return retVal;
|
|
180
|
+
};
|
|
181
|
+
const getColor = memoize(_ref => {
|
|
182
|
+
let {
|
|
183
|
+
dark,
|
|
184
|
+
hue,
|
|
185
|
+
light,
|
|
186
|
+
offset,
|
|
187
|
+
shade,
|
|
188
|
+
theme,
|
|
189
|
+
transparency,
|
|
190
|
+
variable
|
|
191
|
+
} = _ref;
|
|
192
|
+
let retVal;
|
|
193
|
+
const palette = theme.palette && Object.keys(theme.palette).length > 0 ? theme.palette : DEFAULT_THEME.palette;
|
|
194
|
+
const {
|
|
195
|
+
base,
|
|
196
|
+
variables,
|
|
197
|
+
...colors
|
|
198
|
+
} = theme.colors && Object.keys(theme.colors).length > 0 ? theme.colors : DEFAULT_THEME.colors;
|
|
199
|
+
const scheme = base === 'dark' ? 'dark' : 'light';
|
|
200
|
+
const mode = scheme === 'dark' ? dark : light;
|
|
201
|
+
let _hue = mode?.hue || hue;
|
|
202
|
+
let _shade = mode?.shade === undefined ? shade : mode.shade;
|
|
203
|
+
const _offset = mode?.offset === undefined ? offset : mode.offset;
|
|
204
|
+
let _transparency = mode?.transparency === undefined ? transparency : mode.transparency;
|
|
205
|
+
if (variable) {
|
|
206
|
+
const _variables = variables?.[scheme] ? variables[scheme] : DEFAULT_THEME.colors.variables[scheme];
|
|
207
|
+
const value = fromVariable(variable, _variables, palette);
|
|
208
|
+
_hue = value.hue;
|
|
209
|
+
_shade = value.shade;
|
|
210
|
+
_transparency = _transparency === undefined ? value.transparency : _transparency;
|
|
211
|
+
}
|
|
212
|
+
if (_hue) {
|
|
213
|
+
const opacity = theme.opacity && Object.keys(theme.opacity).length > 0 ? theme.opacity : DEFAULT_THEME.opacity;
|
|
214
|
+
retVal = toColor(colors, palette, opacity, scheme, _hue, _shade, _offset, _transparency);
|
|
215
|
+
}
|
|
216
|
+
if (retVal === undefined) {
|
|
217
|
+
throw new Error('Error: invalid `getColor` parameters');
|
|
218
|
+
}
|
|
219
|
+
return retVal;
|
|
220
|
+
}, _ref2 => {
|
|
221
|
+
let {
|
|
222
|
+
dark,
|
|
223
|
+
hue,
|
|
224
|
+
light,
|
|
225
|
+
offset,
|
|
226
|
+
shade,
|
|
227
|
+
theme,
|
|
228
|
+
transparency,
|
|
229
|
+
variable
|
|
230
|
+
} = _ref2;
|
|
231
|
+
return JSON.stringify({
|
|
232
|
+
dark,
|
|
233
|
+
hue,
|
|
234
|
+
light,
|
|
235
|
+
offset,
|
|
236
|
+
shade,
|
|
237
|
+
colors: theme.colors,
|
|
238
|
+
palette: theme.palette,
|
|
239
|
+
opacity: theme.opacity,
|
|
240
|
+
transparency,
|
|
241
|
+
variable
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
export { getColor };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import DEFAULT_THEME from '../elements/theme/index.js';
|
|
8
|
+
import PALETTE_V8 from '../elements/palette/v8.js';
|
|
9
|
+
import { rgba, darken, lighten } from 'polished';
|
|
10
|
+
import memoize from 'lodash.memoize';
|
|
11
|
+
|
|
12
|
+
const DEFAULT_SHADE = 600;
|
|
13
|
+
const adjust = (color, expected, actual) => {
|
|
14
|
+
if (expected !== actual) {
|
|
15
|
+
const amount = Math.abs(expected - actual) / 100 * 0.05;
|
|
16
|
+
return expected > actual ? darken(amount, color) : lighten(amount, color);
|
|
17
|
+
}
|
|
18
|
+
return color;
|
|
19
|
+
};
|
|
20
|
+
const getColorV8 = memoize(function (hue) {
|
|
21
|
+
let shade = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_SHADE;
|
|
22
|
+
let theme = arguments.length > 2 ? arguments[2] : undefined;
|
|
23
|
+
let transparency = arguments.length > 3 ? arguments[3] : undefined;
|
|
24
|
+
let retVal;
|
|
25
|
+
if (isNaN(shade)) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
const palette = {
|
|
29
|
+
background: PALETTE_V8.white,
|
|
30
|
+
foreground: PALETTE_V8.grey[800],
|
|
31
|
+
...(theme && theme.palette ? {
|
|
32
|
+
...theme.palette,
|
|
33
|
+
...PALETTE_V8
|
|
34
|
+
} : {
|
|
35
|
+
...DEFAULT_THEME.palette,
|
|
36
|
+
...PALETTE_V8
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
const colors = theme && theme.colors ? theme.colors : DEFAULT_THEME.colors;
|
|
40
|
+
let _hue;
|
|
41
|
+
if (typeof hue === 'string') {
|
|
42
|
+
_hue = colors[hue] || hue;
|
|
43
|
+
} else {
|
|
44
|
+
_hue = hue;
|
|
45
|
+
}
|
|
46
|
+
if (Object.prototype.hasOwnProperty.call(palette, _hue)) {
|
|
47
|
+
_hue = palette[_hue];
|
|
48
|
+
}
|
|
49
|
+
if (typeof _hue === 'object') {
|
|
50
|
+
retVal = _hue[shade];
|
|
51
|
+
if (!retVal) {
|
|
52
|
+
const _shade = Object.keys(_hue).map(hueKey => parseInt(hueKey, 10)).reduce((previous, current) => {
|
|
53
|
+
return Math.abs(current - shade) < Math.abs(previous - shade) ? current : previous;
|
|
54
|
+
});
|
|
55
|
+
retVal = adjust(_hue[_shade], shade, _shade);
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
retVal = adjust(_hue, shade, DEFAULT_SHADE);
|
|
59
|
+
}
|
|
60
|
+
if (transparency) {
|
|
61
|
+
retVal = rgba(retVal, transparency);
|
|
62
|
+
}
|
|
63
|
+
return retVal;
|
|
64
|
+
}, (hue, shade, theme, transparency) => JSON.stringify({
|
|
65
|
+
hue,
|
|
66
|
+
shade,
|
|
67
|
+
palette: theme?.palette,
|
|
68
|
+
colors: theme?.colors,
|
|
69
|
+
transparency
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
export { DEFAULT_SHADE, getColorV8 };
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
const PLACEMENT_MAP = {
|
|
8
|
+
end: 'right',
|
|
9
|
+
'end-top': 'right-start',
|
|
10
|
+
'end-bottom': 'right-end',
|
|
11
|
+
start: 'left',
|
|
12
|
+
'start-top': 'left-start',
|
|
13
|
+
'start-bottom': 'left-end'
|
|
14
|
+
};
|
|
15
|
+
const RTL_PLACEMENT_MAP = {
|
|
16
|
+
left: 'right',
|
|
17
|
+
'left-start': 'right-start',
|
|
18
|
+
'left-end': 'right-end',
|
|
19
|
+
right: 'left',
|
|
20
|
+
'right-start': 'left-start',
|
|
21
|
+
'right-end': 'left-end'
|
|
22
|
+
};
|
|
23
|
+
const toFloatingPlacement = (placement, theme) => {
|
|
24
|
+
let retVal = PLACEMENT_MAP[placement] || placement;
|
|
25
|
+
if (theme.rtl) {
|
|
26
|
+
retVal = RTL_PLACEMENT_MAP[retVal] || retVal;
|
|
27
|
+
}
|
|
28
|
+
return retVal;
|
|
29
|
+
};
|
|
30
|
+
const SIDE_FALLBACKS_MAP = {
|
|
31
|
+
top: ['top-start', 'top', 'top-end'],
|
|
32
|
+
right: ['right-start', 'right', 'right-end'],
|
|
33
|
+
bottom: ['bottom-start', 'bottom', 'bottom-end'],
|
|
34
|
+
left: ['left-start', 'left', 'left-end']
|
|
35
|
+
};
|
|
36
|
+
const SIDE_OPPOSITE_MAP = {
|
|
37
|
+
top: 'bottom',
|
|
38
|
+
right: 'left',
|
|
39
|
+
bottom: 'top',
|
|
40
|
+
left: 'right'
|
|
41
|
+
};
|
|
42
|
+
const toFallbackPlacements = (primaryPlacement, theme, fallbackPlacements) => {
|
|
43
|
+
if (Array.isArray(fallbackPlacements) && fallbackPlacements.length > 0) {
|
|
44
|
+
return fallbackPlacements.map(fallbackPlacement => toFloatingPlacement(fallbackPlacement, theme));
|
|
45
|
+
}
|
|
46
|
+
const side = primaryPlacement.split('-')[0];
|
|
47
|
+
const sameSideFallbackPlacements = [...SIDE_FALLBACKS_MAP[side]];
|
|
48
|
+
const oppositeSideFallbackPlacements = SIDE_FALLBACKS_MAP[SIDE_OPPOSITE_MAP[side]];
|
|
49
|
+
sameSideFallbackPlacements.splice(sameSideFallbackPlacements.indexOf(primaryPlacement), 1);
|
|
50
|
+
return [...sameSideFallbackPlacements, ...oppositeSideFallbackPlacements];
|
|
51
|
+
};
|
|
52
|
+
const getFloatingPlacements = (theme, placement, fallbackPlacements) => {
|
|
53
|
+
const floatingPlacement = toFloatingPlacement(placement, theme);
|
|
54
|
+
const floatingFallbackPlacements = toFallbackPlacements(floatingPlacement, theme, fallbackPlacements);
|
|
55
|
+
return [floatingPlacement, floatingFallbackPlacements];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export { PLACEMENT_MAP, RTL_PLACEMENT_MAP, getFloatingPlacements };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import DEFAULT_THEME from '../elements/theme/index.js';
|
|
8
|
+
import { getColorV8 } from './getColorV8.js';
|
|
9
|
+
import { getColor } from './getColor.js';
|
|
10
|
+
|
|
11
|
+
const getFocusBoxShadow = _ref => {
|
|
12
|
+
let {
|
|
13
|
+
boxShadow,
|
|
14
|
+
inset = false,
|
|
15
|
+
color = {
|
|
16
|
+
variable: 'border.primaryEmphasis'
|
|
17
|
+
},
|
|
18
|
+
shadowWidth = 'md',
|
|
19
|
+
spacerColor = {
|
|
20
|
+
variable: 'background.default'
|
|
21
|
+
},
|
|
22
|
+
spacerWidth = 'xs',
|
|
23
|
+
theme = DEFAULT_THEME,
|
|
24
|
+
...args
|
|
25
|
+
} = _ref;
|
|
26
|
+
const _args = args;
|
|
27
|
+
const _color = _args.hue ? getColorV8(_args.hue, _args.shade, theme) : getColor({
|
|
28
|
+
...color,
|
|
29
|
+
theme
|
|
30
|
+
});
|
|
31
|
+
const shadow = theme.shadows[shadowWidth](_color);
|
|
32
|
+
if (spacerWidth === null) {
|
|
33
|
+
return `${inset ? 'inset' : ''} ${shadow}`;
|
|
34
|
+
}
|
|
35
|
+
const _spacerColor = _args.spacerHue ? getColorV8(_args.spacerHue, _args.spacerShade, theme) : getColor({
|
|
36
|
+
...spacerColor,
|
|
37
|
+
theme
|
|
38
|
+
});
|
|
39
|
+
const retVal = `
|
|
40
|
+
${inset ? 'inset' : ''} ${theme.shadows[spacerWidth](_spacerColor)},
|
|
41
|
+
${inset ? 'inset' : ''} ${shadow}`;
|
|
42
|
+
return boxShadow ? `${retVal}, ${boxShadow}` : retVal;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export { getFocusBoxShadow };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
import { getValueAndUnit } from 'polished';
|
|
8
|
+
|
|
9
|
+
function getLineHeight(height, fontSize) {
|
|
10
|
+
const [heightValue, heightUnit] = getValueAndUnit(height.toString());
|
|
11
|
+
const [fontSizeValue, fontSizeUnit] = getValueAndUnit(fontSize.toString());
|
|
12
|
+
const PIXELS = 'px';
|
|
13
|
+
if (heightUnit && heightUnit !== PIXELS) {
|
|
14
|
+
throw new Error(`Unexpected \`height\` with '${heightUnit}' units.`);
|
|
15
|
+
}
|
|
16
|
+
if (fontSizeUnit && fontSizeUnit !== PIXELS) {
|
|
17
|
+
throw new Error(`Unexpected \`fontSize\` with '${fontSizeUnit}' units.`);
|
|
18
|
+
}
|
|
19
|
+
return heightValue / fontSizeValue;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { getLineHeight as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright Zendesk, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed under the Apache License, Version 2.0
|
|
5
|
+
* found at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
+
*/
|
|
7
|
+
const getMenuPosition = placement => {
|
|
8
|
+
return placement.split('-')[0];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { getMenuPosition };
|