@vuu-ui/vuu-utils 2.0.0 → 2.1.0-alpha.2

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 (171) hide show
  1. package/cjs/node_modules/@dnd-kit/react/hooks.js +3 -3
  2. package/cjs/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +492 -0
  3. package/cjs/node_modules/@floating-ui/dom/dist/floating-ui.dom.js.map +1 -0
  4. package/cjs/node_modules/@floating-ui/react/dist/floating-ui.react.js +987 -0
  5. package/cjs/node_modules/@floating-ui/react/dist/floating-ui.react.js.map +1 -0
  6. package/cjs/node_modules/@floating-ui/react/dist/floating-ui.react.utils.js +130 -0
  7. package/cjs/node_modules/@floating-ui/react/dist/floating-ui.react.utils.js.map +1 -0
  8. package/cjs/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +183 -0
  9. package/cjs/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +1 -0
  10. package/cjs/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +39 -0
  11. package/cjs/node_modules/@floating-ui/utils/dist/floating-ui.utils.js.map +1 -0
  12. package/cjs/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerContext.js +10 -0
  13. package/cjs/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerContext.js.map +1 -0
  14. package/cjs/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerProvider.js +76 -0
  15. package/cjs/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerProvider.js.map +1 -0
  16. package/cjs/node_modules/@salt-ds/core/dist-es/aria-announcer/useAriaAnnouncer.js +52 -0
  17. package/cjs/node_modules/@salt-ds/core/dist-es/aria-announcer/useAriaAnnouncer.js.map +1 -0
  18. package/cjs/node_modules/@salt-ds/core/dist-es/breakpoints/BreakpointProvider.js +59 -0
  19. package/cjs/node_modules/@salt-ds/core/dist-es/breakpoints/BreakpointProvider.js.map +1 -0
  20. package/cjs/node_modules/@salt-ds/core/dist-es/breakpoints/Breakpoints.js +12 -0
  21. package/cjs/node_modules/@salt-ds/core/dist-es/breakpoints/Breakpoints.js.map +1 -0
  22. package/cjs/node_modules/@salt-ds/core/dist-es/button/Button.css.js +6 -0
  23. package/cjs/node_modules/@salt-ds/core/dist-es/button/Button.css.js.map +1 -0
  24. package/cjs/node_modules/@salt-ds/core/dist-es/button/Button.js +96 -0
  25. package/cjs/node_modules/@salt-ds/core/dist-es/button/Button.js.map +1 -0
  26. package/cjs/node_modules/@salt-ds/core/dist-es/button/useButton.js +65 -0
  27. package/cjs/node_modules/@salt-ds/core/dist-es/button/useButton.js.map +1 -0
  28. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/ProviderContext.js +11 -0
  29. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/ProviderContext.js.map +1 -0
  30. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.css.js +6 -0
  31. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.css.js.map +1 -0
  32. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.js +160 -0
  33. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.js.map +1 -0
  34. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/ThemeApplicator.js +115 -0
  35. package/cjs/node_modules/@salt-ds/core/dist-es/salt-provider/ThemeApplicator.js.map +1 -0
  36. package/cjs/node_modules/@salt-ds/core/dist-es/spinner/Spinner.css.js +6 -0
  37. package/cjs/node_modules/@salt-ds/core/dist-es/spinner/Spinner.css.js.map +1 -0
  38. package/cjs/node_modules/@salt-ds/core/dist-es/spinner/Spinner.js +86 -0
  39. package/cjs/node_modules/@salt-ds/core/dist-es/spinner/Spinner.js.map +1 -0
  40. package/cjs/node_modules/@salt-ds/core/dist-es/spinner/svgSpinners/SpinnerSVG.js +93 -0
  41. package/cjs/node_modules/@salt-ds/core/dist-es/spinner/svgSpinners/SpinnerSVG.js.map +1 -0
  42. package/cjs/node_modules/@salt-ds/core/dist-es/utils/createChainedFunction.js +20 -0
  43. package/cjs/node_modules/@salt-ds/core/dist-es/utils/createChainedFunction.js.map +1 -0
  44. package/cjs/node_modules/@salt-ds/core/dist-es/utils/createContext.js +14 -0
  45. package/cjs/node_modules/@salt-ds/core/dist-es/utils/createContext.js.map +1 -0
  46. package/cjs/node_modules/@salt-ds/core/dist-es/utils/debounce.js +22 -0
  47. package/cjs/node_modules/@salt-ds/core/dist-es/utils/debounce.js.map +1 -0
  48. package/cjs/node_modules/@salt-ds/core/dist-es/utils/makePrefixer.js +6 -0
  49. package/cjs/node_modules/@salt-ds/core/dist-es/utils/makePrefixer.js.map +1 -0
  50. package/cjs/node_modules/@salt-ds/core/dist-es/utils/useFloatingUI/useFloatingUI.js +52 -0
  51. package/cjs/node_modules/@salt-ds/core/dist-es/utils/useFloatingUI/useFloatingUI.js.map +1 -0
  52. package/cjs/node_modules/@salt-ds/core/dist-es/utils/useId.js +45 -0
  53. package/cjs/node_modules/@salt-ds/core/dist-es/utils/useId.js.map +1 -0
  54. package/cjs/node_modules/@salt-ds/core/dist-es/utils/useIsomorphicLayoutEffect.js +8 -0
  55. package/cjs/node_modules/@salt-ds/core/dist-es/utils/useIsomorphicLayoutEffect.js.map +1 -0
  56. package/cjs/node_modules/@salt-ds/core/dist-es/utils/usePreventScroll.js +233 -0
  57. package/cjs/node_modules/@salt-ds/core/dist-es/utils/usePreventScroll.js.map +1 -0
  58. package/cjs/node_modules/@salt-ds/core/dist-es/viewport/ViewportProvider.js +35 -0
  59. package/cjs/node_modules/@salt-ds/core/dist-es/viewport/ViewportProvider.js.map +1 -0
  60. package/cjs/node_modules/@salt-ds/styles/dist-es/style-injection-provider/index.js +22 -0
  61. package/cjs/node_modules/@salt-ds/styles/dist-es/style-injection-provider/index.js.map +1 -0
  62. package/cjs/node_modules/@salt-ds/styles/dist-es/use-style-injection/InsertionPointProvider.js +16 -0
  63. package/cjs/node_modules/@salt-ds/styles/dist-es/use-style-injection/InsertionPointProvider.js.map +1 -0
  64. package/cjs/node_modules/@salt-ds/styles/dist-es/use-style-injection/useStyleInjection.js +75 -0
  65. package/cjs/node_modules/@salt-ds/styles/dist-es/use-style-injection/useStyleInjection.js.map +1 -0
  66. package/cjs/node_modules/@salt-ds/window/dist-es/WindowProvider.js +17 -0
  67. package/cjs/node_modules/@salt-ds/window/dist-es/WindowProvider.js.map +1 -0
  68. package/cjs/node_modules/tabbable/dist/index.esm.js +550 -0
  69. package/cjs/node_modules/tabbable/dist/index.esm.js.map +1 -0
  70. package/cjs/packages/vuu-utils/src/ThemeProvider.js +2 -2
  71. package/cjs/packages/vuu-utils/src/ThemeProvider.js.map +1 -1
  72. package/cjs/packages/vuu-utils/src/data-editing/DataEditingProvider.js +25 -0
  73. package/cjs/packages/vuu-utils/src/data-editing/DataEditingProvider.js.map +1 -0
  74. package/cjs/packages/vuu-utils/src/data-editing/EditButtons.js +23 -0
  75. package/cjs/packages/vuu-utils/src/data-editing/EditButtons.js.map +1 -0
  76. package/cjs/packages/vuu-utils/src/data-editing/EditTracker.js +154 -0
  77. package/cjs/packages/vuu-utils/src/data-editing/EditTracker.js.map +1 -0
  78. package/cjs/packages/vuu-utils/src/data-editing/useEditableTable.js +69 -0
  79. package/cjs/packages/vuu-utils/src/data-editing/useEditableTable.js.map +1 -0
  80. package/cjs/packages/vuu-utils/src/index.js +9 -0
  81. package/cjs/packages/vuu-utils/src/index.js.map +1 -1
  82. package/esm/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +489 -0
  83. package/esm/node_modules/@floating-ui/dom/dist/floating-ui.dom.js.map +1 -0
  84. package/esm/node_modules/@floating-ui/react/dist/floating-ui.react.js +962 -0
  85. package/esm/node_modules/@floating-ui/react/dist/floating-ui.react.js.map +1 -0
  86. package/esm/node_modules/@floating-ui/react/dist/floating-ui.react.utils.js +114 -0
  87. package/esm/node_modules/@floating-ui/react/dist/floating-ui.react.utils.js.map +1 -0
  88. package/esm/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +162 -0
  89. package/esm/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +1 -0
  90. package/esm/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +33 -0
  91. package/esm/node_modules/@floating-ui/utils/dist/floating-ui.utils.js.map +1 -0
  92. package/esm/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerContext.js +8 -0
  93. package/esm/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerContext.js.map +1 -0
  94. package/esm/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerProvider.js +73 -0
  95. package/esm/node_modules/@salt-ds/core/dist-es/aria-announcer/AriaAnnouncerProvider.js.map +1 -0
  96. package/esm/node_modules/@salt-ds/core/dist-es/aria-announcer/useAriaAnnouncer.js +50 -0
  97. package/esm/node_modules/@salt-ds/core/dist-es/aria-announcer/useAriaAnnouncer.js.map +1 -0
  98. package/esm/node_modules/@salt-ds/core/dist-es/breakpoints/BreakpointProvider.js +56 -0
  99. package/esm/node_modules/@salt-ds/core/dist-es/breakpoints/BreakpointProvider.js.map +1 -0
  100. package/esm/node_modules/@salt-ds/core/dist-es/breakpoints/Breakpoints.js +10 -0
  101. package/esm/node_modules/@salt-ds/core/dist-es/breakpoints/Breakpoints.js.map +1 -0
  102. package/esm/node_modules/@salt-ds/core/dist-es/button/Button.css.js +4 -0
  103. package/esm/node_modules/@salt-ds/core/dist-es/button/Button.css.js.map +1 -0
  104. package/esm/node_modules/@salt-ds/core/dist-es/button/Button.js +94 -0
  105. package/esm/node_modules/@salt-ds/core/dist-es/button/Button.js.map +1 -0
  106. package/esm/node_modules/@salt-ds/core/dist-es/button/useButton.js +63 -0
  107. package/esm/node_modules/@salt-ds/core/dist-es/button/useButton.js.map +1 -0
  108. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/ProviderContext.js +9 -0
  109. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/ProviderContext.js.map +1 -0
  110. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.css.js +4 -0
  111. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.css.js.map +1 -0
  112. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.js +151 -0
  113. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/SaltProvider.js.map +1 -0
  114. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/ThemeApplicator.js +113 -0
  115. package/esm/node_modules/@salt-ds/core/dist-es/salt-provider/ThemeApplicator.js.map +1 -0
  116. package/esm/node_modules/@salt-ds/core/dist-es/spinner/Spinner.css.js +4 -0
  117. package/esm/node_modules/@salt-ds/core/dist-es/spinner/Spinner.css.js.map +1 -0
  118. package/esm/node_modules/@salt-ds/core/dist-es/spinner/Spinner.js +84 -0
  119. package/esm/node_modules/@salt-ds/core/dist-es/spinner/Spinner.js.map +1 -0
  120. package/esm/node_modules/@salt-ds/core/dist-es/spinner/svgSpinners/SpinnerSVG.js +91 -0
  121. package/esm/node_modules/@salt-ds/core/dist-es/spinner/svgSpinners/SpinnerSVG.js.map +1 -0
  122. package/esm/node_modules/@salt-ds/core/dist-es/utils/createChainedFunction.js +18 -0
  123. package/esm/node_modules/@salt-ds/core/dist-es/utils/createChainedFunction.js.map +1 -0
  124. package/esm/node_modules/@salt-ds/core/dist-es/utils/createContext.js +12 -0
  125. package/esm/node_modules/@salt-ds/core/dist-es/utils/createContext.js.map +1 -0
  126. package/esm/node_modules/@salt-ds/core/dist-es/utils/debounce.js +20 -0
  127. package/esm/node_modules/@salt-ds/core/dist-es/utils/debounce.js.map +1 -0
  128. package/esm/node_modules/@salt-ds/core/dist-es/utils/makePrefixer.js +4 -0
  129. package/esm/node_modules/@salt-ds/core/dist-es/utils/makePrefixer.js.map +1 -0
  130. package/esm/node_modules/@salt-ds/core/dist-es/utils/useFloatingUI/useFloatingUI.js +50 -0
  131. package/esm/node_modules/@salt-ds/core/dist-es/utils/useFloatingUI/useFloatingUI.js.map +1 -0
  132. package/esm/node_modules/@salt-ds/core/dist-es/utils/useId.js +24 -0
  133. package/esm/node_modules/@salt-ds/core/dist-es/utils/useId.js.map +1 -0
  134. package/esm/node_modules/@salt-ds/core/dist-es/utils/useIsomorphicLayoutEffect.js +6 -0
  135. package/esm/node_modules/@salt-ds/core/dist-es/utils/useIsomorphicLayoutEffect.js.map +1 -0
  136. package/esm/node_modules/@salt-ds/core/dist-es/utils/usePreventScroll.js +231 -0
  137. package/esm/node_modules/@salt-ds/core/dist-es/utils/usePreventScroll.js.map +1 -0
  138. package/esm/node_modules/@salt-ds/core/dist-es/viewport/ViewportProvider.js +32 -0
  139. package/esm/node_modules/@salt-ds/core/dist-es/viewport/ViewportProvider.js.map +1 -0
  140. package/esm/node_modules/@salt-ds/styles/dist-es/style-injection-provider/index.js +19 -0
  141. package/esm/node_modules/@salt-ds/styles/dist-es/style-injection-provider/index.js.map +1 -0
  142. package/esm/node_modules/@salt-ds/styles/dist-es/use-style-injection/InsertionPointProvider.js +14 -0
  143. package/esm/node_modules/@salt-ds/styles/dist-es/use-style-injection/InsertionPointProvider.js.map +1 -0
  144. package/esm/node_modules/@salt-ds/styles/dist-es/use-style-injection/useStyleInjection.js +54 -0
  145. package/esm/node_modules/@salt-ds/styles/dist-es/use-style-injection/useStyleInjection.js.map +1 -0
  146. package/esm/node_modules/@salt-ds/window/dist-es/WindowProvider.js +15 -0
  147. package/esm/node_modules/@salt-ds/window/dist-es/WindowProvider.js.map +1 -0
  148. package/esm/node_modules/tabbable/dist/index.esm.js +546 -0
  149. package/esm/node_modules/tabbable/dist/index.esm.js.map +1 -0
  150. package/esm/packages/vuu-utils/src/ThemeProvider.js +2 -2
  151. package/esm/packages/vuu-utils/src/ThemeProvider.js.map +1 -1
  152. package/esm/packages/vuu-utils/src/context-definitions/WorkspaceContext.js +2 -2
  153. package/esm/packages/vuu-utils/src/context-definitions/WorkspaceContext.js.map +1 -1
  154. package/esm/packages/vuu-utils/src/data-editing/DataEditingProvider.js +22 -0
  155. package/esm/packages/vuu-utils/src/data-editing/DataEditingProvider.js.map +1 -0
  156. package/esm/packages/vuu-utils/src/data-editing/EditButtons.js +21 -0
  157. package/esm/packages/vuu-utils/src/data-editing/EditButtons.js.map +1 -0
  158. package/esm/packages/vuu-utils/src/data-editing/EditTracker.js +152 -0
  159. package/esm/packages/vuu-utils/src/data-editing/EditTracker.js.map +1 -0
  160. package/esm/packages/vuu-utils/src/data-editing/useEditableTable.js +67 -0
  161. package/esm/packages/vuu-utils/src/data-editing/useEditableTable.js.map +1 -0
  162. package/esm/packages/vuu-utils/src/feature-utils.js +2 -2
  163. package/esm/packages/vuu-utils/src/feature-utils.js.map +1 -1
  164. package/esm/packages/vuu-utils/src/index.js +4 -0
  165. package/esm/packages/vuu-utils/src/index.js.map +1 -1
  166. package/package.json +6 -6
  167. package/types/data-editing/DataEditingProvider.d.ts +7 -0
  168. package/types/data-editing/EditButtons.d.ts +7 -0
  169. package/types/data-editing/EditTracker.d.ts +24 -0
  170. package/types/data-editing/useEditableTable.d.ts +15 -0
  171. package/types/index.d.ts +5 -1
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { createContext, useContext, isValidElement, cloneElement } from 'react';
3
- import cx from 'clsx';
3
+ import clsx from 'clsx';
4
4
 
