@via-profit/ui-kit 0.10.1 → 0.12.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 (42) hide show
  1. package/Badge/BadgeBase.d.ts +8 -3
  2. package/Badge/BadgeBase.js +5 -6
  3. package/Badge/BadgeContainer.d.ts +8 -0
  4. package/Badge/BadgeContainer.js +148 -10
  5. package/Badge/BadgeDeleteButton.d.ts +4 -4
  6. package/Badge/BadgeDeleteButton.js +5 -4
  7. package/Badge/BadgeDeleteIcon.d.ts +4 -0
  8. package/Badge/BadgeDeleteIcon.js +9 -0
  9. package/Badge/BadgeOutlined.js +2 -2
  10. package/Badge/BadgeStandard.js +2 -2
  11. package/Badge/BadgeStyled.d.ts +2 -5
  12. package/Badge/BadgeStyled.js +4 -163
  13. package/Badge/index.d.ts +3 -4
  14. package/Badge/index.js +17 -3
  15. package/CHANGELOG.md +23 -0
  16. package/Popper/Popper.js +17 -12
  17. package/ThemeProvider/tokens.d.ts +1 -1
  18. package/ThemeProvider/tokens.js +1 -1
  19. package/Toast/ToastContainer.d.ts +5 -3
  20. package/Toast/ToastContainer.js +1 -1
  21. package/Toast/ToastItem.d.ts +2 -2
  22. package/Toast/ToastItem.js +11 -1
  23. package/Toast/index.d.ts +1 -1
  24. package/Toast/store.d.ts +15 -0
  25. package/Toast/store.js +5 -1
  26. package/Tooltip/index.d.ts +6 -0
  27. package/Tooltip/index.js +9 -6
  28. package/esm/Badge/BadgeBase.js +5 -6
  29. package/esm/Badge/BadgeContainer.js +148 -10
  30. package/esm/Badge/BadgeDeleteButton.js +5 -4
  31. package/esm/Badge/BadgeDeleteIcon.js +4 -0
  32. package/esm/Badge/BadgeOutlined.js +2 -2
  33. package/esm/Badge/BadgeStandard.js +2 -2
  34. package/esm/Badge/BadgeStyled.js +2 -163
  35. package/esm/Badge/index.js +17 -3
  36. package/esm/Popper/Popper.js +17 -12
  37. package/esm/ThemeProvider/tokens.js +1 -1
  38. package/esm/Toast/ToastContainer.js +2 -2
  39. package/esm/Toast/ToastItem.js +12 -2
  40. package/esm/Toast/store.js +4 -0
  41. package/esm/Tooltip/index.js +9 -6
  42. package/package.json +6 -1
