@veracity/vui 2.11.0 → 2.12.0-beta.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 (158) hide show
  1. package/dist/cjs/button/buttonIcon.d.ts.map +1 -1
  2. package/dist/cjs/button/buttonIcon.js +4 -2
  3. package/dist/cjs/core/vuiProvider/consts.d.ts +2 -0
  4. package/dist/cjs/core/vuiProvider/consts.d.ts.map +1 -0
  5. package/dist/cjs/core/vuiProvider/consts.js +4 -0
  6. package/dist/cjs/core/vuiProvider/globalStyle.d.ts.map +1 -1
  7. package/dist/cjs/core/vuiProvider/globalStyle.js +6 -0
  8. package/dist/cjs/core/vuiProvider/index.d.ts +2 -0
  9. package/dist/cjs/core/vuiProvider/index.d.ts.map +1 -1
  10. package/dist/cjs/core/vuiProvider/index.js +2 -0
  11. package/dist/cjs/core/vuiProvider/useBodyScrollLock.d.ts +7 -0
  12. package/dist/cjs/core/vuiProvider/useBodyScrollLock.d.ts.map +1 -0
  13. package/dist/cjs/core/vuiProvider/useBodyScrollLock.js +18 -0
  14. package/dist/cjs/core/vuiProvider/vuiProvider.d.ts.map +1 -1
  15. package/dist/cjs/core/vuiProvider/vuiProvider.js +0 -2
  16. package/dist/cjs/definition/definition.d.ts.map +1 -1
  17. package/dist/cjs/definition/definition.js +0 -1
  18. package/dist/cjs/dialog/consts.d.ts +0 -1
  19. package/dist/cjs/dialog/consts.d.ts.map +1 -1
  20. package/dist/cjs/dialog/consts.js +1 -2
  21. package/dist/cjs/focusLock/focusLock.d.ts +11 -0
  22. package/dist/cjs/focusLock/focusLock.d.ts.map +1 -0
  23. package/dist/cjs/{modal → focusLock}/focusLock.js +3 -3
  24. package/dist/cjs/focusLock/focusLock.types.d.ts.map +1 -0
  25. package/dist/cjs/focusLock/index.d.ts +4 -0
  26. package/dist/cjs/focusLock/index.d.ts.map +1 -0
  27. package/dist/cjs/focusLock/index.js +24 -0
  28. package/dist/cjs/footer/footer.d.ts.map +1 -1
  29. package/dist/cjs/footer/footer.js +5 -1
  30. package/dist/cjs/footer/footer.types.d.ts +2 -1
  31. package/dist/cjs/footer/footer.types.d.ts.map +1 -1
  32. package/dist/cjs/index.d.ts +1 -0
  33. package/dist/cjs/index.d.ts.map +1 -1
  34. package/dist/cjs/index.js +1 -0
  35. package/dist/cjs/input/consts.d.ts +6 -0
  36. package/dist/cjs/input/consts.d.ts.map +1 -1
  37. package/dist/cjs/input/consts.js +7 -1
  38. package/dist/cjs/input/input.d.ts.map +1 -1
  39. package/dist/cjs/input/input.js +3 -3
  40. package/dist/cjs/input/input.types.d.ts +2 -0
  41. package/dist/cjs/input/input.types.d.ts.map +1 -1
  42. package/dist/cjs/modal/index.d.ts +2 -2
  43. package/dist/cjs/modal/index.d.ts.map +1 -1
  44. package/dist/cjs/modal/index.js +2 -2
  45. package/dist/cjs/modal/modal.d.ts.map +1 -1
  46. package/dist/cjs/modal/modal.js +1 -1
  47. package/dist/cjs/modal/modal.types.d.ts +1 -1
  48. package/dist/cjs/modal/modal.types.d.ts.map +1 -1
  49. package/dist/cjs/modal/modalManager.d.ts +2 -2
  50. package/dist/cjs/modal/modalManager.d.ts.map +1 -1
  51. package/dist/cjs/modal/modalManager.js +6 -9
  52. package/dist/cjs/sidemenu/sidemenu.d.ts +0 -1
  53. package/dist/cjs/sidemenu/sidemenu.d.ts.map +1 -1
  54. package/dist/cjs/sidemenu/sidemenu.js +10 -11
  55. package/dist/cjs/sidemenu/sidemenu.types.d.ts +4 -0
  56. package/dist/cjs/sidemenu/sidemenu.types.d.ts.map +1 -1
  57. package/dist/cjs/sidemenu/sidemenuItem.d.ts.map +1 -1
  58. package/dist/cjs/sidemenu/sidemenuItem.js +1 -1
  59. package/dist/esm/button/buttonIcon.d.ts.map +1 -1
  60. package/dist/esm/button/buttonIcon.js +4 -2
  61. package/dist/esm/core/vuiProvider/consts.d.ts +2 -0
  62. package/dist/esm/core/vuiProvider/consts.d.ts.map +1 -0
  63. package/dist/esm/core/vuiProvider/consts.js +1 -0
  64. package/dist/esm/core/vuiProvider/globalStyle.d.ts.map +1 -1
  65. package/dist/esm/core/vuiProvider/globalStyle.js +6 -0
  66. package/dist/esm/core/vuiProvider/index.d.ts +2 -0
  67. package/dist/esm/core/vuiProvider/index.d.ts.map +1 -1
  68. package/dist/esm/core/vuiProvider/index.js +2 -0
  69. package/dist/esm/core/vuiProvider/useBodyScrollLock.d.ts +7 -0
  70. package/dist/esm/core/vuiProvider/useBodyScrollLock.d.ts.map +1 -0
  71. package/dist/esm/core/vuiProvider/useBodyScrollLock.js +14 -0
  72. package/dist/esm/core/vuiProvider/vuiProvider.d.ts.map +1 -1
  73. package/dist/esm/core/vuiProvider/vuiProvider.js +0 -2
  74. package/dist/esm/definition/definition.d.ts.map +1 -1
  75. package/dist/esm/definition/definition.js +0 -1
  76. package/dist/esm/dialog/consts.d.ts +0 -1
  77. package/dist/esm/dialog/consts.d.ts.map +1 -1
  78. package/dist/esm/dialog/consts.js +0 -1
  79. package/dist/esm/focusLock/focusLock.d.ts +11 -0
  80. package/dist/esm/focusLock/focusLock.d.ts.map +1 -0
  81. package/dist/esm/{modal → focusLock}/focusLock.js +3 -3
  82. package/dist/esm/focusLock/focusLock.types.d.ts.map +1 -0
  83. package/dist/esm/focusLock/index.d.ts +4 -0
  84. package/dist/esm/focusLock/index.d.ts.map +1 -0
  85. package/dist/esm/focusLock/index.js +3 -0
  86. package/dist/esm/footer/footer.d.ts.map +1 -1
  87. package/dist/esm/footer/footer.js +5 -1
  88. package/dist/esm/footer/footer.types.d.ts +2 -1
  89. package/dist/esm/footer/footer.types.d.ts.map +1 -1
  90. package/dist/esm/index.d.ts +1 -0
  91. package/dist/esm/index.d.ts.map +1 -1
  92. package/dist/esm/index.js +1 -0
  93. package/dist/esm/input/consts.d.ts +6 -0
  94. package/dist/esm/input/consts.d.ts.map +1 -1
  95. package/dist/esm/input/consts.js +6 -0
  96. package/dist/esm/input/input.d.ts.map +1 -1
  97. package/dist/esm/input/input.js +4 -4
  98. package/dist/esm/input/input.types.d.ts +2 -0
  99. package/dist/esm/input/input.types.d.ts.map +1 -1
  100. package/dist/esm/modal/index.d.ts +2 -2
  101. package/dist/esm/modal/index.d.ts.map +1 -1
  102. package/dist/esm/modal/index.js +2 -2
  103. package/dist/esm/modal/modal.d.ts.map +1 -1
  104. package/dist/esm/modal/modal.js +1 -1
  105. package/dist/esm/modal/modal.types.d.ts +1 -1
  106. package/dist/esm/modal/modal.types.d.ts.map +1 -1
  107. package/dist/esm/modal/modalManager.d.ts +2 -2
  108. package/dist/esm/modal/modalManager.d.ts.map +1 -1
  109. package/dist/esm/modal/modalManager.js +6 -9
  110. package/dist/esm/sidemenu/sidemenu.d.ts +0 -1
  111. package/dist/esm/sidemenu/sidemenu.d.ts.map +1 -1
  112. package/dist/esm/sidemenu/sidemenu.js +9 -11
  113. package/dist/esm/sidemenu/sidemenu.types.d.ts +4 -0
  114. package/dist/esm/sidemenu/sidemenu.types.d.ts.map +1 -1
  115. package/dist/esm/sidemenu/sidemenuItem.d.ts.map +1 -1
  116. package/dist/esm/sidemenu/sidemenuItem.js +2 -0
  117. package/package.json +1 -1
  118. package/src/button/buttonIcon.tsx +6 -3
  119. package/src/core/vuiProvider/consts.ts +1 -0
  120. package/src/core/vuiProvider/globalStyle.tsx +6 -0
  121. package/src/core/vuiProvider/index.ts +2 -0
  122. package/src/core/vuiProvider/useBodyScrollLock.tsx +17 -0
  123. package/src/core/vuiProvider/vuiProvider.tsx +0 -2
  124. package/src/definition/definition.tsx +0 -3
  125. package/src/dialog/consts.ts +0 -2
  126. package/src/{modal → focusLock}/focusLock.tsx +4 -3
  127. package/src/focusLock/index.ts +3 -0
  128. package/src/footer/footer.tsx +29 -1
  129. package/src/footer/footer.types.ts +2 -1
  130. package/src/index.ts +1 -0
  131. package/src/input/consts.ts +7 -0
  132. package/src/input/input.tsx +66 -55
  133. package/src/input/input.types.ts +2 -0
  134. package/src/modal/index.ts +2 -2
  135. package/src/modal/modal.tsx +1 -2
  136. package/src/modal/modal.types.ts +1 -1
  137. package/src/modal/modalManager.ts +6 -9
  138. package/src/sidemenu/sidemenu.tsx +23 -13
  139. package/src/sidemenu/sidemenu.types.ts +4 -0
  140. package/src/sidemenu/sidemenuItem.tsx +2 -0
  141. package/dist/cjs/modal/focusLock.d.ts +0 -11
  142. package/dist/cjs/modal/focusLock.d.ts.map +0 -1
  143. package/dist/cjs/modal/focusLock.types.d.ts.map +0 -1
  144. package/dist/cjs/modal/modalStyle.d.ts +0 -3
  145. package/dist/cjs/modal/modalStyle.d.ts.map +0 -1
  146. package/dist/cjs/modal/modalStyle.js +0 -10
  147. package/dist/esm/modal/focusLock.d.ts +0 -11
  148. package/dist/esm/modal/focusLock.d.ts.map +0 -1
  149. package/dist/esm/modal/focusLock.types.d.ts.map +0 -1
  150. package/dist/esm/modal/modalStyle.d.ts +0 -3
  151. package/dist/esm/modal/modalStyle.d.ts.map +0 -1
  152. package/dist/esm/modal/modalStyle.js +0 -8
  153. package/src/modal/modalStyle.ts +0 -9
  154. /package/dist/cjs/{modal → focusLock}/focusLock.types.d.ts +0 -0
  155. /package/dist/cjs/{modal → focusLock}/focusLock.types.js +0 -0
  156. /package/dist/esm/{modal → focusLock}/focusLock.types.d.ts +0 -0
  157. /package/dist/esm/{modal → focusLock}/focusLock.types.js +0 -0
  158. /package/src/{modal → focusLock}/focusLock.types.ts +0 -0