5
5
  const DEFAULT_DENSITY = "medium";
6
6
  const DEFAULT_THEME = "salt-theme";
@@ -35,7 +35,7 @@ const useThemeAttributes = (themeAttributes) => {
35
35
  const createThemedChildren = (children, theme, themeMode, density) => {
36
36
  if (isValidElement(children)) {
37
37
  return cloneElement(children, {
38
- className: cx(
38
+ className: clsx(
39
39
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
40
40
  children.props?.className,
41
41
  `${theme}-theme`,
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeProvider.js","sources":["../../../../../../packages/vuu-utils/src/ThemeProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n HTMLAttributes,\n ReactNode,\n isValidElement,\n cloneElement,\n useContext,\n} from \"react\";\nimport cx from \"clsx\";\n\nexport const DEFAULT_DENSITY: Density = \"medium\";\nexport const DEFAULT_THEME = \"salt-theme\";\nexport const DEFAULT_THEME_MODE: ThemeMode = \"light\";\n\nexport type Density = \"high\" | \"medium\" | \"low\" | \"touch\";\nexport type ThemeMode = \"light\" | \"dark\";\nexport type TargetElement = \"root\" | \"scope\" | \"child\";\n\nexport interface ThemeContextProps {\n density: Density;\n theme: string;\n themeMode: ThemeMode;\n}\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n density: \"high\",\n theme: \"vuu\",\n themeMode: \"light\",\n});\n\nexport type ThemeClasses = [string, string, ThemeMode];\n\nconst DEFAULT_THEME_ATTRIBUTES: ThemeClasses = [\n \"vuu\",\n \"salt-density-high\",\n \"light\" as ThemeMode,\n];\n\nexport type ThemeAttributes = {\n themeClass: string;\n densityClass: string;\n dataMode: ThemeMode;\n};\n\nexport const useThemeAttributes = (\n themeAttributes?: ThemeAttributes\n): [string, string, ThemeMode] => {\n const context = useContext(ThemeContext);\n if (themeAttributes) {\n return [\n themeAttributes.themeClass,\n themeAttributes.densityClass,\n themeAttributes.dataMode,\n ];\n } else if (context) {\n return [\n `${context.theme}-theme`,\n `salt-density-${context.density}`,\n context.themeMode,\n ];\n }\n return DEFAULT_THEME_ATTRIBUTES;\n};\n\nconst createThemedChildren = (\n children: ReactNode,\n theme: string,\n themeMode: ThemeMode,\n density: Density\n) => {\n if (isValidElement<HTMLAttributes<HTMLElement>>(children)) {\n return cloneElement(children, {\n className: cx(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n children.props?.className,\n `${theme}-theme`,\n `salt-density-${density}`\n ),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n \"data-mode\": themeMode,\n });\n } else {\n console.warn(\n `\\nThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.\n Wrap elements with a single container`\n );\n return children;\n }\n};\n\ninterface ThemeProviderProps {\n applyThemeClasses?: boolean;\n children: ReactNode;\n density?: Density;\n theme?: string;\n themeMode?: ThemeMode;\n}\n\nexport const ThemeProvider = ({\n applyThemeClasses = false,\n children,\n theme: themeProp,\n themeMode: themeModeProp,\n density: densityProp,\n}: ThemeProviderProps) => {\n const {\n density: inheritedDensity,\n themeMode: inheritedThemeMode,\n theme: inheritedTheme,\n } = useContext(ThemeContext);\n const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;\n const themeMode = themeModeProp ?? inheritedThemeMode ?? DEFAULT_THEME_MODE;\n const theme = themeProp ?? inheritedTheme ?? DEFAULT_THEME;\n const themedChildren = applyThemeClasses\n ? createThemedChildren(children, theme, themeMode, density)\n : children;\n\n return (\n <ThemeContext.Provider value={{ themeMode, density, theme }}>\n {themedChildren}\n </ThemeContext.Provider>\n );\n};\n\nThemeProvider.displayName = \"ThemeProvider\";\n"],"names":[],"mappings":";;;;AAUO,MAAM,eAA2B,GAAA;AACjC,MAAM,aAAgB,GAAA;AACtB,MAAM,kBAAgC,GAAA;AAYtC,MAAM,eAAe,aAAiC,CAAA;AAAA,EAC3D,OAAS,EAAA,MAAA;AAAA,EACT,KAAO,EAAA,KAAA;AAAA,EACP,SAAW,EAAA;AACb,CAAC;AAID,MAAM,wBAAyC,GAAA;AAAA,EAC7C,KAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAA;AAQa,MAAA,kBAAA,GAAqB,CAChC,eACgC,KAAA;AAChC,EAAM,MAAA,OAAA,GAAU,WAAW,YAAY,CAAA;AACvC,EAAA,IAAI,eAAiB,EAAA;AACnB,IAAO,OAAA;AAAA,MACL,eAAgB,CAAA,UAAA;AAAA,MAChB,eAAgB,CAAA,YAAA;AAAA,MAChB,eAAgB,CAAA;AAAA,KAClB;AAAA,aACS,OAAS,EAAA;AAClB,IAAO,OAAA;AAAA,MACL,CAAA,EAAG,QAAQ,KAAK,CAAA,MAAA,CAAA;AAAA,MAChB,CAAA,aAAA,EAAgB,QAAQ,OAAO,CAAA,CAAA;AAAA,MAC/B,OAAQ,CAAA;AAAA,KACV;AAAA;AAEF,EAAO,OAAA,wBAAA;AACT;AAEA,MAAM,oBAAuB,GAAA,CAC3B,QACA,EAAA,KAAA,EACA,WACA,OACG,KAAA;AACH,EAAI,IAAA,cAAA,CAA4C,QAAQ,CAAG,EAAA;AACzD,IAAA,OAAO,aAAa,QAAU,EAAA;AAAA,MAC5B,SAAW,EAAA,EAAA;AAAA;AAAA,QAET,SAAS,KAAO,EAAA,SAAA;AAAA,QAChB,GAAG,KAAK,CAAA,MAAA,CAAA;AAAA,QACR,gBAAgB,OAAO,CAAA;AAAA,OACzB;AAAA;AAAA;AAAA,MAGA,WAAa,EAAA;AAAA,KACd,CAAA;AAAA,GACI,MAAA;AACL,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN;AAAA;AAAA,iDAAA;AAAA,KAEF;AACA,IAAO,OAAA,QAAA;AAAA;AAEX,CAAA;AAUO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,iBAAoB,GAAA,KAAA;AAAA,EACpB,QAAA;AAAA,EACA,KAAO,EAAA,SAAA;AAAA,EACP,SAAW,EAAA,aAAA;AAAA,EACX,OAAS,EAAA;AACX,CAA0B,KAAA;AACxB,EAAM,MAAA;AAAA,IACJ,OAAS,EAAA,gBAAA;AAAA,IACT,SAAW,EAAA,kBAAA;AAAA,IACX,KAAO,EAAA;AAAA,GACT,GAAI,WAAW,YAAY,CAAA;AAC3B,EAAM,MAAA,OAAA,GAAU,eAAe,gBAAoB,IAAA,eAAA;AACnD,EAAM,MAAA,SAAA,GAAY,iBAAiB,kBAAsB,IAAA,kBAAA;AACzD,EAAM,MAAA,KAAA,GAAQ,aAAa,cAAkB,IAAA,aAAA;AAC7C,EAAA,MAAM,iBAAiB,iBACnB,GAAA,oBAAA,CAAqB,UAAU,KAAO,EAAA,SAAA,EAAW,OAAO,CACxD,GAAA,QAAA;AAEJ,EACE,uBAAA,GAAA,CAAC,YAAa,CAAA,QAAA,EAAb,EAAsB,KAAA,EAAO,EAAE,SAAW,EAAA,OAAA,EAAS,KAAM,EAAA,EACvD,QACH,EAAA,cAAA,EAAA,CAAA;AAEJ;AAEA,aAAA,CAAc,WAAc,GAAA,eAAA;;;;"}
1
+ {"version":3,"file":"ThemeProvider.js","sources":["../../../../../../packages/vuu-utils/src/ThemeProvider.tsx"],"sourcesContent":["import React, {\n createContext,\n HTMLAttributes,\n ReactNode,\n isValidElement,\n cloneElement,\n useContext,\n} from \"react\";\nimport cx from \"clsx\";\n\nexport const DEFAULT_DENSITY: Density = \"medium\";\nexport const DEFAULT_THEME = \"salt-theme\";\nexport const DEFAULT_THEME_MODE: ThemeMode = \"light\";\n\nexport type Density = \"high\" | \"medium\" | \"low\" | \"touch\";\nexport type ThemeMode = \"light\" | \"dark\";\nexport type TargetElement = \"root\" | \"scope\" | \"child\";\n\nexport interface ThemeContextProps {\n density: Density;\n theme: string;\n themeMode: ThemeMode;\n}\n\nexport const ThemeContext = createContext<ThemeContextProps>({\n density: \"high\",\n theme: \"vuu\",\n themeMode: \"light\",\n});\n\nexport type ThemeClasses = [string, string, ThemeMode];\n\nconst DEFAULT_THEME_ATTRIBUTES: ThemeClasses = [\n \"vuu\",\n \"salt-density-high\",\n \"light\" as ThemeMode,\n];\n\nexport type ThemeAttributes = {\n themeClass: string;\n densityClass: string;\n dataMode: ThemeMode;\n};\n\nexport const useThemeAttributes = (\n themeAttributes?: ThemeAttributes\n): [string, string, ThemeMode] => {\n const context = useContext(ThemeContext);\n if (themeAttributes) {\n return [\n themeAttributes.themeClass,\n themeAttributes.densityClass,\n themeAttributes.dataMode,\n ];\n } else if (context) {\n return [\n `${context.theme}-theme`,\n `salt-density-${context.density}`,\n context.themeMode,\n ];\n }\n return DEFAULT_THEME_ATTRIBUTES;\n};\n\nconst createThemedChildren = (\n children: ReactNode,\n theme: string,\n themeMode: ThemeMode,\n density: Density\n) => {\n if (isValidElement<HTMLAttributes<HTMLElement>>(children)) {\n return cloneElement(children, {\n className: cx(\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n children.props?.className,\n `${theme}-theme`,\n `salt-density-${density}`\n ),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-expect-error\n \"data-mode\": themeMode,\n });\n } else {\n console.warn(\n `\\nThemeProvider can only apply CSS classes for theming to a single nested child element of the ThemeProvider.\n Wrap elements with a single container`\n );\n return children;\n }\n};\n\ninterface ThemeProviderProps {\n applyThemeClasses?: boolean;\n children: ReactNode;\n density?: Density;\n theme?: string;\n themeMode?: ThemeMode;\n}\n\nexport const ThemeProvider = ({\n applyThemeClasses = false,\n children,\n theme: themeProp,\n themeMode: themeModeProp,\n density: densityProp,\n}: ThemeProviderProps) => {\n const {\n density: inheritedDensity,\n themeMode: inheritedThemeMode,\n theme: inheritedTheme,\n } = useContext(ThemeContext);\n const density = densityProp ?? inheritedDensity ?? DEFAULT_DENSITY;\n const themeMode = themeModeProp ?? inheritedThemeMode ?? DEFAULT_THEME_MODE;\n const theme = themeProp ?? inheritedTheme ?? DEFAULT_THEME;\n const themedChildren = applyThemeClasses\n ? createThemedChildren(children, theme, themeMode, density)\n : children;\n\n return (\n <ThemeContext.Provider value={{ themeMode, density, theme }}>\n {themedChildren}\n </ThemeContext.Provider>\n );\n};\n\nThemeProvider.displayName = \"ThemeProvider\";\n"],"names":["cx"],"mappings":";;;;AAUO,MAAM,eAA2B,GAAA;AACjC,MAAM,aAAgB,GAAA;AACtB,MAAM,kBAAgC,GAAA;AAYtC,MAAM,eAAe,aAAiC,CAAA;AAAA,EAC3D,OAAS,EAAA,MAAA;AAAA,EACT,KAAO,EAAA,KAAA;AAAA,EACP,SAAW,EAAA;AACb,CAAC;AAID,MAAM,wBAAyC,GAAA;AAAA,EAC7C,KAAA;AAAA,EACA,mBAAA;AAAA,EACA;AACF,CAAA;AAQa,MAAA,kBAAA,GAAqB,CAChC,eACgC,KAAA;AAChC,EAAM,MAAA,OAAA,GAAU,WAAW,YAAY,CAAA;AACvC,EAAA,IAAI,eAAiB,EAAA;AACnB,IAAO,OAAA;AAAA,MACL,eAAgB,CAAA,UAAA;AAAA,MAChB,eAAgB,CAAA,YAAA;AAAA,MAChB,eAAgB,CAAA;AAAA,KAClB;AAAA,aACS,OAAS,EAAA;AAClB,IAAO,OAAA;AAAA,MACL,CAAA,EAAG,QAAQ,KAAK,CAAA,MAAA,CAAA;AAAA,MAChB,CAAA,aAAA,EAAgB,QAAQ,OAAO,CAAA,CAAA;AAAA,MAC/B,OAAQ,CAAA;AAAA,KACV;AAAA;AAEF,EAAO,OAAA,wBAAA;AACT;AAEA,MAAM,oBAAuB,GAAA,CAC3B,QACA,EAAA,KAAA,EACA,WACA,OACG,KAAA;AACH,EAAI,IAAA,cAAA,CAA4C,QAAQ,CAAG,EAAA;AACzD,IAAA,OAAO,aAAa,QAAU,EAAA;AAAA,MAC5B,SAAW,EAAAA,IAAA;AAAA;AAAA,QAET,SAAS,KAAO,EAAA,SAAA;AAAA,QAChB,GAAG,KAAK,CAAA,MAAA,CAAA;AAAA,QACR,gBAAgB,OAAO,CAAA;AAAA,OACzB;AAAA;AAAA;AAAA,MAGA,WAAa,EAAA;AAAA,KACd,CAAA;AAAA,GACI,MAAA;AACL,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN;AAAA;AAAA,iDAAA;AAAA,KAEF;AACA,IAAO,OAAA,QAAA;AAAA;AAEX,CAAA;AAUO,MAAM,gBAAgB,CAAC;AAAA,EAC5B,iBAAoB,GAAA,KAAA;AAAA,EACpB,QAAA;AAAA,EACA,KAAO,EAAA,SAAA;AAAA,EACP,SAAW,EAAA,aAAA;AAAA,EACX,OAAS,EAAA;AACX,CAA0B,KAAA;AACxB,EAAM,MAAA;AAAA,IACJ,OAAS,EAAA,gBAAA;AAAA,IACT,SAAW,EAAA,kBAAA;AAAA,IACX,KAAO,EAAA;AAAA,GACT,GAAI,WAAW,YAAY,CAAA;AAC3B,EAAM,MAAA,OAAA,GAAU,eAAe,gBAAoB,IAAA,eAAA;AACnD,EAAM,MAAA,SAAA,GAAY,iBAAiB,kBAAsB,IAAA,kBAAA;AACzD,EAAM,MAAA,KAAA,GAAQ,aAAa,cAAkB,IAAA,aAAA;AAC7C,EAAA,MAAM,iBAAiB,iBACnB,GAAA,oBAAA,CAAqB,UAAU,KAAO,EAAA,SAAA,EAAW,OAAO,CACxD,GAAA,QAAA;AAEJ,EACE,uBAAA,GAAA,CAAC,YAAa,CAAA,QAAA,EAAb,EAAsB,KAAA,EAAO,EAAE,SAAW,EAAA,OAAA,EAAS,KAAM,EAAA,EACvD,QACH,EAAA,cAAA,EAAA,CAAA;AAEJ;AAEA,aAAA,CAAc,WAAc,GAAA,eAAA;;;;"}
@@ -1,6 +1,6 @@
1
- import React, { useContext } from 'react';
1
+ import React__default, { useContext } from 'react';
2
2
 
3
- const WorkspaceContext = React.createContext({
3
+ const WorkspaceContext = React__default.createContext({
4
4
  getApplicationSettings: () => void 0,
5
5
  layoutMetadata: [],
6
6
  saveLayout: () => void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceContext.js","sources":["../../../../../../../packages/vuu-utils/src/context-definitions/WorkspaceContext.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport {\n ApplicationSetting,\n ApplicationSettings,\n LayoutJSON\n} from \"../json-types\";\nimport { LayoutMetadata, LayoutMetadataDto } from \"../layout-types\";\n\nexport interface WorkspaceContextProps {\n layoutMetadata: LayoutMetadata[];\n layoutPlaceholderJSON?: LayoutJSON;\n getApplicationSettings: (\n key?: keyof ApplicationSettings\n ) => ApplicationSettings | ApplicationSetting | undefined;\n loadLayoutById: (id: string) => void;\n saveApplicationSettings: (\n settings: ApplicationSettings | ApplicationSetting,\n key?: keyof ApplicationSettings\n ) => void;\n saveLayout: (n: LayoutMetadataDto) => void;\n saveApplicationLayout: (layout: LayoutJSON) => void;\n workspaceJSON?: LayoutJSON | LayoutJSON[];\n}\n\nexport const WorkspaceContext = React.createContext<WorkspaceContextProps>({\n getApplicationSettings: () => undefined,\n layoutMetadata: [],\n saveLayout: () => undefined,\n saveApplicationLayout: () => undefined,\n saveApplicationSettings: () => undefined,\n loadLayoutById: () => undefined\n});\n\nexport const usePlaceholderJSON = () => {\n const { layoutPlaceholderJSON } = useContext(WorkspaceContext);\n return layoutPlaceholderJSON;\n};\n"],"names":[],"mappings":";;AAwBa,MAAA,gBAAA,GAAmB,MAAM,aAAqC,CAAA;AAAA,EACzE,wBAAwB,MAAM,KAAA,CAAA;AAAA,EAC9B,gBAAgB,EAAC;AAAA,EACjB,YAAY,MAAM,KAAA,CAAA;AAAA,EAClB,uBAAuB,MAAM,KAAA,CAAA;AAAA,EAC7B,yBAAyB,MAAM,KAAA,CAAA;AAAA,EAC/B,gBAAgB,MAAM,KAAA;AACxB,CAAC;AAEM,MAAM,qBAAqB,MAAM;AACtC,EAAA,MAAM,EAAE,qBAAA,EAA0B,GAAA,UAAA,CAAW,gBAAgB,CAAA;AAC7D,EAAO,OAAA,qBAAA;AACT;;;;"}
1
+ {"version":3,"file":"WorkspaceContext.js","sources":["../../../../../../../packages/vuu-utils/src/context-definitions/WorkspaceContext.tsx"],"sourcesContent":["import React, { useContext } from \"react\";\nimport {\n ApplicationSetting,\n ApplicationSettings,\n LayoutJSON\n} from \"../json-types\";\nimport { LayoutMetadata, LayoutMetadataDto } from \"../layout-types\";\n\nexport interface WorkspaceContextProps {\n layoutMetadata: LayoutMetadata[];\n layoutPlaceholderJSON?: LayoutJSON;\n getApplicationSettings: (\n key?: keyof ApplicationSettings\n ) => ApplicationSettings | ApplicationSetting | undefined;\n loadLayoutById: (id: string) => void;\n saveApplicationSettings: (\n settings: ApplicationSettings | ApplicationSetting,\n key?: keyof ApplicationSettings\n ) => void;\n saveLayout: (n: LayoutMetadataDto) => void;\n saveApplicationLayout: (layout: LayoutJSON) => void;\n workspaceJSON?: LayoutJSON | LayoutJSON[];\n}\n\nexport const WorkspaceContext = React.createContext<WorkspaceContextProps>({\n getApplicationSettings: () => undefined,\n layoutMetadata: [],\n saveLayout: () => undefined,\n saveApplicationLayout: () => undefined,\n saveApplicationSettings: () => undefined,\n loadLayoutById: () => undefined\n});\n\nexport const usePlaceholderJSON = () => {\n const { layoutPlaceholderJSON } = useContext(WorkspaceContext);\n return layoutPlaceholderJSON;\n};\n"],"names":["React"],"mappings":";;AAwBa,MAAA,gBAAA,GAAmBA,eAAM,aAAqC,CAAA;AAAA,EACzE,wBAAwB,MAAM,KAAA,CAAA;AAAA,EAC9B,gBAAgB,EAAC;AAAA,EACjB,YAAY,MAAM,KAAA,CAAA;AAAA,EAClB,uBAAuB,MAAM,KAAA,CAAA;AAAA,EAC7B,yBAAyB,MAAM,KAAA,CAAA;AAAA,EAC/B,gBAAgB,MAAM,KAAA;AACxB,CAAC;AAEM,MAAM,qBAAqB,MAAM;AACtC,EAAA,MAAM,EAAE,qBAAA,EAA0B,GAAA,UAAA,CAAW,gBAAgB,CAAA;AAC7D,EAAO,OAAA,qBAAA;AACT;;;;"}
@@ -0,0 +1,22 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { createContext, useContext } from 'react';
3
+
4
+ const DataEditingContext = createContext(void 0);
5
+ const DataEditingProvider = ({
6
+ children,
7
+ editTracker
8
+ }) => {
9
+ return /* @__PURE__ */ jsx(DataEditingContext.Provider, { value: editTracker, children });
10
+ };
11
+ const useEditTracker = () => {
12
+ const editTracker = useContext(DataEditingContext);
13
+ if (editTracker === void 0) {
14
+ console.warn(
15
+ "[useEditTracker] no DataEditingContext in scope. You need to enclose editable component(s) with DataEditingProvider"
16
+ );
17
+ }
18
+ return editTracker;
19
+ };
20
+
21
+ export { DataEditingProvider, useEditTracker };
22
+ //# sourceMappingURL=DataEditingProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DataEditingProvider.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/DataEditingProvider.tsx"],"sourcesContent":["import { createContext, ReactNode, useContext } from \"react\";\nimport { EditTracker } from \"./EditTracker\";\n\nconst DataEditingContext = createContext<EditTracker | undefined>(undefined);\n\nexport const DataEditingProvider = ({\n children,\n editTracker,\n}: {\n children: ReactNode;\n editTracker: EditTracker;\n}) => {\n return (\n <DataEditingContext.Provider value={editTracker}>\n {children}\n </DataEditingContext.Provider>\n );\n};\n\nexport const useEditTracker = () => {\n const editTracker = useContext(DataEditingContext);\n if (editTracker === undefined) {\n console.warn(\n \"[useEditTracker] no DataEditingContext in scope. You need to enclose editable component(s) with DataEditingProvider\",\n );\n }\n return editTracker;\n};\n"],"names":[],"mappings":";;;AAGA,MAAM,kBAAA,GAAqB,cAAuC,KAAS,CAAA,CAAA;AAEpE,MAAM,sBAAsB,CAAC;AAAA,EAClC,QAAA;AAAA,EACA;AACF,CAGM,KAAA;AACJ,EAAA,2BACG,kBAAmB,CAAA,QAAA,EAAnB,EAA4B,KAAA,EAAO,aACjC,QACH,EAAA,CAAA;AAEJ;AAEO,MAAM,iBAAiB,MAAM;AAClC,EAAM,MAAA,WAAA,GAAc,WAAW,kBAAkB,CAAA;AACjD,EAAA,IAAI,gBAAgB,KAAW,CAAA,EAAA;AAC7B,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN;AAAA,KACF;AAAA;AAEF,EAAO,OAAA,WAAA;AACT;;;;"}
@@ -0,0 +1,21 @@
1
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
+ import { useState, useMemo } from 'react';
3
+ import { Button } from '../../../../node_modules/@salt-ds/core/dist-es/button/Button.js';
4
+
5
+ const EditButtons = ({
6
+ editTracker,
7
+ onCancel,
8
+ onSave
9
+ }) => {
10
+ const [editState, setEditState] = useState("clean");
11
+ useMemo(() => {
12
+ editTracker?.on("editState", setEditState);
13
+ }, [editTracker]);
14
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
15
+ /* @__PURE__ */ jsx(Button, { disabled: editState === "clean", onClick: onSave, children: "Save" }),
16
+ /* @__PURE__ */ jsx(Button, { onClick: onCancel, children: "Cancel" })
17
+ ] });
18
+ };
19
+
20
+ export { EditButtons };
21
+ //# sourceMappingURL=EditButtons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditButtons.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditButtons.tsx"],"sourcesContent":["import { Button } from \"@salt-ds/core\";\nimport { EditState, EditTracker } from \"./EditTracker\";\nimport { useMemo, useState } from \"react\";\n\nexport interface EditButtonProps {\n editTracker?: EditTracker;\n onCancel: () => void;\n onSave: () => void;\n}\n\nexport const EditButtons = ({\n editTracker,\n onCancel,\n onSave,\n}: EditButtonProps) => {\n const [editState, setEditState] = useState<EditState>(\"clean\");\n\n useMemo(() => {\n editTracker?.on(\"editState\", setEditState);\n }, [editTracker]);\n\n return (\n <>\n <Button disabled={editState === \"clean\"} onClick={onSave}>\n Save\n </Button>\n <Button onClick={onCancel}>Cancel</Button>\n </>\n );\n};\n"],"names":[],"mappings":";;;;AAUO,MAAM,cAAc,CAAC;AAAA,EAC1B,WAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAuB,KAAA;AACrB,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAoB,OAAO,CAAA;AAE7D,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAa,WAAA,EAAA,EAAA,CAAG,aAAa,YAAY,CAAA;AAAA,GAC3C,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,EAAA,uBAEI,IAAA,CAAA,QAAA,EAAA,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UAAO,QAAU,EAAA,SAAA,KAAc,OAAS,EAAA,OAAA,EAAS,QAAQ,QAE1D,EAAA,MAAA,EAAA,CAAA;AAAA,oBACC,GAAA,CAAA,MAAA,EAAA,EAAO,OAAS,EAAA,QAAA,EAAU,QAAM,EAAA,QAAA,EAAA;AAAA,GACnC,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,152 @@
1
+ import { EventEmitter } from '../event-emitter.js';
2
+ import { isRpcSuccess } from '../protocol-message-utils.js';
3
+
4
+ var __typeError = (msg) => {
5
+ throw TypeError(msg);
6
+ };
7
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
8
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
11
+ var _active, _rowEdits, _editCount, _dataSource, _inEditMode;
12
+ class EditTracker extends EventEmitter {
13
+ constructor() {
14
+ super(...arguments);
15
+ __privateAdd(this, _active, false);
16
+ /**
17
+ * Row key => row edits
18
+ */
19
+ __privateAdd(this, _rowEdits, /* @__PURE__ */ new Map());
20
+ __privateAdd(this, _editCount, 0);
21
+ __privateAdd(this, _dataSource);
22
+ __privateAdd(this, _inEditMode, false);
23
+ }
24
+ get active() {
25
+ return __privateGet(this, _active);
26
+ }
27
+ set active(isActive) {
28
+ __privateSet(this, _active, isActive);
29
+ }
30
+ get editCount() {
31
+ return __privateGet(this, _editCount);
32
+ }
33
+ set editCount(val) {
34
+ if (val !== __privateGet(this, _editCount)) {
35
+ const oldCount = __privateGet(this, _editCount);
36
+ __privateSet(this, _editCount, val);
37
+ if (val === 0) {
38
+ this.emit("editState", "clean");
39
+ } else if (oldCount === 0) {
40
+ this.emit("editState", "dirty");
41
+ }
42
+ }
43
+ }
44
+ set dataSource(ds) {
45
+ __privateSet(this, _dataSource, ds);
46
+ }
47
+ clear() {
48
+ __privateGet(this, _rowEdits).clear();
49
+ __privateSet(this, _editCount, 0);
50
+ }
51
+ async enterEditMode() {
52
+ __privateSet(this, _inEditMode, true);
53
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
54
+ type: "RPC_REQUEST",
55
+ rpcName: "ENTER_EDIT_MODE",
56
+ params: {}
57
+ });
58
+ if (isRpcSuccess(rpcResponse)) {
59
+ const { table: sessionTable } = rpcResponse.data;
60
+ return sessionTable;
61
+ } else {
62
+ console.log("fail");
63
+ }
64
+ }
65
+ get inEditMode() {
66
+ return __privateGet(this, _inEditMode);
67
+ }
68
+ get editState() {
69
+ return this.editCount === 0 ? "clean" : "dirty";
70
+ }
71
+ async cancelChanges() {
72
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
73
+ type: "RPC_REQUEST",
74
+ rpcName: "EXIT_EDIT_MODE",
75
+ params: {}
76
+ });
77
+ this.clear();
78
+ return rpcResponse;
79
+ }
80
+ async saveChanges() {
81
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
82
+ type: "RPC_REQUEST",
83
+ rpcName: "EXIT_EDIT_MODE",
84
+ params: { save: true }
85
+ });
86
+ this.clear();
87
+ return rpcResponse;
88
+ }
89
+ // TODO how do we deal with the '_edited' pattern
90
+ edit(key, columnName, originalValue, newValue) {
91
+ const rowEditDetails = __privateGet(this, _rowEdits).get(key);
92
+ if (rowEditDetails) {
93
+ const { cellEdits } = rowEditDetails;
94
+ const cellEdit = cellEdits.get(columnName);
95
+ if (cellEdit) {
96
+ if (newValue === cellEdit.originalValue) {
97
+ if (cellEdits.size === 1) {
98
+ __privateGet(this, _rowEdits).delete(key);
99
+ } else {
100
+ cellEdits.delete(columnName);
101
+ }
102
+ this.editCount = __privateGet(this, _editCount) - 1;
103
+ } else {
104
+ cellEdit.editedValue = newValue;
105
+ }
106
+ } else {
107
+ cellEdits.set(columnName, {
108
+ originalValue,
109
+ editedValue: newValue
110
+ });
111
+ this.editCount = __privateGet(this, _editCount) + 1;
112
+ }
113
+ } else {
114
+ __privateGet(this, _rowEdits).set(key, {
115
+ cellEdits: /* @__PURE__ */ new Map([
116
+ [columnName, { originalValue, editedValue: newValue }]
117
+ ])
118
+ });
119
+ this.editCount = __privateGet(this, _editCount) + 1;
120
+ }
121
+ }
122
+ async commit(key, columnName) {
123
+ const rowEditDetails = __privateGet(this, _rowEdits).get(key);
124
+ if (rowEditDetails) {
125
+ const { cellEdits } = rowEditDetails;
126
+ const cellEditValues = cellEdits.get(columnName);
127
+ if (cellEditValues) {
128
+ const { editedValue } = cellEditValues;
129
+ const rpcResponse = await __privateGet(this, _dataSource)?.rpcRequest?.({
130
+ type: "RPC_REQUEST",
131
+ rpcName: "editCell",
132
+ params: {
133
+ column: `${columnName}`,
134
+ data: editedValue,
135
+ key
136
+ }
137
+ });
138
+ return rpcResponse;
139
+ }
140
+ } else {
141
+ throw Error(`[EditTracker] commit, key ${key} not found `);
142
+ }
143
+ }
144
+ }
145
+ _active = new WeakMap();
146
+ _rowEdits = new WeakMap();
147
+ _editCount = new WeakMap();
148
+ _dataSource = new WeakMap();
149
+ _inEditMode = new WeakMap();
150
+
151
+ export { EditTracker };
152
+ //# sourceMappingURL=EditTracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EditTracker.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/EditTracker.tsx"],"sourcesContent":["import { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuRowDataItemType, VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { EventEmitter } from \"../event-emitter\";\nimport { isRpcSuccess } from \"../protocol-message-utils\";\n\nexport type EditState = \"clean\" | \"dirty\";\n\ntype CellEdit = {\n originalValue: VuuRowDataItemType;\n editedValue: VuuRowDataItemType;\n};\n\ntype RowEditDetails = {\n /**\n * Column name => cell edit details\n */\n cellEdits: Map<string, CellEdit>;\n};\n\ntype EditTrackerEvents = {\n editState: (editState: EditState) => void;\n};\n\nexport class EditTracker extends EventEmitter<EditTrackerEvents> {\n #active = false;\n /**\n * Row key => row edits\n */\n #rowEdits = new Map<string, RowEditDetails>();\n #editCount = 0;\n #dataSource?: DataSource;\n #inEditMode = false;\n\n get active() {\n return this.#active;\n }\n set active(isActive: boolean) {\n this.#active = isActive;\n }\n get editCount() {\n return this.#editCount;\n }\n\n set editCount(val: number) {\n if (val !== this.#editCount) {\n const oldCount = this.#editCount;\n this.#editCount = val;\n if (val === 0) {\n this.emit(\"editState\", \"clean\");\n } else if (oldCount === 0) {\n this.emit(\"editState\", \"dirty\");\n }\n }\n }\n\n set dataSource(ds: DataSource) {\n this.#dataSource = ds;\n }\n\n clear() {\n this.#rowEdits.clear();\n this.#editCount = 0;\n }\n\n async enterEditMode() {\n this.#inEditMode = true;\n\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"ENTER_EDIT_MODE\",\n params: {},\n });\n\n if (isRpcSuccess(rpcResponse)) {\n const { table: sessionTable } = rpcResponse.data as { table: VuuTable };\n return sessionTable;\n } else {\n console.log(\"fail\");\n }\n }\n\n get inEditMode() {\n return this.#inEditMode;\n }\n\n get editState(): EditState {\n return this.editCount === 0 ? \"clean\" : \"dirty\";\n }\n\n async cancelChanges() {\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"EXIT_EDIT_MODE\",\n params: {},\n });\n this.clear();\n return rpcResponse;\n }\n\n async saveChanges() {\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"EXIT_EDIT_MODE\",\n params: { save: true },\n });\n this.clear();\n return rpcResponse;\n }\n\n // TODO how do we deal with the '_edited' pattern\n edit(\n key: string,\n columnName: string,\n originalValue: VuuRowDataItemType,\n newValue: VuuRowDataItemType,\n ) {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n const { cellEdits } = rowEditDetails;\n const cellEdit = cellEdits.get(columnName);\n if (cellEdit) {\n if (newValue === cellEdit.originalValue) {\n if (cellEdits.size === 1) {\n this.#rowEdits.delete(key);\n } else {\n // re-editing a cell had removed the edit\n cellEdits.delete(columnName);\n }\n this.editCount = this.#editCount - 1;\n } else {\n cellEdit.editedValue = newValue;\n }\n } else {\n // row has already been edited, but this column has not\n cellEdits.set(columnName, {\n originalValue,\n editedValue: newValue,\n });\n this.editCount = this.#editCount + 1;\n }\n } else {\n this.#rowEdits.set(key, {\n cellEdits: new Map([\n [columnName, { originalValue, editedValue: newValue }],\n ]),\n });\n this.editCount = this.#editCount + 1;\n }\n }\n\n async commit(key: string, columnName: string) {\n const rowEditDetails = this.#rowEdits.get(key);\n if (rowEditDetails) {\n const { cellEdits } = rowEditDetails;\n const cellEditValues = cellEdits.get(columnName);\n if (cellEditValues) {\n const { editedValue } = cellEditValues;\n const rpcResponse = await this.#dataSource?.rpcRequest?.({\n type: \"RPC_REQUEST\",\n rpcName: \"editCell\",\n params: {\n column: `${columnName}`,\n data: editedValue,\n key,\n },\n });\n\n return rpcResponse;\n }\n } else {\n throw Error(`[EditTracker] commit, key ${key} not found `);\n }\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import { useState, useMemo, useCallback } from 'react';
2
+ import { EditTracker } from './EditTracker.js';
3
+ import { useData } from '../context-definitions/DataProvider.js';
4
+ import { isRpcSuccess } from '../protocol-message-utils.js';
5
+
6
+ const useEditableTable = ({ table }) => {
7
+ const { VuuDataSource } = useData();
8
+ const [editMode, setEditMode] = useState("view");
9
+ const [sessionDataSource, setSessionDataSource] = useState(void 0);
10
+ const dataSource = useMemo(() => {
11
+ return new VuuDataSource({ table });
12
+ }, [table, VuuDataSource]);
13
+ const editTracker = useMemo(() => new EditTracker(), []);
14
+ useMemo(() => {
15
+ if (dataSource) {
16
+ editTracker.dataSource = dataSource;
17
+ }
18
+ }, [dataSource, editTracker]);
19
+ const onCancel = useCallback(() => {
20
+ editTracker.dataSource = dataSource;
21
+ editTracker.cancelChanges();
22
+ setEditMode("view");
23
+ setSessionDataSource(void 0);
24
+ dataSource.resume?.();
25
+ }, [dataSource, editTracker]);
26
+ const onSave = useCallback(async () => {
27
+ editTracker.dataSource = dataSource;
28
+ const response = await editTracker.saveChanges();
29
+ if (isRpcSuccess(response)) {
30
+ setEditMode("view");
31
+ setSessionDataSource(void 0);
32
+ dataSource.resume?.();
33
+ }
34
+ }, [dataSource, editTracker]);
35
+ const onToggleEditMode = useCallback(
36
+ async (e) => {
37
+ const toggleButton = e.target;
38
+ const editMode2 = toggleButton.value;
39
+ setEditMode(editMode2);
40
+ if (editMode2 === "edit") {
41
+ const sessionTable = await editTracker.enterEditMode();
42
+ if (sessionTable && dataSource.tableSchema) {
43
+ dataSource.suspend?.(false);
44
+ const sessionDataSource2 = new VuuDataSource({
45
+ columns: dataSource.columns,
46
+ table: sessionTable,
47
+ viewport: sessionTable.table
48
+ });
49
+ setSessionDataSource(sessionDataSource2);
50
+ editTracker.dataSource = sessionDataSource2;
51
+ }
52
+ }
53
+ },
54
+ [VuuDataSource, dataSource, editTracker]
55
+ );
56
+ return {
57
+ dataSource: sessionDataSource ?? dataSource,
58
+ editMode,
59
+ editTracker,
60
+ onCancel,
61
+ onSave,
62
+ onToggleEditMode
63
+ };
64
+ };
65
+
66
+ export { useEditableTable };
67
+ //# sourceMappingURL=useEditableTable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEditableTable.js","sources":["../../../../../../../packages/vuu-utils/src/data-editing/useEditableTable.ts"],"sourcesContent":["import { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { SyntheticEvent, useCallback, useMemo, useState } from \"react\";\nimport { EditTracker } from \"./EditTracker\";\nimport { useData } from \"../context-definitions/DataProvider\";\nimport { DataSource } from \"@vuu-ui/vuu-data-types\";\nimport { isRpcSuccess } from \"../protocol-message-utils\";\n\nexport type EditMode = \"edit\" | \"view\";\n\nexport const useEditableTable = ({ table }: { table: VuuTable }) => {\n const { VuuDataSource } = useData();\n const [editMode, setEditMode] = useState<EditMode>(\"view\");\n const [sessionDataSource, setSessionDataSource] = useState<\n DataSource | undefined\n >(undefined);\n\n const dataSource = useMemo(() => {\n return new VuuDataSource({ table });\n }, [table, VuuDataSource]);\n\n const editTracker = useMemo(() => new EditTracker(), []);\n\n useMemo(() => {\n if (dataSource) {\n editTracker.dataSource = dataSource;\n }\n }, [dataSource, editTracker]);\n\n const onCancel = useCallback(() => {\n editTracker.dataSource = dataSource;\n editTracker.cancelChanges();\n setEditMode(\"view\");\n setSessionDataSource(undefined);\n dataSource.resume?.();\n }, [dataSource, editTracker]);\n\n const onSave = useCallback(async () => {\n editTracker.dataSource = dataSource;\n const response = await editTracker.saveChanges();\n if (isRpcSuccess(response)) {\n setEditMode(\"view\");\n setSessionDataSource(undefined);\n dataSource.resume?.();\n }\n }, [dataSource, editTracker]);\n\n const onToggleEditMode = useCallback(\n async (e: SyntheticEvent<HTMLButtonElement>) => {\n const toggleButton = e.target as HTMLButtonElement;\n const editMode = toggleButton.value as EditMode;\n setEditMode(editMode);\n if (editMode === \"edit\") {\n const sessionTable = await editTracker.enterEditMode();\n if (sessionTable && dataSource.tableSchema) {\n dataSource.suspend?.(false);\n const sessionDataSource = new VuuDataSource({\n columns: dataSource.columns,\n table: sessionTable,\n viewport: sessionTable.table,\n });\n setSessionDataSource(sessionDataSource);\n editTracker.dataSource = sessionDataSource;\n }\n }\n },\n [VuuDataSource, dataSource, editTracker],\n );\n\n return {\n dataSource: sessionDataSource ?? dataSource,\n editMode,\n editTracker,\n onCancel,\n onSave,\n onToggleEditMode,\n };\n};\n"],"names":["editMode","sessionDataSource"],"mappings":";;;;;AASO,MAAM,gBAAmB,GAAA,CAAC,EAAE,KAAA,EAAiC,KAAA;AAClE,EAAM,MAAA,EAAE,aAAc,EAAA,GAAI,OAAQ,EAAA;AAClC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAmB,MAAM,CAAA;AACzD,EAAA,MAAM,CAAC,iBAAA,EAAmB,oBAAoB,CAAA,GAAI,SAEhD,KAAS,CAAA,CAAA;AAEX,EAAM,MAAA,UAAA,GAAa,QAAQ,MAAM;AAC/B,IAAA,OAAO,IAAI,aAAA,CAAc,EAAE,KAAA,EAAO,CAAA;AAAA,GACjC,EAAA,CAAC,KAAO,EAAA,aAAa,CAAC,CAAA;AAEzB,EAAA,MAAM,cAAc,OAAQ,CAAA,MAAM,IAAI,WAAY,EAAA,EAAG,EAAE,CAAA;AAEvD,EAAA,OAAA,CAAQ,MAAM;AACZ,IAAA,IAAI,UAAY,EAAA;AACd,MAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AAAA;AAC3B,GACC,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAM,MAAA,QAAA,GAAW,YAAY,MAAM;AACjC,IAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AACzB,IAAA,WAAA,CAAY,aAAc,EAAA;AAC1B,IAAA,WAAA,CAAY,MAAM,CAAA;AAClB,IAAA,oBAAA,CAAqB,KAAS,CAAA,CAAA;AAC9B,IAAA,UAAA,CAAW,MAAS,IAAA;AAAA,GACnB,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAM,MAAA,MAAA,GAAS,YAAY,YAAY;AACrC,IAAA,WAAA,CAAY,UAAa,GAAA,UAAA;AACzB,IAAM,MAAA,QAAA,GAAW,MAAM,WAAA,CAAY,WAAY,EAAA;AAC/C,IAAI,IAAA,YAAA,CAAa,QAAQ,CAAG,EAAA;AAC1B,MAAA,WAAA,CAAY,MAAM,CAAA;AAClB,MAAA,oBAAA,CAAqB,KAAS,CAAA,CAAA;AAC9B,MAAA,UAAA,CAAW,MAAS,IAAA;AAAA;AACtB,GACC,EAAA,CAAC,UAAY,EAAA,WAAW,CAAC,CAAA;AAE5B,EAAA,MAAM,gBAAmB,GAAA,WAAA;AAAA,IACvB,OAAO,CAAyC,KAAA;AAC9C,MAAA,MAAM,eAAe,CAAE,CAAA,MAAA;AACvB,MAAA,MAAMA,YAAW,YAAa,CAAA,KAAA;AAC9B,MAAA,WAAA,CAAYA,SAAQ,CAAA;AACpB,MAAA,IAAIA,cAAa,MAAQ,EAAA;AACvB,QAAM,MAAA,YAAA,GAAe,MAAM,WAAA,CAAY,aAAc,EAAA;AACrD,QAAI,IAAA,YAAA,IAAgB,WAAW,WAAa,EAAA;AAC1C,UAAA,UAAA,CAAW,UAAU,KAAK,CAAA;AAC1B,UAAMC,MAAAA,kBAAAA,GAAoB,IAAI,aAAc,CAAA;AAAA,YAC1C,SAAS,UAAW,CAAA,OAAA;AAAA,YACpB,KAAO,EAAA,YAAA;AAAA,YACP,UAAU,YAAa,CAAA;AAAA,WACxB,CAAA;AACD,UAAA,oBAAA,CAAqBA,kBAAiB,CAAA;AACtC,UAAA,WAAA,CAAY,UAAaA,GAAAA,kBAAAA;AAAA;AAC3B;AACF,KACF;AAAA,IACA,CAAC,aAAe,EAAA,UAAA,EAAY,WAAW;AAAA,GACzC;AAEA,EAAO,OAAA;AAAA,IACL,YAAY,iBAAqB,IAAA,UAAA;AAAA,IACjC,QAAA;AAAA,IACA,WAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -1,6 +1,6 @@
1
1
  import { partition } from './array-utils.js';