@@ -1,163 +1,2 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import React from 'react';
13
- import styled from '@emotion/styled';
14
- import { useTheme, css } from '@emotion/react';
15
- import Color from '../Color';
16
- import BadgeBase from './BadgeBase';
17
- import { themeFocusRing, BORDER_WIDTH } from '../ThemeProvider/tokens';
18
- const parseColor = (color, fallback) => {
19
- try {
20
- return Color.fromString(color);
21
- }
22
- catch (err) {
23
- console.error(`invalid color value «${color}»`);
24
- return fallback;
25
- }
26
- };
27
- const getStandardColors = (color, theme) => {
28
- switch (true) {
29
- case color === 'primary':
30
- return { $color: theme.color.accentPrimaryContrast, $background: theme.color.accentPrimary };
31
- case color === 'secondary':
32
- return {
33
- $color: theme.color.accentSecondaryContrast,
34
- $background: theme.color.accentSecondary,
35
- };
36
- case typeof color === 'undefined':
37
- case color === 'default':
38
- return { $background: theme.color.surface.darken(10), $color: theme.color.textPrimary };
39
- default: {
40
- const $background = parseColor(String(color), theme.color.surface);
41
- return {
42
- $background,
43
- $color: $background.getContrast(theme.color.textPrimary) > 5
44
- ? theme.color.textPrimary
45
- : theme.color.surface,
46
- };
47
- }
48
- }
49
- };
50
- const getOutlinedColors = (color, theme) => {
51
- switch (true) {
52
- case color === 'primary':
53
- return { $color: theme.color.accentPrimary, $background: theme.color.accentPrimary };
54
- case color === 'secondary':
55
- return { $color: theme.color.accentSecondary, $background: theme.color.accentSecondary };
56
- case typeof color === 'undefined':
57
- case color === 'default':
58
- return {
59
- $color: Color.fromString(theme.color.textPrimary.toString()),
60
- $background: theme.color.textPrimary.lighten(100),
61
- };
62
- default: {
63
- const c = parseColor(String(color), theme.color.textPrimary);
64
- return { $color: c, $background: c };
65
- }
66
- }
67
- };
68
- /**
69
- * The pale background of the color and the text of the same hue: dark on the light theme,
70
- * light on the dark one. `$background` is the color itself
71
- */
72
- const getSoftColors = (color, theme) => {
73
- const base = color === 'primary'
74
- ? theme.color.accentPrimary
75
- : color === 'secondary'
76
- ? theme.color.accentSecondary
77
- : typeof color === 'undefined' || color === 'default'
78
- ? theme.color.textPrimary
79
- : parseColor(String(color), theme.color.textPrimary);
80
- return {
81
- $background: base,
82
- $color: theme.isDark ? base.lighten(60) : base.darken(60),
83
- };
84
- };
85
- /**
86
- * Both variants are one styled component: switching the variant (e.g. a toggling filter badge)
87
- * must not remount the element, otherwise the focused badge loses the focus
88
- */
89
- const StyledBadge = styled(BadgeBase) `
90
- border-style: solid;
91
- border-width: ${BORDER_WIDTH};
92
- border-color: ${({ $background }) => $background.toString()};
93
- --badge-dot-color: ${({ $variant, $background, $color }) => ($variant === 'standard' ? $color : $background).toString()};
94
-
95
- ${({ $variant, $color, $background }) => $variant === 'soft' &&
96
- css `
97
- color: ${$color.toString()};
98
- background-color: ${$background.alpha(0.18).toString()};
99
- border-color: transparent;
100
-
101
- &:focus-visible {
102
- outline-style: solid;
103
- outline-width: 0.14em;
104
- outline-color: ${$background.alpha(0.6).toString()};
105
- }
106
- `}
107
-
108
- ${({ $variant, $color, $background, theme }) => $variant === 'soft'
109
- ? ''
110
- : $variant === 'outlined'
111
- ? css `
112
- color: ${$color.darken(30).toString()};
113
- background-color: transparent;
114
-
115
- &:focus-visible {
116
- outline-style: solid;
117
- outline-width: 0.14em;
118
- outline-color: ${$background.rgbString()};
119
- }
120
- `
121
- : css `
122
- color: ${$color.toString()};
123
- background-color: ${$background.toString()};
124
-
125
- &:focus-visible {
126
- outline-color: ${$background.rgbString() === theme.color.accentPrimary.rgbString()
127
- ? theme.color.textPrimary.toString()
128
- : theme.color.accentPrimary.toString()};
129
- }
130
- `}
131
-
132
- ${({ $clickable, $variant, $background }) => $clickable &&
133
- css `
134
- cursor: pointer;
135
-
136
- &:hover {
137
- ${$variant === 'soft'
138
- ? css `
139
- background-color: ${$background.alpha(0.3).toString()};
140
- `
141
- : $variant === 'outlined'
142
- ? css `
143
- background-color: ${$background.darken(20).alpha(0.1).toString()};
144
- `
145
- : css `
146
- background-color: ${$background.darken(30).toString()};
147
- border-color: ${$background.darken(30).toString()};
148
- `}
149
- }
150
- `}
151
- ${({ theme }) => themeFocusRing(theme)}
152
- `;
153
- const BadgeStyled = (props, ref) => {
154
- const { children, color, variant = 'standard', onClick } = props, restProps = __rest(props, ["children", "color", "variant", "onClick"]);
155
- const theme = useTheme();
156
- const { $background, $color } = React.useMemo(() => variant === 'soft'
157
- ? getSoftColors(color, theme)
158
- : variant === 'outlined'
159
- ? getOutlinedColors(color, theme)
160
- : getStandardColors(color, theme), [color, variant, theme]);
161
- return (React.createElement(StyledBadge, Object.assign({ "$variant": variant, "$clickable": typeof onClick === 'function', "$color": $color, "$background": $background, color: color, variant: variant, onClick: onClick }, restProps, { ref: ref }), children));
162
- };
163
- export default React.forwardRef(BadgeStyled);
1
+ // Preserve the old import path without adding a wrapper around Badge
2
+ export { default } from './index';
@@ -1,5 +1,19 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
1
12
  import React from 'react';