@@ -1,15 +1,11 @@
1
1
  import { useEffect } from 'react';
2
- import { addBodyClass, removeBodyClass } from '../utils/dom';
2
+ import { useBodyScrollLock } from '../core';
3
3
  /** State management for nested modals. */
4
4
  class ModalManager {
5
5
  constructor() {
6
6
  this.modals = [];
7
- this.add = (modal) => {
8
- this.modals.push(modal);
9
- };
10
- this.remove = (modal) => {
11
- this.modals = this.modals.filter(m => m !== modal);
12
- };
7
+ this.add = (modal) => this.modals.push(modal);
8
+ this.remove = (modal) => (this.modals = this.modals.filter(m => m !== modal));
13
9
  this.isTopModal = (modal) => {
14
10
  const topmostModal = this.modals[this.modals.length - 1];
15
11
  return topmostModal === modal;
@@ -19,16 +15,17 @@ class ModalManager {
19
15
  export const manager = new ModalManager();
20
16
  /** Refs of new modals will be automatically added/removed from the state when rendering. */
21
17
  export function useModalManager(ref, isOpen, disableScrollLock) {
18
+ const { setIsScrollLocked } = useBodyScrollLock();
22
19
  useEffect(() => {
23
20
  if (isOpen) {
24
21
  manager.add(ref);
25
22
  if (!disableScrollLock)
26
- addBodyClass('vui-no-scroll');
23
+ setIsScrollLocked(true);
27
24
  }
28
25
  return () => {
29
26
  manager.remove(ref);
30
27
  if (!disableScrollLock)
31
- removeBodyClass('vui-no-scroll');
28
+ setIsScrollLocked(false);
32
29
  };
33
30
  }, [isOpen, ref]);
34
31
  }
@@ -2,7 +2,6 @@ import { VuiComponent } from '../core';
2
2
  import { SidemenuProps } from './sidemenu.types';
3
3
  import SidemenuItem from './sidemenuItem';
4
4
  import SidemenuTop from './sidemenuTop';
5
- export declare const SidemenuBase: import("styled-components").StyledComponent<"div", import("styled-components").DefaultTheme, import("..").SystemProps, never>;
6
5
  /** A collapsible side menu for navigation. */
7
6
  export declare const Sidemenu: VuiComponent<"div", SidemenuProps> & {
8
7
  Top: typeof SidemenuTop;
@@ -1 +1 @@
1
- {"version":3,"file":"sidemenu.d.ts","sourceRoot":"","sources":["../../../src/sidemenu/sidemenu.tsx"],"names":[],"mappings":"AAIA,OAAO,EAA+B,YAAY,EAAE,MAAM,SAAS,CAAA;AAKnE,OAAO,EAAqB,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,YAAY,MAAM,gBAAgB,CAAA;AACzC,OAAO,WAAW,MAAM,eAAe,CAAA;AAEvC,eAAO,MAAM,YAAY,+HAMxB,CAAA;AAED,8CAA8C;AAC9C,eAAO,MAAM,QAAQ;SA+Cd,kBAAkB;UACjB,mBAAmB;CAC1B,CAAA;AAKD,eAAe,QAAQ,CAAA"}
1
+ {"version":3,"file":"sidemenu.d.ts","sourceRoot":"","sources":["../../../src/sidemenu/sidemenu.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAuB,YAAY,EAAE,MAAM,SAAS,CAAA;AAK3D,OAAO,EAAqB,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACnE,OAAO,YAAY,MAAM,gBAAgB,CAAA;AACzC,OAAO,WAAW,MAAM,eAAe,CAAA;AAEvC,8CAA8C;AAC9C,eAAO,MAAM,QAAQ;SAiEd,kBAAkB;UACjB,mBAAmB;CAC1B,CAAA;AAKD,eAAe,QAAQ,CAAA"}
@@ -1,23 +1,16 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
2
  import Box from '../box';
3
3
  import Button from '../button';
4
- import { styled, useStyleConfig, vui } from '../core';
4
+ import { useStyleConfig, vui } from '../core';
5
5
  import Icon from '../icon';
6
6
  import { cs, filterUndefined } from '../utils';
7
7
  import { expandedWidth } from './consts';
8
8
  import { SidemenuProvider } from './context';
9
9
  import SidemenuItem from './sidemenuItem';
10
10
  import SidemenuTop from './sidemenuTop';
11
- export const SidemenuBase = styled.divBox `
12
- display: flex;
13
- flex-direction: column;
14
- min-width: 0;
15
- transition-duration: normal;
16
- overflow: hidden;
17
- `;
18
11
  /** A collapsible side menu for navigation. */
19
12
  export const Sidemenu = vui((props, ref) => {
20
- const { children, className, items, isExpanded = false, size, variant, width = 280, ...rest } = props;
13
+ const { children, className, items, isExpanded = false, size, variant, width = 280, onNavigate, ...rest } = props;
21
14
  const [isExpandedInternal, setIsExpandedInternal] = useState(isExpanded);
22
15
  const context = useMemo(() => filterUndefined({ size, variant, isExpandedInternal }), [size, variant, isExpandedInternal]);
23
16
  const styles = useStyleConfig('Sidemenu', props);
@@ -29,10 +22,15 @@ export const Sidemenu = vui((props, ref) => {
29
22
  const w = isExpandedInternal ? width : expandedWidth;
30
23
  const icon = `falArrow${isExpandedInternal ? 'Left' : 'Right'}`;
31
24
  const justifyContent = isExpandedInternal ? 'flex-end' : 'center';
25
+ function onItemClick(item) {
26
+ item?.onClick?.();
27
+ if (item?.path)
28
+ onNavigate?.(item.path);
29
+ }
32
30
  return (React.createElement(SidemenuProvider, { value: context },
33
- React.createElement(SidemenuBase, { className: cs('vui-sidemenu', className), ref: ref, w: w, ...styles.container, ...rest },
31
+ React.createElement(Box, { className: cs('vui-sidemenu', className), elevation: "3", flexDirection: "column", minWidth: 0, overflowX: "hidden", ref: ref, transitionDuration: "normal", w: w, ...styles.container, ...rest },
34
32
  React.createElement(Box, { flexDirection: "column", flexGrow: 1, overflowX: "hidden", overflowY: "auto", w: "100%" }, items
35
- ? items?.map?.((item, key) => React.createElement(SidemenuItem, { key: key, ...item }))
33
+ ? items?.map?.((item, key) => (React.createElement(SidemenuItem, { key: key, ...item, onClick: () => onItemClick(item) })))
36
34
  : children),
37
35
  React.createElement(Box, { className: "vui-sidemenu-bottom", w: "100%", ...styles.bottom },
38
36
  React.createElement(Button, { borderRadius: 0, justifyContent: justifyContent, minH: size === 'lg' ? '56px' : '40px', onClick: onToggle, variant: isDark ? 'tertiaryLight' : 'tertiaryDark', w: "100%" },
@@ -9,6 +9,8 @@ export type SidemenuProps = SystemProps & ThemingProps<'Sidemenu'> & {
9
9
  items?: SidemenuItemProps[];
10
10
  /** Whether the menu is expanded @default false */
11
11
  isExpanded?: boolean;
12
+ /** External callback for navigation to the item path, could be a custom function or React Router hook: https://reactrouter.com/en/main/hooks/use-navigate */
13
+ onNavigate?: (to: string) => void;
12
14
  /** With of the container when the side menu is expanded @default 280 */
13
15
  width?: number;
14
16
  };
@@ -25,6 +27,8 @@ export type SidemenuItemProps = BoxProps & {
25
27
  isActive?: boolean;
26
28
  /** On click callback */
27
29
  onClick?: () => void;
30
+ /** Router path */
31
+ path?: string;
28
32
  /** Title */
29
33
  title: string;
30
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"sidemenu.types.d.ts","sourceRoot":"","sources":["../../../src/sidemenu/sidemenu.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,YAAY,CAAA;AAE3D,MAAM,MAAM,aAAa,GAAG,WAAW,GACrC,YAAY,CAAC,UAAU,CAAC,GAAG;IACzB,gCAAgC;IAChC,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC3B,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG;IACzC,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe;IACf,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,wBAAwB;IACxB,IAAI,EAAE,QAAQ,CAAA;IACd,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IACtB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,YAAY;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG;IACxC,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,sDAAsD;IACtD,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA"}
1
+ {"version":3,"file":"sidemenu.types.d.ts","sourceRoot":"","sources":["../../../src/sidemenu/sidemenu.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,YAAY,CAAA;AAE3D,MAAM,MAAM,aAAa,GAAG,WAAW,GACrC,YAAY,CAAC,UAAU,CAAC,GAAG;IACzB,gCAAgC;IAChC,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAA;IAC3B,mDAAmD;IACnD,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,8JAA8J;IAC9J,UAAU,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACjC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG;IACzC,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe;IACf,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,wBAAwB;IACxB,IAAI,EAAE,QAAQ,CAAA;IACd,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;IACtB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY;IACZ,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG;IACxC,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,sDAAsD;IACtD,SAAS,CAAC,EAAE,SAAS,CAAA;CACtB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"sidemenuItem.d.ts","sourceRoot":"","sources":["../../../src/sidemenu/sidemenuItem.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAyC,YAAY,EAAE,MAAM,SAAS,CAAA;AAM7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,mBAAmB;AACnB,eAAO,MAAM,YAAY,wCA6EmB,CAAA;AAE5C,eAAe,YAAY,CAAA"}
1
+ {"version":3,"file":"sidemenuItem.d.ts","sourceRoot":"","sources":["../../../src/sidemenu/sidemenuItem.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAyC,YAAY,EAAE,MAAM,SAAS,CAAA;AAM7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAEpD,mBAAmB;AACnB,eAAO,MAAM,YAAY,wCA+EmB,CAAA;AAE5C,eAAe,YAAY,CAAA"}
@@ -29,6 +29,7 @@ export const SidemenuItem = vui((props, ref) => {
29
29
  borderRadius: 0,
30
30
  borderLeft: '3px solid transparent',
31
31
  borderLeftColor: isActive ? (isDark ? 'digiGreen.main' : 'seaBlue.main') : undefined,
32
+ bg: isDark ? 'darkBlue.main' : isActive ? 'skyBlue.95' : 'white',
32
33
  color: hasChildrenExpanded ? 'seaBlue.main' : isDark ? 'digiGreen.main' : 'sandstone.10',
33
34
  h: 'auto',
34
35
  justifyContent: 'space-between',
@@ -38,6 +39,7 @@ export const SidemenuItem = vui((props, ref) => {
38
39
  w: '100%',
39
40
  ...styles.item,
40
41
  minH: size === 'lg' ? '56px' : '40px',
42
+ hoverBg: isDark ? 'seaBlue.main' : 'skyBlue.90',
41
43
  ...rest
42
44
  };
43
45
  return (React.createElement(Box, { flexDirection: "column", ref: ref, w: "100%" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veracity/vui",
3
- "version": "2.11.0",
3
+ "version": "2.12.0-beta.0",
4
4
  "description": "Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.",
5
5
  "module": "./dist/esm/index.js",
6
6
  "main": "./dist/cjs/index.js",
@@ -1,16 +1,19 @@
1
1
  import React from 'react'
2
2
 
3
3
  import { useStyleConfig, vui } from '../core'
4
- import Icon, { IconProps } from '../icon'
4
+ import Icon, { IconProp, IconProps } from '../icon'
5
5
  import { cs } from '../utils'
6
6
  import { useButtonContext } from './context'
7
7
 
8
+ const isConceptualIcon = (name?: IconProp) => name?.startsWith('con')
9
+
8
10
  /** Displays an icon within the Button. */
9
11
  export const ButtonIcon = vui<'svg', IconProps>((props, ref) => {
10
- const { className, ...rest } = props
12
+ const { className, name, ...rest } = props
11
13
  const styles = useStyleConfig('Button', useButtonContext())
14
+ const verifiedName = isConceptualIcon(name) ? undefined : name
12
15
 
13
- return <Icon className={cs('vui-buttonIcon', className)} ref={ref} {...styles.icon} {...rest} />
16
+ return <Icon className={cs('vui-buttonIcon', className)} name={verifiedName} ref={ref} {...styles.icon} {...rest} />
14
17
  })
15
18
 
16
19
  export default ButtonIcon
@@ -0,0 +1 @@
1
+ export const noScrollClass = 'vui-no-scroll'
@@ -2,6 +2,7 @@ import foundations from '../../theme/foundations'
2
2
  import { isObject } from '../../utils'
3
3
  import { createGlobalStyle, css } from '../styled'
4
4
  import { bounce, fadeDown, fadeIn, fadeLeft, fadeOut, fadeRight, fadeUp, pulse, spin } from './animations'
5
+ import { noScrollClass } from './consts'
5
6
  import fontFaces from './fontFaces'
6
7
 
7
8
  type GlobalStyleProps = {
@@ -46,6 +47,11 @@ export default createGlobalStyle<GlobalStyleProps>`
46
47
  z-index: 1;
47
48
  }
48
49
 
50
+ body.${noScrollClass} {
51
+ overflow: hidden !important;
52
+ overscroll-behavior: contain;
53
+ }
54
+
49
55
  //@formatter:off
50
56
  ${p =>
51
57
  p.globalStyle &&
@@ -1,6 +1,8 @@
1
1
  export * from './animations'
2
2
  export * from './context'
3
3
  export * from './useOfflineMode'
4
+ export * from './useBodyScrollLock'
5
+ export * from './consts'
4
6
  export { default as fontFaces } from './fontFaces'
5
7
  export { default as GlobalStyle } from './globalStyle'
6
8
  export { default as ResetCSS } from './resetCSS'
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ import { addBodyClass, removeBodyClass } from '../../utils'
4
+ import { noScrollClass } from './consts'
5
+
6
+ export const useBodyScrollLock = () => {
7
+ const [isScrollLocked, setIsScrollLocked] = useState(false)
8
+
9
+ const toggleIsScrollLocked = () => setIsScrollLocked(!isScrollLocked)
10
+
11
+ useEffect(() => {
12
+ if (isScrollLocked) addBodyClass(noScrollClass)
13
+ else removeBodyClass(noScrollClass)
14
+ }, [isScrollLocked])
15
+
16
+ return { isScrollLocked, setIsScrollLocked, toggleIsScrollLocked }
17
+ }
@@ -1,7 +1,6 @@
1
1
  import React, { FC, useReducer } from 'react'
2
2
  import { ThemeProvider } from 'styled-components'
3
3
 
4
- import ModalStyle from '../../modal/modalStyle'
5
4
  import PopoverStyle from '../../popover/popoverStyle'
6
5
  import { Portal } from '../../portal'
7
6
  import defaultTheme, { VuiTheme } from '../../theme'
@@ -47,7 +46,6 @@ const VuiProvider: FC<VuiProviderProps & ChildrenProp> = ({
47
46
  <>
48
47
  {resetCSS && <ResetCSS />}
49
48
  <GlobalStyle globalStyle={globalStyle} />
50
- <ModalStyle />
51
49
  <PopoverStyle />
52
50
  {children}
53
51
  {notifyOffline && <NotifyOffline />}
@@ -64,9 +64,6 @@ export const DefinitionHorizontalBase = styled.dlBox`
64
64
  export const Definition = vui<'dl', DefinitionProps>((props, ref) => {
65
65
  const { orientation = 'horizontal', ...rest } = props as DefinitionProps
66
66
  const styles = useStyleConfig('Definition', props)
67
-
68
- console.log('orientation', orientation)
69
-
70
67
  return (
71
68
  <>
72
69
  {orientation === 'horizontal' && (
@@ -31,5 +31,3 @@ export const dialogStatusMapping: DialogStatusMapping = {
31
31
  export const containerId = 'vui-dynamic-container'
32
32
 
33
33
  export const modalClass = 'vui-modal'
34
-
35
- export const noScrollClass = 'vui-no-scroll'
@@ -5,10 +5,11 @@ import { ChildrenProp } from '../core'
5
5
  import { FocusLockProps } from './focusLock.types'
6
6
 
7
7
  /**
8
- * Traps the focus within the provided content. That is, tabbing with keyboard will
9
- * only cycle through the children and won't leave the boundary of the FocusLock.
10
- * This behavior enhances accessibility of the Modal component.
8
+ * Traps the focus within the provided content.
9
+ *
10
+ * Tabbing using the keyboard will only cycle through the children and won't leave the boundary of the FocusLock wrapper.
11
11
  */
12
+
12
13
  export const FocusLock: FC<FocusLockProps & ChildrenProp> = props => {
13
14
  const {
14
15
  autoFocus,
@@ -0,0 +1,3 @@
1
+ export * from './focusLock'
2
+ export { default } from './focusLock'
3
+ export * from './focusLock.types'
@@ -4,6 +4,7 @@ import { Box } from '../box'
4
4
  import { styled, useDown, useStyleConfig, vui, VuiComponent } from '../core'
5
5
  import { Divider } from '../divider'
6
6
  import { Link } from '../link'
7
+ import Menu from '../menu'
7
8
  import { T } from '../t'
8
9
  import { cs } from '../utils'
9
10
  import { FooterProvider } from './context'
@@ -97,7 +98,34 @@ export const Footer = vui<'div', FooterProps>((props, ref) => {
97
98
  >
98
99
  {applicationLinks?.map((link, index) => (
99
100
  <Box flex={{ xs: '0 0 50%', sm: '0 0 auto' }} key={index} minW={70}>
100
- <FooterLink {...link} />
101
+ {link.items && (
102
+ <Menu isLazy={false} offset={[-16, 9]} placement="top-start" size="lg" {...rest}>
103
+ <Menu.Button
104
+ as={Link}
105
+ className="vui-footerLink-trigger"
106
+ pt="3px"
107
+ text={link.text}
108
+ title={link.text}
109
+ {...styles.link}
110
+ {...rest}
111
+ />
112
+
113
+ <Menu.List maxH={400} right={0} w={320} {...styles.list}>
114
+ {link.items.map(({ text, url }, index) => (
115
+ <Menu.Item
116
+ isTruncated
117
+ key={index}
118
+ linkProps={{ href: url }}
119
+ text={text}
120
+ title={text}
121
+ {...styles.item}
122
+ />
123
+ ))}
124
+ </Menu.List>
125
+ </Menu>
126
+ )}
127
+
128
+ {!link.items && <FooterLink {...link} />}
101
129
  </Box>
102
130
  ))}
103
131
  </Box>
@@ -18,7 +18,8 @@ export type FooterLinkData = {
18
18
  /** Unique name that identifies a link in the links dictionary. */
19
19
  id?: string
20
20
  text: string
21
- url: string
21
+ url?: string
22
+ items?: FooterLinkData[]
22
23
  }
23
24
 
24
25
  export type FooterProps = Omit<BoxProps, 'size' | 'variant'> &
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ export * from './definition'
14
14
  export * from './dialog'
15
15
  export * from './divider'
16
16
  export * from './dragAndDrop'
17
+ export * from './focusLock'
17
18
  export * from './footer'
18
19
  export * from './grid'
19
20
  export * from './header'
@@ -43,3 +43,10 @@ export const inputStateMapping: InputStateMapping = {
43
43
  }
44
44
  }
45
45
  }
46
+
47
+ export const displayValueOnlyTextSize = {
48
+ sm: 'xs',
49
+ md: 'sm',
50
+ lg: 'md',
51
+ xl: 'lg'
52
+ }
@@ -4,7 +4,7 @@ import { styled, useStyleConfig, vui, VuiComponent } from '../core'
4
4
  import { T } from '../t'
5
5
  import { ChangeEvent, cs, filterUndefined, isString } from '../utils'
6
6
  import AutoCompletePopover from './autoCompletePopover'
7
- import { inputColors, inputStateMapping } from './consts'
7
+ import { displayValueOnlyTextSize, inputColors, inputStateMapping } from './consts'
8
8
  import { InputProvider } from './context'
9
9
  import { getInitialCount } from './helpers'
10
10
  import HelpText from './helpText'
@@ -67,7 +67,8 @@ export const Input = vui<'div', InputProps>((props, ref) => {
67
67
  readOnly,
68
68
  required,
69
69
  showCount,
70
- size,
70
+ displayValueOnly,
71
+ size = 'lg',
71
72
  state = '',
72
73
  stateMapping,
73
74
  step,
@@ -113,59 +114,69 @@ export const Input = vui<'div', InputProps>((props, ref) => {
113
114
 
114
115
  return (
115
116
  <InputProvider value={context}>
116
- <AutoCompletePopover
117
- autoCompleteMaxHeight={autoCompleteMaxHeight}
118
- autoCompleteOptions={autoCompleteOptions}
119
- filterAutoCompleteOptions={filterAutoCompleteOptions}
120
- onAutoCompleteSelect={onAutoCompleteSelect}
121
- >
122
- <InputBase className={cs('vui-input', className)} ref={ref} {...styles.container} {...aliasedProps} {...rest}>
123
- {itemLeft}
124
- {isString(iconLeft) ? <InputIcon ml={1} name={iconLeft} /> : iconLeft}
125
- {children ?? input ?? (
126
- <InputInput
127
- ref={inputRef}
128
- {...{
129
- autoFocus,
130
- defaultValue,
131
- disabled,
132
- id,
133
- max,
134
- maxLength,
135
- min,
136
- name,
137
- onBlur,
138
- onChange,
139
- onFocus,
140
- pattern,
141
- placeholder,
142
- readOnly,
143
- required,
144
- step,
145
- type
146
- }}
147
- autoComplete={autoCompleteOptions?.length ? 'off' : autoComplete}
148
- value={valueInternal}
149
- {...inputProps}
150
- />
151
- )}
152
- {isString(iconRight) ? <InputIcon mr={1} name={iconRight} /> : iconRight}
153
- {itemRight}
154
- {state && <InputIcon mr={1} {...states[state]?.iconProps} />}
155
- {showCount && (
156
- <T
157
- className="vui-inputCount"
158
- color={maxLength && count > maxLength ? inputColors.error : inputColors.helpText}
159
- position="absolute"
160
- right={0}
161
- size="sm"
162
- top="calc(100% + 1px)"
163
- >
164
- {count} {maxLength ? `/ ${maxLength}` : null}
165
- </T>
166
- )}
167
- </InputBase>
168
- </AutoCompletePopover>
117
+ {displayValueOnly ? (
118
+ <T
119
+ className={cs('vui-input-value', className)}
120
+ size={displayValueOnlyTextSize[size] as 'xs' | 'md' | 'sm' | 'lg'}
121
+ >
122
+ {value || defaultValue}
123
+ </T>
124
+ ) : (
125
+ <AutoCompletePopover
126
+ autoCompleteMaxHeight={autoCompleteMaxHeight}
127
+ autoCompleteOptions={autoCompleteOptions}
128
+ filterAutoCompleteOptions={filterAutoCompleteOptions}
129
+ onAutoCompleteSelect={onAutoCompleteSelect}
130
+ >
131
+ <InputBase className={cs('vui-input', className)} ref={ref} {...styles.container} {...aliasedProps} {...rest}>
132
+ {itemLeft}
133
+ {isString(iconLeft) ? <InputIcon ml={1} name={iconLeft} /> : iconLeft}
134
+ {children ?? input ?? (
135
+ <InputInput
136
+ ref={inputRef}
137
+ {...{
138
+ autoFocus,
139
+ defaultValue,
140
+ disabled,
141
+ id,
142
+ max,
143
+ maxLength,
144
+ min,
145
+ name,
146
+ onBlur,
147
+ onChange,
148
+ onFocus,
149
+ pattern,
150
+ placeholder,
151
+ readOnly,
152
+ required,
153
+ step,
154
+ type
155
+ }}
156
+ autoComplete={autoCompleteOptions?.length ? 'off' : autoComplete}
157
+ value={valueInternal}
158
+ {...inputProps}
159
+ />
160
+ )}
161
+ {isString(iconRight) ? <InputIcon mr={1} name={iconRight} /> : iconRight}
162
+ {itemRight}
163
+ {state && <InputIcon mr={1} {...states[state]?.iconProps} />}
164
+ {showCount && (
165
+ <T
166
+ className="vui-inputCount"
167
+ color={maxLength && count > maxLength ? inputColors.error : inputColors.helpText}
168
+ position="absolute"
169
+ right={0}
170
+ size="sm"
171
+ top="calc(100% + 1px)"
172
+ >
173
+ {count} {maxLength ? `/ ${maxLength}` : null}
174
+ </T>
175
+ )}
176
+ </InputBase>
177
+ </AutoCompletePopover>
178
+ )}
179
+
169
180
  {!!helpText && <HelpText>{helpText}</HelpText>}
170
181
  {!!errorText && <HelpText isError>{errorText}</HelpText>}
171
182
  </InputProvider>
@@ -68,6 +68,8 @@ export type InputProps = SystemProps &
68
68
  required?: boolean
69
69
  /** Displays length of input value if also using maxLength. */
70
70
  showCount?: boolean
71
+ /** Displays the provided value. */
72
+ displayValueOnly?: boolean
71
73
  /** Modifies Input style and content based on the given state. */
72
74
  state?: InputState
73
75
  /** Object definition of styles and content for each state. */
@@ -1,6 +1,6 @@
1
1
  export * from './context'
2
- export * from './focusLock'
3
- export * from './focusLock.types'
2
+ export * from '../focusLock/focusLock'
3
+ export * from '../focusLock/focusLock.types'
4
4
  export * from './modal'
5
5
  export { default as Modal } from './modal'
6
6
  export * from './modal.types'
@@ -2,10 +2,10 @@ import React, { cloneElement, useRef } from 'react'
2
2
 
3
3
  import Box from '../box'
4
4
  import { vui, VuiComponent } from '../core'
5
+ import FocusLock from '../focusLock'
5
6
  import Portal from '../portal'
6
7
  import { callAll, cs, KeyboardEvent, mergeRefs, MouseEvent } from '../utils'
7
8
  import { ModalProvider } from './context'
8
- import FocusLock from './focusLock'
9
9
  import { ModalProps } from './modal.types'
10
10
  import ModalBackdrop from './modalBackdrop'
11
11
  import ModalContent from './modalContent'
@@ -95,7 +95,6 @@ export const Modal = vui<'div', ModalProps>((props, ref) => {
95
95
  onMouseDown={callAll(props.onMouseDown, onMouseDown)}
96
96
  >
97
97
  {!hideBackdrop && <ModalBackdrop />}
98
-
99
98
  <FocusLock
100
99
  autoFocus={!disableAutoFocus}
101
100
  finalFocusRef={finalFocusRef}
@@ -1,9 +1,9 @@
1
1
  import { ReactElement } from 'react'
2
2
 
3
+ import { FocusableElement } from '../focusLock/focusLock.types'
3
4
  import { SystemProps } from '../system'
4
5
  import { ThemingProps } from '../theme'
5
6
  import { MouseEvent } from '../utils'
6
- import { FocusableElement } from './focusLock.types'
7
7
 
8
8
  export type ModalBackdropProps = SystemProps
9
9
 
@@ -1,18 +1,14 @@
1
1
  import { Ref, useEffect } from 'react'
2
2
 
3
- import { addBodyClass, removeBodyClass } from '../utils/dom'
3
+ import { useBodyScrollLock } from '../core'
4
4
 
5
5
  /** State management for nested modals. */
6
6
  class ModalManager {
7
7
  modals: any[] = []
8
8
 
9
- add = (modal: any) => {
10
- this.modals.push(modal)
11
- }
9
+ add = (modal: any) => this.modals.push(modal)
12
10
 
13
- remove = (modal: any) => {
14
- this.modals = this.modals.filter(m => m !== modal)
15
- }
11
+ remove = (modal: any) => (this.modals = this.modals.filter(m => m !== modal))
16
12
 
17
13
  isTopModal = (modal: any) => {
18
14
  const topmostModal = this.modals[this.modals.length - 1]
@@ -24,15 +20,16 @@ export const manager = new ModalManager()
24
20
 
25
21
  /** Refs of new modals will be automatically added/removed from the state when rendering. */
26
22
  export function useModalManager(ref: Ref<any>, isOpen?: boolean, disableScrollLock?: boolean) {
23
+ const { setIsScrollLocked } = useBodyScrollLock()
27
24
  useEffect(() => {
28
25
  if (isOpen) {
29
26
  manager.add(ref)
30
- if (!disableScrollLock) addBodyClass('vui-no-scroll')
27
+ if (!disableScrollLock) setIsScrollLocked(true)
31
28
  }
32
29
 
33
30
  return () => {
34
31
  manager.remove(ref)
35
- if (!disableScrollLock) removeBodyClass('vui-no-scroll')
32
+ if (!disableScrollLock) setIsScrollLocked(false)
36
33
  }
37
34
  }, [isOpen, ref])
38
35
  }