2
2
  import { wordify } from './text-utils.js';
3
- import React from 'react';
3
+ import React__default from 'react';
4
4
  import { getLayoutComponent } from './component-registry.js';
5
5
 
6
6
  const env = process.env.NODE_ENV;
@@ -13,7 +13,7 @@ function featureFromJson({ type }) {
13
13
  `layoutUtils unable to create feature component from JSON, unknown type ${type}`
14
14
  );
15
15
  }
16
- return React.createElement(componentType);
16
+ return React__default.createElement(componentType);
17
17
  }
18
18
  const isCustomFeature = (feature) => feature.leftNavLocation === "vuu-features";
19
19
  const isWildcardSchema = (vuuTables) => vuuTables === "*";
@@ -1 +1 @@
1
- {"version":3,"file":"feature-utils.js","sources":["../../../../../../packages/vuu-utils/src/feature-utils.ts"],"sourcesContent":["import type { TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { ListOption } from \"@vuu-ui/vuu-table-types\";\nimport { partition } from \"./array-utils\";\nimport { wordify } from \"./text-utils\";\nimport React, { ReactElement } from \"react\";\nimport { getLayoutComponent } from \"./component-registry\";\n\nexport type PathMap = {\n [key: string]: Pick<DynamicFeatureDescriptor, \"css\" | \"url\">;\n};\nexport type Environment = \"development\" | \"production\";\nexport const env = process.env.NODE_ENV as Environment;\n\nexport type LookupTableProvider = (table: VuuTable) => ListOption[];\n\nexport interface ViewConfig {\n allowRename?: boolean;\n closeable?: boolean;\n header?: boolean;\n}\n\nexport interface DynamicFeatureProps<P extends object | undefined = object> {\n /**\n props that will be passed to the lazily loaded component.\n */\n ComponentProps?: P;\n ViewProps?: ViewConfig;\n css?: string;\n height?: number;\n title?: string;\n /** \n The url of javascript bundle to lazily load. Bundle must provide a default export\n and that export must be a React component.\n */\n url: string;\n width?: number;\n}\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const vuuConfig: Promise<VuuConfig>;\n}\n\nexport interface DynamicFeatureDescriptor {\n /**\n * url for css file for feature\n */\n css?: string;\n featureProps?: {\n vuuTables?: \"*\" | VuuTable[];\n };\n leftNavLocation: \"vuu-features\" | \"vuu-tables\";\n name: string;\n title: string;\n /**\n * url for javascript bundle to load feature\n */\n url: string;\n viewProps?: ViewConfig;\n}\n\nexport interface StaticFeatureDescriptor {\n group?: string;\n label: string;\n type: string;\n}\n\nconst isStaticFeature = (\n feature: unknown,\n): feature is StaticFeatureDescriptor =>\n feature !== null && typeof feature === \"object\" && \"type\" in feature;\n\nexport const isStaticFeatures = (\n features: unknown,\n): features is StaticFeatureDescriptor[] =>\n Array.isArray(features) && features.every(isStaticFeature);\n\nexport interface FilterTableFeatureProps {\n tableSchema: TableSchema;\n}\n\nexport type DynamicFeatures = {\n [key: string]: DynamicFeatureDescriptor;\n};\n\nexport function featureFromJson({ type }: { type: string }): ReactElement {\n const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);\n if (componentType === undefined) {\n throw Error(\n `layoutUtils unable to create feature component from JSON, unknown type ${type}`,\n );\n }\n return React.createElement(componentType);\n}\n\nexport interface VuuConfig {\n features: DynamicFeatures;\n authUrl?: string;\n websocketUrl: string;\n ssl: boolean;\n}\n\n/**\n * We currently categorize 'features' simply by the leftNavLocation\n * @param feature\n * @returns\n */\nexport const isCustomFeature = (feature: DynamicFeatureDescriptor) =>\n feature.leftNavLocation === \"vuu-features\";\n\nexport const isWildcardSchema = (\n vuuTables?: \"*\" | VuuTable[],\n): vuuTables is \"*\" => vuuTables === \"*\";\nexport const isVuuTables = (\n vuuTables?: \"*\" | VuuTable[],\n): vuuTables is VuuTable[] => Array.isArray(vuuTables);\n\nexport interface FeaturePropsWithFilterTableFeature\n extends Omit<DynamicFeatureProps, \"ComponentProps\"> {\n ComponentProps: FilterTableFeatureProps;\n}\n\nexport const hasFilterTableFeatureProps = (\n props: DynamicFeatureProps,\n): props is FeaturePropsWithFilterTableFeature =>\n typeof props.ComponentProps === \"object\" &&\n props.ComponentProps !== null &&\n \"tableSchema\" in props.ComponentProps;\n\nexport const isSameTable = (t1: VuuTable, t2: VuuTable) => {\n t1.module === t2.module && t1.table == t2.table;\n};\n\n// Sort TableScheas by module\nexport const byModule = (schema1: TableSchema, schema2: TableSchema) => {\n const m1 = schema1.table.module.toLowerCase();\n const m2 = schema2.table.module.toLowerCase();\n if (m1 < m2) {\n return -1;\n } else if (m1 > m2) {\n return 1;\n } else if (schema1.table.table < schema2.table.table) {\n return -1;\n } else if (schema1.table.table > schema2.table.table) {\n return 1;\n } else {\n return 0;\n }\n};\n\nexport type GetFeaturePaths = (params: {\n env: Environment;\n fileName: string;\n withCss?: boolean;\n}) => DynamicFeatureProps;\n\nexport const getFilterTableFeatures = (\n schemas: TableSchema[],\n getFeaturePath: GetFeaturePaths,\n) =>\n schemas\n .sort(byModule)\n .map<DynamicFeatureProps<FilterTableFeatureProps>>((schema) => ({\n ...getFeaturePath({ env, fileName: \"FilterTable\" }),\n ComponentProps: {\n tableSchema: schema,\n },\n ViewProps: {\n allowRename: true,\n },\n title: `${schema.table.module} ${schema.table.table}`,\n }));\n\nexport type Component = {\n componentName: string;\n component: unknown;\n};\n\nexport const assertComponentRegistered = (\n componentName: string,\n component: unknown,\n) => {\n if (typeof component !== \"function\") {\n console.warn(\n `${componentName} module not loaded, will be unabale to deserialize from layout JSON`,\n );\n }\n};\n\nexport const assertComponentsRegistered = (componentList: Component[]) => {\n for (const { componentName, component } of componentList) {\n assertComponentRegistered(componentName, component);\n }\n};\n/**\n * Process the DynamicFeature descriptors. Identify\n * the vuu tables required and inject the appropriate TableSchemas\n *\n * @param dynamicFeatures\n * @param tableSchemas\n * @returns\n */\nexport const getCustomAndTableFeatures = (\n dynamicFeatures: DynamicFeatureDescriptor[],\n tableSchemas: TableSchema[],\n): {\n dynamicFeatures: DynamicFeatureProps[];\n tableFeatures: DynamicFeatureProps<FilterTableFeatureProps>[];\n} => {\n // Split features into simple tables and 'custom' features\n const [customFeatureConfig, tableFeaturesConfig] = partition(\n dynamicFeatures,\n isCustomFeature,\n );\n\n const customFeatures: DynamicFeatureProps[] = [];\n const tableFeatures: DynamicFeatureProps<FilterTableFeatureProps>[] = [];\n\n for (const {\n featureProps = {},\n viewProps,\n ...feature\n } of tableFeaturesConfig) {\n const { vuuTables } = featureProps;\n // Currently FilterTable is the only 'tableFeature' and it uses the wildcard\n if (isWildcardSchema(vuuTables)) {\n if (tableSchemas) {\n for (const tableSchema of tableSchemas) {\n tableFeatures.push({\n ...feature,\n ComponentProps: {\n tableSchema,\n },\n title: `${tableSchema.table.module} ${wordify(\n tableSchema.table.table,\n )}`,\n ViewProps: {\n ...viewProps,\n allowRename: true,\n },\n });\n }\n }\n }\n }\n\n for (const {\n featureProps = {},\n viewProps,\n ...feature\n } of customFeatureConfig) {\n const { vuuTables } = featureProps;\n if (isVuuTables(vuuTables)) {\n if (tableSchemas) {\n customFeatures.push({\n ...feature,\n ComponentProps: vuuTables.reduce<Record<string, TableSchema>>(\n (map, vuuTable) => {\n map[`${vuuTable.table}Schema`] = tableSchemas.find(\n (tableSchema) => isSameTable(vuuTable, tableSchema.table),\n ) as TableSchema;\n return map;\n },\n {},\n ),\n ViewProps: viewProps,\n });\n }\n } else {\n customFeatures.push(feature);\n }\n }\n return { dynamicFeatures: customFeatures, tableFeatures: tableFeatures };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-utils.js","sources":["../../../../../../packages/vuu-utils/src/feature-utils.ts"],"sourcesContent":["import type { TableSchema } from \"@vuu-ui/vuu-data-types\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport { ListOption } from \"@vuu-ui/vuu-table-types\";\nimport { partition } from \"./array-utils\";\nimport { wordify } from \"./text-utils\";\nimport React, { ReactElement } from \"react\";\nimport { getLayoutComponent } from \"./component-registry\";\n\nexport type PathMap = {\n [key: string]: Pick<DynamicFeatureDescriptor, \"css\" | \"url\">;\n};\nexport type Environment = \"development\" | \"production\";\nexport const env = process.env.NODE_ENV as Environment;\n\nexport type LookupTableProvider = (table: VuuTable) => ListOption[];\n\nexport interface ViewConfig {\n allowRename?: boolean;\n closeable?: boolean;\n header?: boolean;\n}\n\nexport interface DynamicFeatureProps<P extends object | undefined = object> {\n /**\n props that will be passed to the lazily loaded component.\n */\n ComponentProps?: P;\n ViewProps?: ViewConfig;\n css?: string;\n height?: number;\n title?: string;\n /** \n The url of javascript bundle to lazily load. Bundle must provide a default export\n and that export must be a React component.\n */\n url: string;\n width?: number;\n}\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const vuuConfig: Promise<VuuConfig>;\n}\n\nexport interface DynamicFeatureDescriptor {\n /**\n * url for css file for feature\n */\n css?: string;\n featureProps?: {\n vuuTables?: \"*\" | VuuTable[];\n };\n leftNavLocation: \"vuu-features\" | \"vuu-tables\";\n name: string;\n title: string;\n /**\n * url for javascript bundle to load feature\n */\n url: string;\n viewProps?: ViewConfig;\n}\n\nexport interface StaticFeatureDescriptor {\n group?: string;\n label: string;\n type: string;\n}\n\nconst isStaticFeature = (\n feature: unknown,\n): feature is StaticFeatureDescriptor =>\n feature !== null && typeof feature === \"object\" && \"type\" in feature;\n\nexport const isStaticFeatures = (\n features: unknown,\n): features is StaticFeatureDescriptor[] =>\n Array.isArray(features) && features.every(isStaticFeature);\n\nexport interface FilterTableFeatureProps {\n tableSchema: TableSchema;\n}\n\nexport type DynamicFeatures = {\n [key: string]: DynamicFeatureDescriptor;\n};\n\nexport function featureFromJson({ type }: { type: string }): ReactElement {\n const componentType = type.match(/^[a-z]/) ? type : getLayoutComponent(type);\n if (componentType === undefined) {\n throw Error(\n `layoutUtils unable to create feature component from JSON, unknown type ${type}`,\n );\n }\n return React.createElement(componentType);\n}\n\nexport interface VuuConfig {\n features: DynamicFeatures;\n authUrl?: string;\n websocketUrl: string;\n ssl: boolean;\n}\n\n/**\n * We currently categorize 'features' simply by the leftNavLocation\n * @param feature\n * @returns\n */\nexport const isCustomFeature = (feature: DynamicFeatureDescriptor) =>\n feature.leftNavLocation === \"vuu-features\";\n\nexport const isWildcardSchema = (\n vuuTables?: \"*\" | VuuTable[],\n): vuuTables is \"*\" => vuuTables === \"*\";\nexport const isVuuTables = (\n vuuTables?: \"*\" | VuuTable[],\n): vuuTables is VuuTable[] => Array.isArray(vuuTables);\n\nexport interface FeaturePropsWithFilterTableFeature\n extends Omit<DynamicFeatureProps, \"ComponentProps\"> {\n ComponentProps: FilterTableFeatureProps;\n}\n\nexport const hasFilterTableFeatureProps = (\n props: DynamicFeatureProps,\n): props is FeaturePropsWithFilterTableFeature =>\n typeof props.ComponentProps === \"object\" &&\n props.ComponentProps !== null &&\n \"tableSchema\" in props.ComponentProps;\n\nexport const isSameTable = (t1: VuuTable, t2: VuuTable) => {\n t1.module === t2.module && t1.table == t2.table;\n};\n\n// Sort TableScheas by module\nexport const byModule = (schema1: TableSchema, schema2: TableSchema) => {\n const m1 = schema1.table.module.toLowerCase();\n const m2 = schema2.table.module.toLowerCase();\n if (m1 < m2) {\n return -1;\n } else if (m1 > m2) {\n return 1;\n } else if (schema1.table.table < schema2.table.table) {\n return -1;\n } else if (schema1.table.table > schema2.table.table) {\n return 1;\n } else {\n return 0;\n }\n};\n\nexport type GetFeaturePaths = (params: {\n env: Environment;\n fileName: string;\n withCss?: boolean;\n}) => DynamicFeatureProps;\n\nexport const getFilterTableFeatures = (\n schemas: TableSchema[],\n getFeaturePath: GetFeaturePaths,\n) =>\n schemas\n .sort(byModule)\n .map<DynamicFeatureProps<FilterTableFeatureProps>>((schema) => ({\n ...getFeaturePath({ env, fileName: \"FilterTable\" }),\n ComponentProps: {\n tableSchema: schema,\n },\n ViewProps: {\n allowRename: true,\n },\n title: `${schema.table.module} ${schema.table.table}`,\n }));\n\nexport type Component = {\n componentName: string;\n component: unknown;\n};\n\nexport const assertComponentRegistered = (\n componentName: string,\n component: unknown,\n) => {\n if (typeof component !== \"function\") {\n console.warn(\n `${componentName} module not loaded, will be unabale to deserialize from layout JSON`,\n );\n }\n};\n\nexport const assertComponentsRegistered = (componentList: Component[]) => {\n for (const { componentName, component } of componentList) {\n assertComponentRegistered(componentName, component);\n }\n};\n/**\n * Process the DynamicFeature descriptors. Identify\n * the vuu tables required and inject the appropriate TableSchemas\n *\n * @param dynamicFeatures\n * @param tableSchemas\n * @returns\n */\nexport const getCustomAndTableFeatures = (\n dynamicFeatures: DynamicFeatureDescriptor[],\n tableSchemas: TableSchema[],\n): {\n dynamicFeatures: DynamicFeatureProps[];\n tableFeatures: DynamicFeatureProps<FilterTableFeatureProps>[];\n} => {\n // Split features into simple tables and 'custom' features\n const [customFeatureConfig, tableFeaturesConfig] = partition(\n dynamicFeatures,\n isCustomFeature,\n );\n\n const customFeatures: DynamicFeatureProps[] = [];\n const tableFeatures: DynamicFeatureProps<FilterTableFeatureProps>[] = [];\n\n for (const {\n featureProps = {},\n viewProps,\n ...feature\n } of tableFeaturesConfig) {\n const { vuuTables } = featureProps;\n // Currently FilterTable is the only 'tableFeature' and it uses the wildcard\n if (isWildcardSchema(vuuTables)) {\n if (tableSchemas) {\n for (const tableSchema of tableSchemas) {\n tableFeatures.push({\n ...feature,\n ComponentProps: {\n tableSchema,\n },\n title: `${tableSchema.table.module} ${wordify(\n tableSchema.table.table,\n )}`,\n ViewProps: {\n ...viewProps,\n allowRename: true,\n },\n });\n }\n }\n }\n }\n\n for (const {\n featureProps = {},\n viewProps,\n ...feature\n } of customFeatureConfig) {\n const { vuuTables } = featureProps;\n if (isVuuTables(vuuTables)) {\n if (tableSchemas) {\n customFeatures.push({\n ...feature,\n ComponentProps: vuuTables.reduce<Record<string, TableSchema>>(\n (map, vuuTable) => {\n map[`${vuuTable.table}Schema`] = tableSchemas.find(\n (tableSchema) => isSameTable(vuuTable, tableSchema.table),\n ) as TableSchema;\n return map;\n },\n {},\n ),\n ViewProps: viewProps,\n });\n }\n } else {\n customFeatures.push(feature);\n }\n }\n return { dynamicFeatures: customFeatures, tableFeatures: tableFeatures };\n};\n"],"names":["React"],"mappings":"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"}
@@ -10,6 +10,10 @@ export { MEASURES } from './common-types.js';
10
10
  export { getCellConfigPanelRenderer, getCellRenderer, getCellRendererOptions, getColumnHeaderContentRenderer, getColumnHeaderLabelRenderer, getConfigurationEditor, getEditRuleValidator, getLayoutComponent, getRegisteredCellRenderers, getRowClassNameGenerator, isContainer, isLayoutComponent, isView, registerComponent, registerConfigurationEditor } from './component-registry.js';
11
11
  export { getCookieValue, setCookieValue } from './cookie-utils.js';
12
12
  export { importCSS } from './css-utils.js';
13
+ export { EditButtons } from './data-editing/EditButtons.js';
14
+ export { DataEditingProvider, useEditTracker } from './data-editing/DataEditingProvider.js';
15
+ export { EditTracker } from './data-editing/EditTracker.js';
16
+ export { useEditableTable } from './data-editing/useEditableTable.js';
13
17
  export { DOWN1, DOWN2, UP1, UP2, asInteger, getMovingValueDirection, isValidNumber, numericTypeOfStringValue, shallowEquals, stringIsValidDecimal, stringIsValidInt, stringIsValidNumber } from './data-utils.js';
14
18
  export { BaseDataSource, defaultSuspenseProps } from './datasource/BaseDataSource.js';
15
19
  export { isViewportMenusAction, isVisualLinkCreatedAction, isVisualLinkRemovedAction, isVisualLinksAction, isVuuFeatureAction } from './datasource/datasource-action-utils.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
- "version": "2.0.0",
2
+ "version": "2.1.0-alpha.2",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "types": "types/index.d.ts",
6
6
  "devDependencies": {
7
- "@vuu-ui/vuu-data-types": "2.0.0",
8
- "@vuu-ui/vuu-table-types": "2.0.0",
9
- "@vuu-ui/vuu-filter-types": "2.0.0",
10
- "@vuu-ui/vuu-protocol-types": "2.0.0"
7
+ "@vuu-ui/vuu-data-types": "2.1.0-alpha.2",
8
+ "@vuu-ui/vuu-table-types": "2.1.0-alpha.2",
9
+ "@vuu-ui/vuu-filter-types": "2.1.0-alpha.2",
10
+ "@vuu-ui/vuu-protocol-types": "2.1.0-alpha.2"
11
11
  },
12
12
  "peerDependencies": {
13
13
  "@internationalized/date": "^3.0.0",
14
- "@vuu-ui/vuu-filter-parser": "2.0.0",
14
+ "@vuu-ui/vuu-filter-parser": "2.1.0-alpha.2",
15
15
  "clsx": "^2.0.0",
16
16
  "react": "^19.2.3",
17
17
  "react-dom": "^19.2.3"
@@ -0,0 +1,7 @@
1
+ import { ReactNode } from "react";
2
+ import { EditTracker } from "./EditTracker";
3
+ export declare const DataEditingProvider: ({ children, editTracker, }: {
4
+ children: ReactNode;
5
+ editTracker: EditTracker;
6
+ }) => import("react/jsx-runtime").JSX.Element;
7
+ export declare const useEditTracker: () => EditTracker | undefined;
@@ -0,0 +1,7 @@
1
+ import { EditTracker } from "./EditTracker";
2
+ export interface EditButtonProps {
3
+ editTracker?: EditTracker;
4
+ onCancel: () => void;
5
+ onSave: () => void;
6
+ }
7
+ export declare const EditButtons: ({ editTracker, onCancel, onSave, }: EditButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,24 @@
1
+ import { DataSource } from "@vuu-ui/vuu-data-types";
2
+ import type { VuuRowDataItemType, VuuTable } from "@vuu-ui/vuu-protocol-types";
3
+ import { EventEmitter } from "../event-emitter";
4
+ export type EditState = "clean" | "dirty";
5
+ type EditTrackerEvents = {
6
+ editState: (editState: EditState) => void;
7
+ };
8
+ export declare class EditTracker extends EventEmitter<EditTrackerEvents> {
9
+ #private;
10
+ get active(): boolean;
11
+ set active(isActive: boolean);
12
+ get editCount(): number;
13
+ set editCount(val: number);
14
+ set dataSource(ds: DataSource);
15
+ clear(): void;
16
+ enterEditMode(): Promise<VuuTable | undefined>;
17
+ get inEditMode(): boolean;
18
+ get editState(): EditState;
19
+ cancelChanges(): Promise<import("@vuu-ui/vuu-protocol-types").RpcResultSuccess | import("@vuu-ui/vuu-protocol-types").RpcResultError | undefined>;
20
+ saveChanges(): Promise<import("@vuu-ui/vuu-protocol-types").RpcResultSuccess | import("@vuu-ui/vuu-protocol-types").RpcResultError | undefined>;
21
+ edit(key: string, columnName: string, originalValue: VuuRowDataItemType, newValue: VuuRowDataItemType): void;
22
+ commit(key: string, columnName: string): Promise<import("@vuu-ui/vuu-protocol-types").RpcResultSuccess | import("@vuu-ui/vuu-protocol-types").RpcResultError | undefined>;
23
+ }
24
+ export {};
@@ -0,0 +1,15 @@
1
+ import { VuuTable } from "@vuu-ui/vuu-protocol-types";
2
+ import { SyntheticEvent } from "react";
3
+ import { EditTracker } from "./EditTracker";
4
+ import { DataSource } from "@vuu-ui/vuu-data-types";
5
+ export type EditMode = "edit" | "view";
6
+ export declare const useEditableTable: ({ table }: {
7
+ table: VuuTable;
8
+ }) => {
9
+ dataSource: DataSource;
10
+ editMode: EditMode;
11
+ editTracker: EditTracker;
12
+ onCancel: () => void;
13
+ onSave: () => Promise<void>;
14
+ onToggleEditMode: (e: SyntheticEvent<HTMLButtonElement>) => Promise<void>;
15
+ };
package/types/index.d.ts CHANGED
@@ -12,6 +12,10 @@ export * from "./common-types";
12
12
  export * from "./component-registry";
13
13
  export * from "./cookie-utils";
14
14
  export * from "./css-utils";
15
+ export { EditButtons, type EditButtonProps } from "./data-editing/EditButtons";
16
+ export { DataEditingProvider, useEditTracker, } from "./data-editing/DataEditingProvider";
17
+ export { EditTracker, type EditState } from "./data-editing/EditTracker";
18
+ export { useEditableTable } from "./data-editing/useEditableTable";
15
19
  export * from "./data-utils";
16
20
  export * from "./datasource/BaseDataSource";
17
21
  export * from "./datasource/datasource-action-utils";
@@ -62,7 +66,7 @@ export * from "./url-utils";
62
66
  export * from "./useId";
63
67
  export * from "./useLayoutEffectSkipFirst";
64
68
  export * from "./user-types";
65
- export { WidthHeight, WidthOnly, useResizeObserver, type measurements, type ResizeHandler, } from "./useResizeObserver";
69
+ export { useResizeObserver, WidthHeight, WidthOnly, type measurements, type ResizeHandler, } from "./useResizeObserver";
66
70
  export * from "./useStateRef";
67
71
  /** Context declarations hosted in utils to minimize intra package dependencies */
68
72
  export { DataContext } from "./context-definitions/DataContext";