2
- import BadgeStyled from './BadgeStyled';
3
- // One component for both variants, so changing the variant does not remount the badge
4
- const Badge = (props, ref) => (React.createElement(BadgeStyled, Object.assign({}, props, { ref: ref })));
13
+ import BadgeBase from './BadgeBase';
14
+ // One component for all variants, so changing the variant does not remount the badge
15
+ const Badge = (_a, ref) => {
16
+ var { variant = 'standard' } = _a, props = __rest(_a, ["variant"]);
17
+ return React.createElement(BadgeBase, Object.assign({}, props, { variant: variant, ref: ref }));
18
+ };
5
19
  export default React.forwardRef(Badge);
@@ -61,19 +61,24 @@ const Popper = (props, ref) => {
61
61
  }
62
62
  }, [actualPlacement]);
63
63
  const childrenMemo = React.useMemo(() => children, [children]);
64
- const renderNode = React.useCallback(() => (React.createElement(overridesMap.Container, Object.assign({}, nativeProps, { style: Object.assign(Object.assign(Object.assign(Object.assign({}, style), nativeProps.style), { opacity: isVisible ? 1 : 0, pointerEvents: isVisible ? 'auto' : 'none' }), (positionStrategy === 'fixed' && {
65
- position: 'fixed',
66
- })), zIndex: zIndex, positionStrategy: positionStrategy, "data-popper-placement": actualPlacement, "data-popper-strategy": positionStrategy, ref: el => {
67
- popperRef.current = el;
68
- if (ref) {
69
- if (typeof ref === 'function') {
70
- ref(el);
64
+ const renderNode = React.useCallback(() => {
65
+ var _a, _b;
66
+ return (React.createElement(overridesMap.Container, Object.assign({}, nativeProps, { style: Object.assign(Object.assign(Object.assign(Object.assign({}, style), nativeProps.style), { opacity: isVisible ? 1 : 0,
67
+ // A hidden popper never intercepts the pointer; a visible one lets the caller opt out
68
+ pointerEvents: !isVisible ? 'none' : ((_b = (_a = nativeProps.style) === null || _a === void 0 ? void 0 : _a.pointerEvents) !== null && _b !== void 0 ? _b : 'auto') }), (positionStrategy === 'fixed' && {
69
+ position: 'fixed',
70
+ })), zIndex: zIndex, positionStrategy: positionStrategy, "data-popper-placement": actualPlacement, "data-popper-strategy": positionStrategy, ref: el => {
71
+ popperRef.current = el;
72
+ if (ref) {
73
+ if (typeof ref === 'function') {
74
+ ref(el);
75
+ }
76
+ if (typeof ref === 'object') {
77
+ ref.current = el;
78
+ }
71
79
  }
72
- if (typeof ref === 'object') {
73
- ref.current = el;
74
- }
75
- }
76
- } }), childrenMemo)), [
80
+ } }), childrenMemo));
81
+ }, [
77
82
  overridesMap,
78
83
  nativeProps,
79
84
  style,
@@ -46,7 +46,7 @@ export const CONTROL_LINE_HEIGHT = '1.2em';
46
46
  */
47
47
  export const BORDER_WIDTH = '0.0625em';
48
48
  /**
49
- * The border of the buttons. The standard and the plain buttons have no border:
49
+ * The border of the buttons. The standard, plain and soft buttons have no border:
50
50
  * their padding is larger by this width, so all the variants have the same size
51
51
  */
52
52
  export const CONTROL_BORDER = BORDER_WIDTH;
@@ -7,7 +7,7 @@ import Icon from './ToastIcon';
7
7
  import CloseButton from './ToastCloseButton';
8
8
  import Action from './ToastAction';
9
9
  import ToastItem from './ToastItem';
10
- import { toastStore } from './store';
10
+ import { toastStore, TOAST_DEFAULT_AUTO_CLOSE, } from './store';
11
11
  const POSITIONS = [
12
12
  'top-left',
13
13
  'top-center',
@@ -84,7 +84,7 @@ const useWindowFocused = () => {
84
84
  return isFocused;
85
85
  };
86
86
  const ToastContainer = props => {
87
- const { containerId, position = 'top-right', autoClose = 5000, limit, closeButton = true, closeButtonLabel = 'Close', closeOnClick = true, pauseOnHover = true, pauseOnFocusLoss = true, newestOnTop = false, hotkey = 'F8', label = 'Notifications', zIndex, overrides, } = props;
87
+ const { containerId, position = 'top-right', autoClose = TOAST_DEFAULT_AUTO_CLOSE, limit, closeButton = true, closeButtonLabel = 'Close', closeOnClick = true, pauseOnHover = true, pauseOnFocusLoss = true, newestOnTop = false, hotkey = 'F8', label = 'Notifications', zIndex, overrides, } = props;
88
88
  const theme = useTheme();
89
89
  const allToasts = React.useSyncExternalStore(toastStore.subscribe, toastStore.getSnapshot, toastStore.getServerSnapshot);
90
90
  const toasts = React.useMemo(() => allToasts.filter(item => item.containerId === containerId), [allToasts, containerId]);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import styled from '@emotion/styled';
3
3
  import { TOAST_ANIMATION_MS } from './ToastCard';
4
- import { toast as toastApi, toastStore } from './store';
4
+ import { toast as toastApi, toastStore, TOAST_DEFAULT_AUTO_CLOSE, } from './store';
5
5
  const Body = styled.div `
6
6
  flex: 1;
7
7
  min-width: 0;
@@ -23,12 +23,22 @@ const Actions = styled.div `
23
23
  * The clicks on these elements are actions, not the click on the toast
24
24
  */
25
25
  const INTERACTIVE = 'a, button, input, select, textarea, label, summary, [role="button"], [contenteditable="true"]';
26
+ /**
27
+ * The `autoClose` of the toast type: the own value of the type, then `default`, then 5000
28
+ */
29
+ const getAutoClose = (autoClose, type) => {
30
+ var _a, _b;
31
+ if (typeof autoClose === 'number' || autoClose === false) {
32
+ return autoClose;
33
+ }
34
+ return (_b = (_a = autoClose[type]) !== null && _a !== void 0 ? _a : autoClose.default) !== null && _b !== void 0 ? _b : TOAST_DEFAULT_AUTO_CLOSE;
35
+ };
26
36
  const ToastItem = props => {
27
37
  var _a, _b, _c, _d, _e;
28
38
  const { toast, position, defaults, components, isWindowFocused } = props;
29
39
  const { toastId, content, type = 'default', isLoading = false, description, actions, icon, onClick, onOpen, isClosing, version, } = toast;
30
40
  // The loading toast waits for `toast.update`: it can not be closed by the timer or by the click
31
- const autoClose = isLoading ? false : ((_a = toast.autoClose) !== null && _a !== void 0 ? _a : defaults.autoClose);
41
+ const autoClose = isLoading ? false : ((_a = toast.autoClose) !== null && _a !== void 0 ? _a : getAutoClose(defaults.autoClose, type));
32
42
  const closeButton = isLoading ? false : ((_b = toast.closeButton) !== null && _b !== void 0 ? _b : defaults.closeButton);
33
43
  const closeOnClick = isLoading ? false : ((_c = toast.closeOnClick) !== null && _c !== void 0 ? _c : defaults.closeOnClick);
34
44
  const pauseOnHover = (_d = toast.pauseOnHover) !== null && _d !== void 0 ? _d : defaults.pauseOnHover;
@@ -9,6 +9,10 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
+ /**
13
+ * The time to close the toast when `autoClose` does not set one
14
+ */
15
+ export const TOAST_DEFAULT_AUTO_CLOSE = 5000;
12
16
  let toasts = [];
13
17
  const listeners = new Set();
14
18
  let idCounter = 0;
@@ -40,7 +40,7 @@ const setRef = (ref, value) => {
40
40
  const isEmptyTitle = (title) => title === null || typeof title === 'undefined' || title === false || title === '';
41
41
  const Tooltip = props => {
42
42
  var _a;
43
- const { title, children, placement = 'top', arrow = false, enterDelay = 400, leaveDelay = 100, isOpen, onOpenChange, describeChild = false, offset = 8, zIndex, id, overrides, } = props;
43
+ const { title, children, placement = 'top', arrow = false, enterDelay = 400, leaveDelay = 100, isOpen, onOpenChange, describeChild = false, interactive = false, offset = 8, zIndex, id, overrides, } = props;
44
44
  const theme = useTheme();
45
45
  const generatedId = `tooltip-${React.useId().replace(/:/g, '')}`;
46
46
  const tooltipId = id || generatedId;
@@ -177,12 +177,15 @@ const Tooltip = props => {
177
177
  return (React.createElement(React.Fragment, null,
178
178
  anchor,
179
179
  React.createElement(Popper, { isOpen: open, anchorElement: anchorElement, anchorPos: placement, autoFlip: true, offset: offset, viewportMargin: 8, zIndex: zIndex !== null && zIndex !== void 0 ? zIndex : theme.zIndex.modal + 1, onAnchorPosChanged: setActualPlacement, id: tooltipId, role: "tooltip",
180
- // The pointer can move from the element onto the tooltip without hiding it
181
- onPointerEnter: clearTimer, onPointerLeave: event => {
182
- if (isHoverPointer(event)) {
183
- hide(leaveDelay);
180
+ // Without `interactive` the tooltip must not intercept the pointer: otherwise it
181
+ // blocks the elements under it and sticks under the cursor that moves across it
182
+ style: interactive ? undefined : { pointerEvents: 'none' }, onPointerEnter: interactive ? clearTimer : undefined, onPointerLeave: interactive
183
+ ? event => {
184
+ if (isHoverPointer(event)) {
185
+ hide(leaveDelay);
186
+ }
184
187
  }
185
- } },
188
+ : undefined },
186
189
  React.createElement(overridesMap.Container, null,
187
190
  title,
188
191
  arrow && React.createElement(overridesMap.Arrow, { placement: actualPlacement })))));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@via-profit/ui-kit",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "description": "UI Kit",
5
5
  "repository": {
6
6
  "type": "git",
@@ -150,6 +150,11 @@
150
150
  "import": "./esm/Badge/BadgeDeleteButton.js",
151
151
  "require": "./Badge/BadgeDeleteButton.js"
152
152
  },
153
+ "./Badge/BadgeDeleteIcon": {
154
+ "types": "./Badge/BadgeDeleteIcon.d.ts",
155
+ "import": "./esm/Badge/BadgeDeleteIcon.js",
156
+ "require": "./Badge/BadgeDeleteIcon.js"
157
+ },
153
158
  "./Badge/BadgeDot": {
154
159
  "types": "./Badge/BadgeDot.d.ts",
155
160
  "import": "./esm/Badge/BadgeDot.js",