@apipass/design-system 7.4.7 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/lib/embedded-styles.js +2 -2
  2. package/dist/lib/lib.index.cjs +1 -1
  3. package/dist/lib/lib.index.js +808 -796
  4. package/dist/lib/lib.index.js.map +1 -1
  5. package/dist/lib/style.css +1 -1
  6. package/dist/lib/ui/components/ConfirmDialog/ConfirmDialog.cjs +1 -1
  7. package/dist/lib/ui/components/ConfirmDialog/ConfirmDialog.cjs.map +1 -1
  8. package/dist/lib/ui/components/ConfirmDialog/ConfirmDialog.js +27 -25
  9. package/dist/lib/ui/components/ConfirmDialog/ConfirmDialog.js.map +1 -1
  10. package/dist/lib/ui/components/DataTable/DataTable.cjs +1 -1
  11. package/dist/lib/ui/components/DataTable/DataTable.cjs.map +1 -1
  12. package/dist/lib/ui/components/DataTable/DataTable.js +210 -174
  13. package/dist/lib/ui/components/DataTable/DataTable.js.map +1 -1
  14. package/dist/lib/ui/components/FormModal/FormModal.cjs +1 -1
  15. package/dist/lib/ui/components/FormModal/FormModal.cjs.map +1 -1
  16. package/dist/lib/ui/components/FormModal/FormModal.js +22 -21
  17. package/dist/lib/ui/components/FormModal/FormModal.js.map +1 -1
  18. package/dist/lib/ui/components/LoadingOverlay/LoadingOverlay.cjs +2 -0
  19. package/dist/lib/ui/components/LoadingOverlay/LoadingOverlay.cjs.map +1 -0
  20. package/dist/lib/ui/components/LoadingOverlay/LoadingOverlay.js +36 -0
  21. package/dist/lib/ui/components/LoadingOverlay/LoadingOverlay.js.map +1 -0
  22. package/dist/lib/ui/components/PageLoadingState/PageLoadingState.cjs +2 -0
  23. package/dist/lib/ui/components/PageLoadingState/PageLoadingState.cjs.map +1 -0
  24. package/dist/lib/ui/components/PageLoadingState/PageLoadingState.js +18 -0
  25. package/dist/lib/ui/components/PageLoadingState/PageLoadingState.js.map +1 -0
  26. package/dist/lib/ui/hooks/useAnimationFrame.cjs +2 -0
  27. package/dist/lib/ui/hooks/useAnimationFrame.cjs.map +1 -0
  28. package/dist/lib/ui/hooks/useAnimationFrame.js +24 -0
  29. package/dist/lib/ui/hooks/useAnimationFrame.js.map +1 -0
  30. package/dist/lib/ui/hooks/useLoadingVisibility.cjs +2 -0
  31. package/dist/lib/ui/hooks/useLoadingVisibility.cjs.map +1 -0
  32. package/dist/lib/ui/hooks/useLoadingVisibility.js +34 -0
  33. package/dist/lib/ui/hooks/useLoadingVisibility.js.map +1 -0
  34. package/dist/lib/ui/hooks/useMediaQuery.cjs +1 -1
  35. package/dist/lib/ui/hooks/useMediaQuery.cjs.map +1 -1
  36. package/dist/lib/ui/hooks/useMediaQuery.js +5 -2
  37. package/dist/lib/ui/hooks/useMediaQuery.js.map +1 -1
  38. package/dist/lib/ui/primitives/BrandLoader/BrandLoader.cjs +2 -0
  39. package/dist/lib/ui/primitives/BrandLoader/BrandLoader.cjs.map +1 -0
  40. package/dist/lib/ui/primitives/BrandLoader/BrandLoader.js +165 -0
  41. package/dist/lib/ui/primitives/BrandLoader/BrandLoader.js.map +1 -0
  42. package/dist/lib/ui/primitives/BrandLoader/BrandLoaderProvider.cjs +2 -0
  43. package/dist/lib/ui/primitives/BrandLoader/BrandLoaderProvider.cjs.map +1 -0
  44. package/dist/lib/ui/primitives/BrandLoader/BrandLoaderProvider.js +9 -0
  45. package/dist/lib/ui/primitives/BrandLoader/BrandLoaderProvider.js.map +1 -0
  46. package/dist/lib/ui/primitives/BrandLoader/brandLoaderSymbolContext.cjs +2 -0
  47. package/dist/lib/ui/primitives/BrandLoader/brandLoaderSymbolContext.cjs.map +1 -0
  48. package/dist/lib/ui/primitives/BrandLoader/brandLoaderSymbolContext.js +10 -0
  49. package/dist/lib/ui/primitives/BrandLoader/brandLoaderSymbolContext.js.map +1 -0
  50. package/dist/lib/ui/primitives/BrandLoader/brandLoaderVariants.cjs +2 -0
  51. package/dist/lib/ui/primitives/BrandLoader/brandLoaderVariants.cjs.map +1 -0
  52. package/dist/lib/ui/primitives/BrandLoader/brandLoaderVariants.js +166 -0
  53. package/dist/lib/ui/primitives/BrandLoader/brandLoaderVariants.js.map +1 -0
  54. package/dist/lib/ui/primitives/Button/Button.cjs +1 -1
  55. package/dist/lib/ui/primitives/Button/Button.cjs.map +1 -1
  56. package/dist/lib/ui/primitives/Button/Button.js +72 -49
  57. package/dist/lib/ui/primitives/Button/Button.js.map +1 -1
  58. package/dist/lib/ui/primitives/IconButton/IconButton.cjs +1 -1
  59. package/dist/lib/ui/primitives/IconButton/IconButton.cjs.map +1 -1
  60. package/dist/lib/ui/primitives/IconButton/IconButton.js +11 -11
  61. package/dist/lib/ui/primitives/IconButton/IconButton.js.map +1 -1
  62. package/dist/lib/ui/primitives/LoadingState/LoadingState.cjs +2 -0
  63. package/dist/lib/ui/primitives/LoadingState/LoadingState.cjs.map +1 -0
  64. package/dist/lib/ui/primitives/LoadingState/LoadingState.js +33 -0
  65. package/dist/lib/ui/primitives/LoadingState/LoadingState.js.map +1 -0
  66. package/dist/lib/ui/primitives/PermissionGate/PermissionGate.cjs +1 -1
  67. package/dist/lib/ui/primitives/PermissionGate/PermissionGate.cjs.map +1 -1
  68. package/dist/lib/ui/primitives/PermissionGate/PermissionGate.js +14 -9
  69. package/dist/lib/ui/primitives/PermissionGate/PermissionGate.js.map +1 -1
  70. package/dist/lib/ui/primitives/Tree/Tree.cjs +1 -1
  71. package/dist/lib/ui/primitives/Tree/Tree.cjs.map +1 -1
  72. package/dist/lib/ui/primitives/Tree/Tree.js +31 -24
  73. package/dist/lib/ui/primitives/Tree/Tree.js.map +1 -1
  74. package/dist/types/ui/components/DataTable/DataTable.d.ts +31 -8
  75. package/dist/types/ui/components/LoadingOverlay/LoadingOverlay.d.ts +13 -0
  76. package/dist/types/ui/components/PageLoadingState/PageLoadingState.d.ts +4 -0
  77. package/dist/types/ui/components/index.d.ts +2 -1
  78. package/dist/types/ui/hooks/index.d.ts +1 -0
  79. package/dist/types/ui/hooks/useAnimationFrame.d.ts +3 -0
  80. package/dist/types/ui/hooks/useLoadingVisibility.d.ts +7 -0
  81. package/dist/types/ui/primitives/BrandLoader/BrandLoader.d.ts +25 -0
  82. package/dist/types/ui/primitives/BrandLoader/BrandLoaderProvider.d.ts +7 -0
  83. package/dist/types/ui/primitives/BrandLoader/brandLoaderSymbolContext.d.ts +3 -0
  84. package/dist/types/ui/primitives/BrandLoader/brandLoaderVariants.d.ts +33 -0
  85. package/dist/types/ui/primitives/Button/Button.d.ts +1 -0
  86. package/dist/types/ui/primitives/LoadingState/LoadingState.d.ts +10 -0
  87. package/dist/types/ui/primitives/PermissionGate/PermissionGate.d.ts +16 -6
  88. package/dist/types/ui/primitives/index.d.ts +2 -0
  89. package/package.json +1 -1
  90. package/dist/lib/ui/components/WidgetLoadingState/WidgetLoadingState.cjs +0 -2
  91. package/dist/lib/ui/components/WidgetLoadingState/WidgetLoadingState.cjs.map +0 -1
  92. package/dist/lib/ui/components/WidgetLoadingState/WidgetLoadingState.js +0 -27
  93. package/dist/lib/ui/components/WidgetLoadingState/WidgetLoadingState.js.map +0 -1
  94. package/dist/types/ui/components/WidgetLoadingState/WidgetLoadingState.d.ts +0 -6
@@ -0,0 +1,33 @@
1
+ import { jsx as i, jsxs as l, Fragment as d } from "react/jsx-runtime";
2
+ import { clsx as m } from "../../../vendor/clsx/dist/clsx.js";
3
+ import { BrandLoader as c } from "../BrandLoader/BrandLoader.js";
4
+ /* empty css */
5
+ import { useLoadingVisibility as p, defaultLoadingDelayMs as u } from "../../hooks/useLoadingVisibility.js";
6
+ function L({
7
+ message: a,
8
+ variant: e = "trace",
9
+ size: r = "32",
10
+ delayMs: t = u,
11
+ className: o,
12
+ ...s
13
+ }) {
14
+ const n = p(!0, { delayMs: t, minVisibleMs: 0 });
15
+ return /* @__PURE__ */ i(
16
+ "div",
17
+ {
18
+ role: "status",
19
+ "aria-live": "polite",
20
+ "aria-label": a,
21
+ className: m("loading-state", o),
22
+ ...s,
23
+ children: n && /* @__PURE__ */ l(d, { children: [
24
+ /* @__PURE__ */ i(c, { "aria-hidden": !0, variant: e, size: r, tone: "brand" }),
25
+ /* @__PURE__ */ i("span", { className: "loading-state-message", children: a })
26
+ ] })
27
+ }
28
+ );
29
+ }
30
+ export {
31
+ L as LoadingState
32
+ };
33
+ //# sourceMappingURL=LoadingState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoadingState.js","sources":["../../../../../src/ui/primitives/LoadingState/LoadingState.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { defaultLoadingDelayMs, useLoadingVisibility } from \"hooks\";\nimport { type ComponentPropsWithoutRef } from \"react\";\nimport {\n BrandLoader,\n type BrandLoaderSize,\n type BrandLoaderVariant,\n} from \"../BrandLoader/BrandLoader\";\nimport \"./loading-state.css\";\n\nexport type LoadingStateProps = ComponentPropsWithoutRef<\"div\"> & {\n message: string;\n variant?: BrandLoaderVariant;\n size?: BrandLoaderSize;\n delayMs?: number;\n};\n\nexport function LoadingState({\n message,\n variant = \"trace\",\n size = \"32\",\n delayMs = defaultLoadingDelayMs,\n className,\n ...props\n}: LoadingStateProps) {\n const isVisible = useLoadingVisibility(true, { delayMs, minVisibleMs: 0 });\n\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n aria-label={message}\n className={clsx(\"loading-state\", className)}\n {...props}\n >\n {isVisible && (\n <>\n <BrandLoader aria-hidden variant={variant} size={size} tone=\"brand\" />\n <span className=\"loading-state-message\">{message}</span>\n </>\n )}\n </div>\n );\n}\n"],"names":["LoadingState","message","variant","size","delayMs","defaultLoadingDelayMs","className","props","isVisible","useLoadingVisibility","jsx","clsx","jsxs","Fragment","BrandLoader"],"mappings":";;;;;AAiBO,SAASA,EAAa;AAAA,EAC3B,SAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAUC;AAAA,EACV,WAAAC;AAAA,EACA,GAAGC;AACL,GAAsB;AACpB,QAAMC,IAAYC,EAAqB,IAAM,EAAE,SAAAL,GAAS,cAAc,GAAG;AAEzE,SACE,gBAAAM;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,aAAU;AAAA,MACV,cAAYT;AAAA,MACZ,WAAWU,EAAK,iBAAiBL,CAAS;AAAA,MACzC,GAAGC;AAAA,MAEH,eACC,gBAAAK,EAAAC,GAAA,EACE,UAAA;AAAA,QAAA,gBAAAH,EAACI,KAAY,eAAW,IAAC,SAAAZ,GAAkB,MAAAC,GAAY,MAAK,SAAQ;AAAA,QACpE,gBAAAO,EAAC,QAAA,EAAK,WAAU,yBAAyB,UAAAT,EAAA,CAAQ;AAAA,MAAA,EAAA,CACnD;AAAA,IAAA;AAAA,EAAA;AAIR;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),r=require("../Tooltip/Tooltip.cjs");function s({isAllowed:t,noAccessLabel:o,children:e}){const n=typeof e=="function"?e(t):e;return t?n:i.jsx(r.Tooltip,{content:o,trigger:"hover",placement:"top",offset:4,children:i.jsx("span",{style:{display:"inline-flex"},children:n})})}exports.PermissionGate=s;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("react/jsx-runtime"),u=require("../Tooltip/Tooltip.cjs");function a({isAllowed:s,noAccessLabel:l,isPending:t=!1,pendingLabel:c,children:e}){const r=s&&!t,o=typeof e=="function"?e(r,t):e;if(r)return o;const n=t?c:l;return n?i.jsx(u.Tooltip,{content:n,trigger:"hover",placement:"top",offset:4,children:i.jsx("span",{style:{display:"inline-flex"},children:o})}):o}exports.PermissionGate=a;
2
2
  //# sourceMappingURL=PermissionGate.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionGate.cjs","sources":["../../../../../src/ui/primitives/PermissionGate/PermissionGate.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\nexport interface PermissionGateProps {\n /** Whether the current user has permission to perform this action. */\n isAllowed: boolean;\n /** Tooltip text shown when the action is not allowed. */\n noAccessLabel: string;\n /**\n * Either a React element or a render prop that receives `isAllowed`.\n * Use the render prop to avoid repeating the permission check inside the child.\n */\n children: React.ReactElement | ((isAllowed: boolean) => React.ReactElement);\n}\n\n/**\n * Wraps any interactive element with a tooltip that appears when `isAllowed` is false.\n *\n * When allowed, renders the trigger directly with no wrapper.\n * When not allowed, wraps in a DS Tooltip with hover trigger.\n * A `<span>` wrapper ensures disabled elements still receive pointer events.\n *\n * Dentro de coleções do react-aria-components (`Menu`, `ListBox`, `Table`,\n * `Tree`) o gate vai NO CONTEÚDO do nó, nunca em volta dele:\n *\n * ```tsx\n * // ERRADO — o react-aria descarta esse item e os seguintes, e o menu abre\n * // vazio se ele for o primeiro. Sem erro no console.\n * <PermissionGate …><MenuItem>…</MenuItem></PermissionGate>\n *\n * // CERTO\n * <MenuItem isDisabled={!allowed}>\n * <PermissionGate …><span>…</span></PermissionGate>\n * </MenuItem>\n * ```\n *\n * O collection builder só reconhece nós de coleção; o `<span>` do ramo negado\n * entra na coleção com `node` nulo e quebra a lista encadeada de chaves. Já o\n * conteúdo de um nó é renderizado no DOM real, fora da coleção, e por isso é\n * seguro — é onde o `DataTable` põe o gate nas ações de linha. O `Menu` avisa no\n * console em desenvolvimento se o gate aparecer em volta de um item.\n */\nexport function PermissionGate({\n isAllowed,\n noAccessLabel,\n children,\n}: PermissionGateProps) {\n const trigger =\n typeof children === \"function\" ? children(isAllowed) : children;\n\n if (isAllowed) {\n return trigger;\n }\n\n return (\n <Tooltip content={noAccessLabel} trigger=\"hover\" placement=\"top\" offset={4}>\n <span style={{ display: \"inline-flex\" }}>{trigger}</span>\n </Tooltip>\n );\n}\n"],"names":["PermissionGate","isAllowed","noAccessLabel","children","trigger","Tooltip","jsx"],"mappings":"yJA0CO,SAASA,EAAe,CAC7B,UAAAC,EACA,cAAAC,EACA,SAAAC,CACF,EAAwB,CACtB,MAAMC,EACJ,OAAOD,GAAa,WAAaA,EAASF,CAAS,EAAIE,EAEzD,OAAIF,EACKG,QAINC,UAAA,CAAQ,QAASH,EAAe,QAAQ,QAAQ,UAAU,MAAM,OAAQ,EACvE,SAAAI,MAAC,QAAK,MAAO,CAAE,QAAS,aAAA,EAAkB,WAAQ,EACpD,CAEJ"}
1
+ {"version":3,"file":"PermissionGate.cjs","sources":["../../../../../src/ui/primitives/PermissionGate/PermissionGate.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\ntype PermissionGatePendingProps =\n | { isPending?: false; pendingLabel?: string }\n | {\n isPending: boolean;\n /** Tooltip text shown while `isPending`. */\n pendingLabel: string;\n };\n\nexport type PermissionGateProps = PermissionGatePendingProps & {\n /** Whether the current user has permission to perform this action. */\n isAllowed: boolean;\n /** Tooltip text shown when the action is not allowed. */\n noAccessLabel: string;\n /**\n * Either a React element or a render prop that receives `isAllowed` and `isPending`.\n * Use the render prop to avoid repeating the permission check inside the child, e.g.\n * `{(allowed, pending) => <Button isDisabled={!allowed && !pending} isPending={pending}>…</Button>}`.\n */\n children:\n | React.ReactElement\n | ((isAllowed: boolean, isPending: boolean) => React.ReactElement);\n};\n\n/**\n * Wraps any interactive element with a tooltip that appears when `isAllowed` is false.\n *\n * When allowed, renders the trigger directly with no wrapper.\n * When not allowed, wraps in a DS Tooltip with hover trigger.\n * A `<span>` wrapper ensures disabled elements still receive pointer events.\n *\n * Dentro de coleções do react-aria-components (`Menu`, `ListBox`, `Table`,\n * `Tree`) o gate vai NO CONTEÚDO do nó, nunca em volta dele:\n *\n * ```tsx\n * // ERRADO — o react-aria descarta esse item e os seguintes, e o menu abre\n * // vazio se ele for o primeiro. Sem erro no console.\n * <PermissionGate …><MenuItem>…</MenuItem></PermissionGate>\n *\n * // CERTO\n * <MenuItem isDisabled={!allowed}>\n * <PermissionGate …><span>…</span></PermissionGate>\n * </MenuItem>\n * ```\n *\n * O collection builder só reconhece nós de coleção; o `<span>` do ramo negado\n * entra na coleção com `node` nulo e quebra a lista encadeada de chaves. Já o\n * conteúdo de um nó é renderizado no DOM real, fora da coleção, e por isso é\n * seguro — é onde o `DataTable` põe o gate nas ações de linha. O `Menu` avisa no\n * console em desenvolvimento se o gate aparecer em volta de um item.\n */\nexport function PermissionGate({\n isAllowed,\n noAccessLabel,\n isPending = false,\n pendingLabel,\n children,\n}: PermissionGateProps) {\n const isGranted = isAllowed && !isPending;\n const trigger =\n typeof children === \"function\" ? children(isGranted, isPending) : children;\n\n if (isGranted) {\n return trigger;\n }\n\n const tooltipLabel = isPending ? pendingLabel : noAccessLabel;\n if (!tooltipLabel) {\n return trigger;\n }\n\n return (\n <Tooltip content={tooltipLabel} trigger=\"hover\" placement=\"top\" offset={4}>\n <span style={{ display: \"inline-flex\" }}>{trigger}</span>\n </Tooltip>\n );\n}\n"],"names":["PermissionGate","isAllowed","noAccessLabel","isPending","pendingLabel","children","isGranted","trigger","tooltipLabel","Tooltip","jsx"],"mappings":"yJAqDO,SAASA,EAAe,CAC7B,UAAAC,EACA,cAAAC,EACA,UAAAC,EAAY,GACZ,aAAAC,EACA,SAAAC,CACF,EAAwB,CACtB,MAAMC,EAAYL,GAAa,CAACE,EAC1BI,EACJ,OAAOF,GAAa,WAAaA,EAASC,EAAWH,CAAS,EAAIE,EAEpE,GAAIC,EACF,OAAOC,EAGT,MAAMC,EAAeL,EAAYC,EAAeF,EAChD,OAAKM,QAKFC,UAAA,CAAQ,QAASD,EAAc,QAAQ,QAAQ,UAAU,MAAM,OAAQ,EACtE,SAAAE,MAAC,QAAK,MAAO,CAAE,QAAS,aAAA,EAAkB,WAAQ,EACpD,EANOH,CAQX"}
@@ -1,14 +1,19 @@
1
- import { jsx as r } from "react/jsx-runtime";
2
- import { Tooltip as i } from "../Tooltip/Tooltip.js";
3
- function s({
4
- isAllowed: e,
5
- noAccessLabel: n,
6
- children: t
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ import { Tooltip as l } from "../Tooltip/Tooltip.js";
3
+ function m({
4
+ isAllowed: f,
5
+ noAccessLabel: p,
6
+ isPending: t = !1,
7
+ pendingLabel: s,
8
+ children: o
7
9
  }) {
8
- const o = typeof t == "function" ? t(e) : t;
9
- return e ? o : /* @__PURE__ */ r(i, { content: n, trigger: "hover", placement: "top", offset: 4, children: /* @__PURE__ */ r("span", { style: { display: "inline-flex" }, children: o }) });
10
+ const r = f && !t, e = typeof o == "function" ? o(r, t) : o;
11
+ if (r)
12
+ return e;
13
+ const n = t ? s : p;
14
+ return n ? /* @__PURE__ */ i(l, { content: n, trigger: "hover", placement: "top", offset: 4, children: /* @__PURE__ */ i("span", { style: { display: "inline-flex" }, children: e }) }) : e;
10
15
  }
11
16
  export {
12
- s as PermissionGate
17
+ m as PermissionGate
13
18
  };
14
19
  //# sourceMappingURL=PermissionGate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PermissionGate.js","sources":["../../../../../src/ui/primitives/PermissionGate/PermissionGate.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\nexport interface PermissionGateProps {\n /** Whether the current user has permission to perform this action. */\n isAllowed: boolean;\n /** Tooltip text shown when the action is not allowed. */\n noAccessLabel: string;\n /**\n * Either a React element or a render prop that receives `isAllowed`.\n * Use the render prop to avoid repeating the permission check inside the child.\n */\n children: React.ReactElement | ((isAllowed: boolean) => React.ReactElement);\n}\n\n/**\n * Wraps any interactive element with a tooltip that appears when `isAllowed` is false.\n *\n * When allowed, renders the trigger directly with no wrapper.\n * When not allowed, wraps in a DS Tooltip with hover trigger.\n * A `<span>` wrapper ensures disabled elements still receive pointer events.\n *\n * Dentro de coleções do react-aria-components (`Menu`, `ListBox`, `Table`,\n * `Tree`) o gate vai NO CONTEÚDO do nó, nunca em volta dele:\n *\n * ```tsx\n * // ERRADO — o react-aria descarta esse item e os seguintes, e o menu abre\n * // vazio se ele for o primeiro. Sem erro no console.\n * <PermissionGate …><MenuItem>…</MenuItem></PermissionGate>\n *\n * // CERTO\n * <MenuItem isDisabled={!allowed}>\n * <PermissionGate …><span>…</span></PermissionGate>\n * </MenuItem>\n * ```\n *\n * O collection builder só reconhece nós de coleção; o `<span>` do ramo negado\n * entra na coleção com `node` nulo e quebra a lista encadeada de chaves. Já o\n * conteúdo de um nó é renderizado no DOM real, fora da coleção, e por isso é\n * seguro — é onde o `DataTable` põe o gate nas ações de linha. O `Menu` avisa no\n * console em desenvolvimento se o gate aparecer em volta de um item.\n */\nexport function PermissionGate({\n isAllowed,\n noAccessLabel,\n children,\n}: PermissionGateProps) {\n const trigger =\n typeof children === \"function\" ? children(isAllowed) : children;\n\n if (isAllowed) {\n return trigger;\n }\n\n return (\n <Tooltip content={noAccessLabel} trigger=\"hover\" placement=\"top\" offset={4}>\n <span style={{ display: \"inline-flex\" }}>{trigger}</span>\n </Tooltip>\n );\n}\n"],"names":["PermissionGate","isAllowed","noAccessLabel","children","trigger","Tooltip","jsx"],"mappings":";;AA0CO,SAASA,EAAe;AAAA,EAC7B,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,UAAAC;AACF,GAAwB;AACtB,QAAMC,IACJ,OAAOD,KAAa,aAAaA,EAASF,CAAS,IAAIE;AAEzD,SAAIF,IACKG,sBAINC,GAAA,EAAQ,SAASH,GAAe,SAAQ,SAAQ,WAAU,OAAM,QAAQ,GACvE,UAAA,gBAAAI,EAAC,UAAK,OAAO,EAAE,SAAS,cAAA,GAAkB,aAAQ,GACpD;AAEJ;"}
1
+ {"version":3,"file":"PermissionGate.js","sources":["../../../../../src/ui/primitives/PermissionGate/PermissionGate.tsx"],"sourcesContent":["import React from \"react\";\nimport { Tooltip } from \"../Tooltip/Tooltip\";\n\ntype PermissionGatePendingProps =\n | { isPending?: false; pendingLabel?: string }\n | {\n isPending: boolean;\n /** Tooltip text shown while `isPending`. */\n pendingLabel: string;\n };\n\nexport type PermissionGateProps = PermissionGatePendingProps & {\n /** Whether the current user has permission to perform this action. */\n isAllowed: boolean;\n /** Tooltip text shown when the action is not allowed. */\n noAccessLabel: string;\n /**\n * Either a React element or a render prop that receives `isAllowed` and `isPending`.\n * Use the render prop to avoid repeating the permission check inside the child, e.g.\n * `{(allowed, pending) => <Button isDisabled={!allowed && !pending} isPending={pending}>…</Button>}`.\n */\n children:\n | React.ReactElement\n | ((isAllowed: boolean, isPending: boolean) => React.ReactElement);\n};\n\n/**\n * Wraps any interactive element with a tooltip that appears when `isAllowed` is false.\n *\n * When allowed, renders the trigger directly with no wrapper.\n * When not allowed, wraps in a DS Tooltip with hover trigger.\n * A `<span>` wrapper ensures disabled elements still receive pointer events.\n *\n * Dentro de coleções do react-aria-components (`Menu`, `ListBox`, `Table`,\n * `Tree`) o gate vai NO CONTEÚDO do nó, nunca em volta dele:\n *\n * ```tsx\n * // ERRADO — o react-aria descarta esse item e os seguintes, e o menu abre\n * // vazio se ele for o primeiro. Sem erro no console.\n * <PermissionGate …><MenuItem>…</MenuItem></PermissionGate>\n *\n * // CERTO\n * <MenuItem isDisabled={!allowed}>\n * <PermissionGate …><span>…</span></PermissionGate>\n * </MenuItem>\n * ```\n *\n * O collection builder só reconhece nós de coleção; o `<span>` do ramo negado\n * entra na coleção com `node` nulo e quebra a lista encadeada de chaves. Já o\n * conteúdo de um nó é renderizado no DOM real, fora da coleção, e por isso é\n * seguro — é onde o `DataTable` põe o gate nas ações de linha. O `Menu` avisa no\n * console em desenvolvimento se o gate aparecer em volta de um item.\n */\nexport function PermissionGate({\n isAllowed,\n noAccessLabel,\n isPending = false,\n pendingLabel,\n children,\n}: PermissionGateProps) {\n const isGranted = isAllowed && !isPending;\n const trigger =\n typeof children === \"function\" ? children(isGranted, isPending) : children;\n\n if (isGranted) {\n return trigger;\n }\n\n const tooltipLabel = isPending ? pendingLabel : noAccessLabel;\n if (!tooltipLabel) {\n return trigger;\n }\n\n return (\n <Tooltip content={tooltipLabel} trigger=\"hover\" placement=\"top\" offset={4}>\n <span style={{ display: \"inline-flex\" }}>{trigger}</span>\n </Tooltip>\n );\n}\n"],"names":["PermissionGate","isAllowed","noAccessLabel","isPending","pendingLabel","children","isGranted","trigger","tooltipLabel","Tooltip","jsx"],"mappings":";;AAqDO,SAASA,EAAe;AAAA,EAC7B,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,WAAAC,IAAY;AAAA,EACZ,cAAAC;AAAA,EACA,UAAAC;AACF,GAAwB;AACtB,QAAMC,IAAYL,KAAa,CAACE,GAC1BI,IACJ,OAAOF,KAAa,aAAaA,EAASC,GAAWH,CAAS,IAAIE;AAEpE,MAAIC;AACF,WAAOC;AAGT,QAAMC,IAAeL,IAAYC,IAAeF;AAChD,SAAKM,sBAKFC,GAAA,EAAQ,SAASD,GAAc,SAAQ,SAAQ,WAAU,OAAM,QAAQ,GACtE,UAAA,gBAAAE,EAAC,UAAK,OAAO,EAAE,SAAS,cAAA,GAAkB,aAAQ,GACpD,IANOH;AAQX;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("../../../vendor/clsx/dist/clsx.cjs"),i=require("react-aria-components");;/* empty css */const x=require("../../icons/IconLoader.cjs"),d=require("../../icons/IconChevronRight.cjs");function j(t){return t.hasChildItems??!!(t.children&&t.children.length>0)}function C({className:t,items:s,renderItem:n,isNodeLoading:l,onItemAction:c,dependencies:a,...u}){function h(r){return e.jsxs(i.TreeItem,{id:r.id,textValue:r.label,hasChildItems:j(r),className:"tree-item",onAction:c?()=>c(r):void 0,children:[e.jsx(m,{children:n(r)}),r.children&&r.children.length>0&&e.jsx(i.Collection,{items:r.children,dependencies:a,children:h}),((l==null?void 0:l(r.id))??!1)&&e.jsx(i.TreeItem,{id:`${r.id}::loading`,textValue:"Loading",isDisabled:!0,className:"tree-item",children:e.jsx(m,{children:e.jsx(x.IconLoader,{size:"16",className:"tree-item-loading-icon"})})})]})}return e.jsx(i.Tree,{items:s,className:o.clsx(t,"tree"),dependencies:a,...u,children:h})}function m({children:t}){return e.jsx(i.TreeItemContent,{children:({hasChildItems:s,level:n})=>e.jsxs("div",{className:"tree-item-row",style:{"--tree-item-depth":n-1},children:[s?e.jsx(i.Button,{slot:"chevron",className:"tree-item-chevron",children:e.jsx(d.IconChevronRight,{size:"16"})}):e.jsx("span",{className:"tree-item-chevron-spacer","aria-hidden":"true"}),t]})})}exports.Tree=C;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),j=require("../../../vendor/clsx/dist/clsx.cjs"),s=require("react-aria-components");;/* empty css */const p=require("../BrandLoader/BrandLoader.cjs"),f=require("../../icons/IconChevronRight.cjs");function v(t){return t.hasChildItems??!!(t.children&&t.children.length>0)}function u(t,n){return t.flatMap(i=>[...n(i.id)?[i.id]:[],...u(i.children??[],n)])}function C({className:t,items:n,renderItem:i,isNodeLoading:c,onItemAction:l,dependencies:m,...o}){const x=c?JSON.stringify(u(n,c)):"",a=[...m??[],x];function h(r){return e.jsxs(s.TreeItem,{id:r.id,textValue:r.label,hasChildItems:v(r),className:"tree-item",onAction:l?()=>l(r):void 0,children:[e.jsx(d,{children:i(r)}),r.children&&r.children.length>0&&e.jsx(s.Collection,{items:r.children,dependencies:a,children:h}),((c==null?void 0:c(r.id))??!1)&&e.jsx(s.TreeItem,{id:`${r.id}::loading`,textValue:"Loading",isDisabled:!0,className:"tree-item",children:e.jsx(d,{children:e.jsx(p.BrandLoader,{"aria-hidden":!0,variant:"pulse",size:"16",tone:"brand"})})})]})}return e.jsx(s.Tree,{items:n,className:j.clsx(t,"tree"),dependencies:a,...o,children:h})}function d({children:t}){return e.jsx(s.TreeItemContent,{children:({hasChildItems:n,level:i})=>e.jsxs("div",{className:"tree-item-row",style:{"--tree-item-depth":i-1},children:[n?e.jsx(s.Button,{slot:"chevron",className:"tree-item-chevron",children:e.jsx(f.IconChevronRight,{size:"16"})}):e.jsx("span",{className:"tree-item-chevron-spacer","aria-hidden":"true"}),t]})})}exports.Tree=C;
2
2
  //# sourceMappingURL=Tree.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.cjs","sources":["../../../../../src/ui/primitives/Tree/Tree.tsx"],"sourcesContent":["import type { CSSProperties, Key, ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { IconChevronRight, IconLoader } from \"icons\";\nimport {\n Button,\n Collection,\n Tree as RACTree,\n TreeItem as RACTreeItem,\n TreeItemContent as RACTreeItemContent,\n type TreeProps as RACTreeProps,\n} from \"react-aria-components\";\nimport \"./tree.css\";\n\nexport interface TreeNode<T = unknown> {\n id: string;\n label: string;\n data?: T;\n /** Signals a node has children before they are fetched, so the chevron renders ahead of a lazy load. */\n hasChildItems?: boolean;\n /** `undefined` = not loaded yet, `[]` = loaded and empty. */\n children?: TreeNode<T>[];\n}\n\nexport type TreeProps<T> = Omit<\n RACTreeProps<TreeNode<T>>,\n \"children\" | \"items\"\n> & {\n items: TreeNode<T>[];\n renderItem: (node: TreeNode<T>) => ReactNode;\n isNodeLoading?: (id: Key) => boolean;\n onItemAction?: (node: TreeNode<T>) => void;\n};\n\nfunction hasExpandableChildren<T>(node: TreeNode<T>): boolean {\n return node.hasChildItems ?? Boolean(node.children && node.children.length > 0);\n}\n\nexport function Tree<T>({\n className,\n items,\n renderItem,\n isNodeLoading,\n onItemAction,\n dependencies,\n ...props\n}: TreeProps<T>) {\n function renderNode(node: TreeNode<T>): ReactNode {\n return (\n <RACTreeItem\n id={node.id}\n textValue={node.label}\n hasChildItems={hasExpandableChildren(node)}\n className=\"tree-item\"\n onAction={onItemAction ? () => onItemAction(node) : undefined}\n >\n <TreeItemContent>{renderItem(node)}</TreeItemContent>\n {node.children && node.children.length > 0 && (\n <Collection items={node.children} dependencies={dependencies}>\n {renderNode}\n </Collection>\n )}\n {(isNodeLoading?.(node.id) ?? false) && (\n <RACTreeItem id={`${node.id}::loading`} textValue=\"Loading\" isDisabled className=\"tree-item\">\n <TreeItemContent>\n <IconLoader size=\"16\" className=\"tree-item-loading-icon\" />\n </TreeItemContent>\n </RACTreeItem>\n )}\n </RACTreeItem>\n );\n }\n\n return (\n <RACTree items={items} className={clsx(className, \"tree\")} dependencies={dependencies} {...props}>\n {renderNode}\n </RACTree>\n );\n}\n\ninterface TreeItemContentProps {\n children: ReactNode;\n}\n\nfunction TreeItemContent({ children }: TreeItemContentProps) {\n return (\n <RACTreeItemContent>\n {({ hasChildItems, level }) => (\n <div\n className=\"tree-item-row\"\n style={{ \"--tree-item-depth\": level - 1 } as CSSProperties}\n >\n {hasChildItems ? (\n <Button slot=\"chevron\" className=\"tree-item-chevron\">\n <IconChevronRight size=\"16\" />\n </Button>\n ) : (\n <span className=\"tree-item-chevron-spacer\" aria-hidden=\"true\" />\n )}\n {children}\n </div>\n )}\n </RACTreeItemContent>\n );\n}\n"],"names":["hasExpandableChildren","node","Tree","className","items","renderItem","isNodeLoading","onItemAction","dependencies","props","renderNode","jsxs","RACTreeItem","jsx","TreeItemContent","Collection","IconLoader","RACTree","clsx","children","RACTreeItemContent","hasChildItems","level","Button","IconChevronRight"],"mappings":"8TAiCA,SAASA,EAAyBC,EAA4B,CAC5D,OAAOA,EAAK,eAAiB,GAAQA,EAAK,UAAYA,EAAK,SAAS,OAAS,EAC/E,CAEO,SAASC,EAAQ,CACtB,UAAAC,EACA,MAAAC,EACA,WAAAC,EACA,cAAAC,EACA,aAAAC,EACA,aAAAC,EACA,GAAGC,CACL,EAAiB,CACf,SAASC,EAAWT,EAA8B,CAChD,OACEU,EAAAA,KAACC,EAAAA,SAAA,CACC,GAAIX,EAAK,GACT,UAAWA,EAAK,MAChB,cAAeD,EAAsBC,CAAI,EACzC,UAAU,YACV,SAAUM,EAAe,IAAMA,EAAaN,CAAI,EAAI,OAEpD,SAAA,CAAAY,EAAAA,IAACC,EAAA,CAAiB,SAAAT,EAAWJ,CAAI,CAAA,CAAE,EAClCA,EAAK,UAAYA,EAAK,SAAS,OAAS,GACvCY,EAAAA,IAACE,EAAAA,WAAA,CAAW,MAAOd,EAAK,SAAU,aAAAO,EAC/B,SAAAE,EACH,IAEAJ,GAAA,YAAAA,EAAgBL,EAAK,MAAO,KAC5BY,EAAAA,IAACD,EAAAA,SAAA,CAAY,GAAI,GAAGX,EAAK,EAAE,YAAa,UAAU,UAAU,WAAU,GAAC,UAAU,YAC/E,SAAAY,EAAAA,IAACC,EAAA,CACC,SAAAD,EAAAA,IAACG,EAAAA,WAAA,CAAW,KAAK,KAAK,UAAU,wBAAA,CAAyB,CAAA,CAC3D,CAAA,CACF,CAAA,CAAA,CAAA,CAIR,CAEA,OACEH,EAAAA,IAACI,EAAAA,KAAA,CAAQ,MAAAb,EAAc,UAAWc,EAAAA,KAAKf,EAAW,MAAM,EAAG,aAAAK,EAA6B,GAAGC,EACxF,SAAAC,CAAA,CACH,CAEJ,CAMA,SAASI,EAAgB,CAAE,SAAAK,GAAkC,CAC3D,aACGC,EAAAA,gBAAA,CACE,SAAA,CAAC,CAAE,cAAAC,EAAe,MAAAC,KACjBX,EAAAA,KAAC,MAAA,CACC,UAAU,gBACV,MAAO,CAAE,oBAAqBW,EAAQ,CAAA,EAErC,SAAA,CAAAD,QACEE,EAAAA,OAAA,CAAO,KAAK,UAAU,UAAU,oBAC/B,SAAAV,EAAAA,IAACW,EAAAA,iBAAA,CAAiB,KAAK,IAAA,CAAK,EAC9B,EAEAX,MAAC,QAAK,UAAU,2BAA2B,cAAY,OAAO,EAE/DM,CAAA,CAAA,CAAA,EAGP,CAEJ"}
1
+ {"version":3,"file":"Tree.cjs","sources":["../../../../../src/ui/primitives/Tree/Tree.tsx"],"sourcesContent":["import type { CSSProperties, Key, ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { IconChevronRight } from \"icons\";\nimport { BrandLoader } from \"primitives\";\nimport {\n Button,\n Collection,\n Tree as RACTree,\n TreeItem as RACTreeItem,\n TreeItemContent as RACTreeItemContent,\n type TreeProps as RACTreeProps,\n} from \"react-aria-components\";\nimport \"./tree.css\";\n\nexport interface TreeNode<T = unknown> {\n id: string;\n label: string;\n data?: T;\n /** Signals a node has children before they are fetched, so the chevron renders ahead of a lazy load. */\n hasChildItems?: boolean;\n /** `undefined` = not loaded yet, `[]` = loaded and empty. */\n children?: TreeNode<T>[];\n}\n\nexport type TreeProps<T> = Omit<\n RACTreeProps<TreeNode<T>>,\n \"children\" | \"items\"\n> & {\n items: TreeNode<T>[];\n renderItem: (node: TreeNode<T>) => ReactNode;\n isNodeLoading?: (id: Key) => boolean;\n onItemAction?: (node: TreeNode<T>) => void;\n};\n\nfunction hasExpandableChildren<T>(node: TreeNode<T>): boolean {\n return node.hasChildItems ?? Boolean(node.children && node.children.length > 0);\n}\n\nfunction loadingNodeIdsOf<T>(nodes: TreeNode<T>[], isNodeLoading: (id: Key) => boolean): string[] {\n return nodes.flatMap((node) => [\n ...(isNodeLoading(node.id) ? [node.id] : []),\n ...loadingNodeIdsOf(node.children ?? [], isNodeLoading),\n ]);\n}\n\nexport function Tree<T>({\n className,\n items,\n renderItem,\n isNodeLoading,\n onItemAction,\n dependencies,\n ...props\n}: TreeProps<T>) {\n const loadingNodesSignature = isNodeLoading\n ? JSON.stringify(loadingNodeIdsOf(items, isNodeLoading))\n : \"\";\n const itemDependencies = [...(dependencies ?? []), loadingNodesSignature];\n\n function renderNode(node: TreeNode<T>): ReactNode {\n return (\n <RACTreeItem\n id={node.id}\n textValue={node.label}\n hasChildItems={hasExpandableChildren(node)}\n className=\"tree-item\"\n onAction={onItemAction ? () => onItemAction(node) : undefined}\n >\n <TreeItemContent>{renderItem(node)}</TreeItemContent>\n {node.children && node.children.length > 0 && (\n <Collection items={node.children} dependencies={itemDependencies}>\n {renderNode}\n </Collection>\n )}\n {(isNodeLoading?.(node.id) ?? false) && (\n <RACTreeItem id={`${node.id}::loading`} textValue=\"Loading\" isDisabled className=\"tree-item\">\n <TreeItemContent>\n <BrandLoader aria-hidden variant=\"pulse\" size=\"16\" tone=\"brand\" />\n </TreeItemContent>\n </RACTreeItem>\n )}\n </RACTreeItem>\n );\n }\n\n return (\n <RACTree items={items} className={clsx(className, \"tree\")} dependencies={itemDependencies} {...props}>\n {renderNode}\n </RACTree>\n );\n}\n\ninterface TreeItemContentProps {\n children: ReactNode;\n}\n\nfunction TreeItemContent({ children }: TreeItemContentProps) {\n return (\n <RACTreeItemContent>\n {({ hasChildItems, level }) => (\n <div\n className=\"tree-item-row\"\n style={{ \"--tree-item-depth\": level - 1 } as CSSProperties}\n >\n {hasChildItems ? (\n <Button slot=\"chevron\" className=\"tree-item-chevron\">\n <IconChevronRight size=\"16\" />\n </Button>\n ) : (\n <span className=\"tree-item-chevron-spacer\" aria-hidden=\"true\" />\n )}\n {children}\n </div>\n )}\n </RACTreeItemContent>\n );\n}\n"],"names":["hasExpandableChildren","node","loadingNodeIdsOf","nodes","isNodeLoading","Tree","className","items","renderItem","onItemAction","dependencies","props","loadingNodesSignature","itemDependencies","renderNode","jsxs","RACTreeItem","jsx","TreeItemContent","Collection","BrandLoader","RACTree","clsx","children","RACTreeItemContent","hasChildItems","level","Button","IconChevronRight"],"mappings":"kUAkCA,SAASA,EAAyBC,EAA4B,CAC5D,OAAOA,EAAK,eAAiB,GAAQA,EAAK,UAAYA,EAAK,SAAS,OAAS,EAC/E,CAEA,SAASC,EAAoBC,EAAsBC,EAA+C,CAChG,OAAOD,EAAM,QAASF,GAAS,CAC7B,GAAIG,EAAcH,EAAK,EAAE,EAAI,CAACA,EAAK,EAAE,EAAI,CAAA,EACzC,GAAGC,EAAiBD,EAAK,UAAY,CAAA,EAAIG,CAAa,CAAA,CACvD,CACH,CAEO,SAASC,EAAQ,CACtB,UAAAC,EACA,MAAAC,EACA,WAAAC,EACA,cAAAJ,EACA,aAAAK,EACA,aAAAC,EACA,GAAGC,CACL,EAAiB,CACf,MAAMC,EAAwBR,EAC1B,KAAK,UAAUF,EAAiBK,EAAOH,CAAa,CAAC,EACrD,GACES,EAAmB,CAAC,GAAIH,GAAgB,CAAA,EAAKE,CAAqB,EAExE,SAASE,EAAWb,EAA8B,CAChD,OACEc,EAAAA,KAACC,EAAAA,SAAA,CACC,GAAIf,EAAK,GACT,UAAWA,EAAK,MAChB,cAAeD,EAAsBC,CAAI,EACzC,UAAU,YACV,SAAUQ,EAAe,IAAMA,EAAaR,CAAI,EAAI,OAEpD,SAAA,CAAAgB,EAAAA,IAACC,EAAA,CAAiB,SAAAV,EAAWP,CAAI,CAAA,CAAE,EAClCA,EAAK,UAAYA,EAAK,SAAS,OAAS,GACvCgB,MAACE,EAAAA,WAAA,CAAW,MAAOlB,EAAK,SAAU,aAAcY,EAC7C,SAAAC,EACH,IAEAV,GAAA,YAAAA,EAAgBH,EAAK,MAAO,KAC5BgB,EAAAA,IAACD,EAAAA,SAAA,CAAY,GAAI,GAAGf,EAAK,EAAE,YAAa,UAAU,UAAU,WAAU,GAAC,UAAU,YAC/E,SAAAgB,EAAAA,IAACC,EAAA,CACC,SAAAD,EAAAA,IAACG,EAAAA,aAAY,cAAW,GAAC,QAAQ,QAAQ,KAAK,KAAK,KAAK,OAAA,CAAQ,EAClE,CAAA,CACF,CAAA,CAAA,CAAA,CAIR,CAEA,OACEH,EAAAA,IAACI,EAAAA,KAAA,CAAQ,MAAAd,EAAc,UAAWe,EAAAA,KAAKhB,EAAW,MAAM,EAAG,aAAcO,EAAmB,GAAGF,EAC5F,SAAAG,CAAA,CACH,CAEJ,CAMA,SAASI,EAAgB,CAAE,SAAAK,GAAkC,CAC3D,aACGC,EAAAA,gBAAA,CACE,SAAA,CAAC,CAAE,cAAAC,EAAe,MAAAC,KACjBX,EAAAA,KAAC,MAAA,CACC,UAAU,gBACV,MAAO,CAAE,oBAAqBW,EAAQ,CAAA,EAErC,SAAA,CAAAD,QACEE,EAAAA,OAAA,CAAO,KAAK,UAAU,UAAU,oBAC/B,SAAAV,EAAAA,IAACW,EAAAA,iBAAA,CAAiB,KAAK,IAAA,CAAK,EAC9B,EAEAX,MAAC,QAAK,UAAU,2BAA2B,cAAY,OAAO,EAE/DM,CAAA,CAAA,CAAA,EAGP,CAEJ"}
@@ -1,54 +1,61 @@
1
- import { jsx as r, jsxs as o } from "react/jsx-runtime";
2
- import { clsx as u } from "../../../vendor/clsx/dist/clsx.js";
3
- import { Tree as f, TreeItem as s, Collection as p, TreeItemContent as C, Button as x } from "react-aria-components";
1
+ import { jsx as r, jsxs as d } from "react/jsx-runtime";
2
+ import { clsx as C } from "../../../vendor/clsx/dist/clsx.js";
3
+ import { Tree as v, TreeItem as h, Collection as x, TreeItemContent as I, Button as T } from "react-aria-components";
4
4
  /* empty css */
5
- import { IconLoader as I } from "../../icons/IconLoader.js";
6
- import { IconChevronRight as T } from "../../icons/IconChevronRight.js";
7
- function v(t) {
5
+ import { BrandLoader as b } from "../BrandLoader/BrandLoader.js";
6
+ import { IconChevronRight as B } from "../../icons/IconChevronRight.js";
7
+ function N(t) {
8
8
  return t.hasChildItems ?? !!(t.children && t.children.length > 0);
9
9
  }
10
- function B({
10
+ function u(t, i) {
11
+ return t.flatMap((n) => [
12
+ ...i(n.id) ? [n.id] : [],
13
+ ...u(n.children ?? [], i)
14
+ ]);
15
+ }
16
+ function O({
11
17
  className: t,
12
18
  items: i,
13
- renderItem: l,
14
- isNodeLoading: n,
19
+ renderItem: n,
20
+ isNodeLoading: l,
15
21
  onItemAction: c,
16
- dependencies: a,
17
- ...d
22
+ dependencies: o,
23
+ ...p
18
24
  }) {
19
- function m(e) {
20
- return /* @__PURE__ */ o(
21
- s,
25
+ const f = l ? JSON.stringify(u(i, l)) : "", a = [...o ?? [], f];
26
+ function s(e) {
27
+ return /* @__PURE__ */ d(
28
+ h,
22
29
  {
23
30
  id: e.id,
24
31
  textValue: e.label,
25
- hasChildItems: v(e),
32
+ hasChildItems: N(e),
26
33
  className: "tree-item",
27
34
  onAction: c ? () => c(e) : void 0,
28
35
  children: [
29
- /* @__PURE__ */ r(h, { children: l(e) }),
30
- e.children && e.children.length > 0 && /* @__PURE__ */ r(p, { items: e.children, dependencies: a, children: m }),
31
- ((n == null ? void 0 : n(e.id)) ?? !1) && /* @__PURE__ */ r(s, { id: `${e.id}::loading`, textValue: "Loading", isDisabled: !0, className: "tree-item", children: /* @__PURE__ */ r(h, { children: /* @__PURE__ */ r(I, { size: "16", className: "tree-item-loading-icon" }) }) })
36
+ /* @__PURE__ */ r(m, { children: n(e) }),
37
+ e.children && e.children.length > 0 && /* @__PURE__ */ r(x, { items: e.children, dependencies: a, children: s }),
38
+ ((l == null ? void 0 : l(e.id)) ?? !1) && /* @__PURE__ */ r(h, { id: `${e.id}::loading`, textValue: "Loading", isDisabled: !0, className: "tree-item", children: /* @__PURE__ */ r(m, { children: /* @__PURE__ */ r(b, { "aria-hidden": !0, variant: "pulse", size: "16", tone: "brand" }) }) })
32
39
  ]
33
40
  }
34
41
  );
35
42
  }
36
- return /* @__PURE__ */ r(f, { items: i, className: u(t, "tree"), dependencies: a, ...d, children: m });
43
+ return /* @__PURE__ */ r(v, { items: i, className: C(t, "tree"), dependencies: a, ...p, children: s });
37
44
  }
38
- function h({ children: t }) {
39
- return /* @__PURE__ */ r(C, { children: ({ hasChildItems: i, level: l }) => /* @__PURE__ */ o(
45
+ function m({ children: t }) {
46
+ return /* @__PURE__ */ r(I, { children: ({ hasChildItems: i, level: n }) => /* @__PURE__ */ d(
40
47
  "div",
41
48
  {
42
49
  className: "tree-item-row",
43
- style: { "--tree-item-depth": l - 1 },
50
+ style: { "--tree-item-depth": n - 1 },
44
51
  children: [
45
- i ? /* @__PURE__ */ r(x, { slot: "chevron", className: "tree-item-chevron", children: /* @__PURE__ */ r(T, { size: "16" }) }) : /* @__PURE__ */ r("span", { className: "tree-item-chevron-spacer", "aria-hidden": "true" }),
52
+ i ? /* @__PURE__ */ r(T, { slot: "chevron", className: "tree-item-chevron", children: /* @__PURE__ */ r(B, { size: "16" }) }) : /* @__PURE__ */ r("span", { className: "tree-item-chevron-spacer", "aria-hidden": "true" }),
46
53
  t
47
54
  ]
48
55
  }
49
56
  ) });
50
57
  }
51
58
  export {
52
- B as Tree
59
+ O as Tree
53
60
  };
54
61
  //# sourceMappingURL=Tree.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.js","sources":["../../../../../src/ui/primitives/Tree/Tree.tsx"],"sourcesContent":["import type { CSSProperties, Key, ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { IconChevronRight, IconLoader } from \"icons\";\nimport {\n Button,\n Collection,\n Tree as RACTree,\n TreeItem as RACTreeItem,\n TreeItemContent as RACTreeItemContent,\n type TreeProps as RACTreeProps,\n} from \"react-aria-components\";\nimport \"./tree.css\";\n\nexport interface TreeNode<T = unknown> {\n id: string;\n label: string;\n data?: T;\n /** Signals a node has children before they are fetched, so the chevron renders ahead of a lazy load. */\n hasChildItems?: boolean;\n /** `undefined` = not loaded yet, `[]` = loaded and empty. */\n children?: TreeNode<T>[];\n}\n\nexport type TreeProps<T> = Omit<\n RACTreeProps<TreeNode<T>>,\n \"children\" | \"items\"\n> & {\n items: TreeNode<T>[];\n renderItem: (node: TreeNode<T>) => ReactNode;\n isNodeLoading?: (id: Key) => boolean;\n onItemAction?: (node: TreeNode<T>) => void;\n};\n\nfunction hasExpandableChildren<T>(node: TreeNode<T>): boolean {\n return node.hasChildItems ?? Boolean(node.children && node.children.length > 0);\n}\n\nexport function Tree<T>({\n className,\n items,\n renderItem,\n isNodeLoading,\n onItemAction,\n dependencies,\n ...props\n}: TreeProps<T>) {\n function renderNode(node: TreeNode<T>): ReactNode {\n return (\n <RACTreeItem\n id={node.id}\n textValue={node.label}\n hasChildItems={hasExpandableChildren(node)}\n className=\"tree-item\"\n onAction={onItemAction ? () => onItemAction(node) : undefined}\n >\n <TreeItemContent>{renderItem(node)}</TreeItemContent>\n {node.children && node.children.length > 0 && (\n <Collection items={node.children} dependencies={dependencies}>\n {renderNode}\n </Collection>\n )}\n {(isNodeLoading?.(node.id) ?? false) && (\n <RACTreeItem id={`${node.id}::loading`} textValue=\"Loading\" isDisabled className=\"tree-item\">\n <TreeItemContent>\n <IconLoader size=\"16\" className=\"tree-item-loading-icon\" />\n </TreeItemContent>\n </RACTreeItem>\n )}\n </RACTreeItem>\n );\n }\n\n return (\n <RACTree items={items} className={clsx(className, \"tree\")} dependencies={dependencies} {...props}>\n {renderNode}\n </RACTree>\n );\n}\n\ninterface TreeItemContentProps {\n children: ReactNode;\n}\n\nfunction TreeItemContent({ children }: TreeItemContentProps) {\n return (\n <RACTreeItemContent>\n {({ hasChildItems, level }) => (\n <div\n className=\"tree-item-row\"\n style={{ \"--tree-item-depth\": level - 1 } as CSSProperties}\n >\n {hasChildItems ? (\n <Button slot=\"chevron\" className=\"tree-item-chevron\">\n <IconChevronRight size=\"16\" />\n </Button>\n ) : (\n <span className=\"tree-item-chevron-spacer\" aria-hidden=\"true\" />\n )}\n {children}\n </div>\n )}\n </RACTreeItemContent>\n );\n}\n"],"names":["hasExpandableChildren","node","Tree","className","items","renderItem","isNodeLoading","onItemAction","dependencies","props","renderNode","jsxs","RACTreeItem","jsx","TreeItemContent","Collection","IconLoader","RACTree","clsx","children","RACTreeItemContent","hasChildItems","level","Button","IconChevronRight"],"mappings":";;;;;;AAiCA,SAASA,EAAyBC,GAA4B;AAC5D,SAAOA,EAAK,iBAAiB,GAAQA,EAAK,YAAYA,EAAK,SAAS,SAAS;AAC/E;AAEO,SAASC,EAAQ;AAAA,EACtB,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAC;AAAA,EACA,cAAAC;AAAA,EACA,cAAAC;AAAA,EACA,GAAGC;AACL,GAAiB;AACf,WAASC,EAAWT,GAA8B;AAChD,WACE,gBAAAU;AAAA,MAACC;AAAAA,MAAA;AAAA,QACC,IAAIX,EAAK;AAAA,QACT,WAAWA,EAAK;AAAA,QAChB,eAAeD,EAAsBC,CAAI;AAAA,QACzC,WAAU;AAAA,QACV,UAAUM,IAAe,MAAMA,EAAaN,CAAI,IAAI;AAAA,QAEpD,UAAA;AAAA,UAAA,gBAAAY,EAACC,GAAA,EAAiB,UAAAT,EAAWJ,CAAI,EAAA,CAAE;AAAA,UAClCA,EAAK,YAAYA,EAAK,SAAS,SAAS,KACvC,gBAAAY,EAACE,GAAA,EAAW,OAAOd,EAAK,UAAU,cAAAO,GAC/B,UAAAE,GACH;AAAA,YAEAJ,KAAA,gBAAAA,EAAgBL,EAAK,QAAO,OAC5B,gBAAAY,EAACD,GAAA,EAAY,IAAI,GAAGX,EAAK,EAAE,aAAa,WAAU,WAAU,YAAU,IAAC,WAAU,aAC/E,UAAA,gBAAAY,EAACC,GAAA,EACC,UAAA,gBAAAD,EAACG,GAAA,EAAW,MAAK,MAAK,WAAU,yBAAA,CAAyB,EAAA,CAC3D,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AAEA,SACE,gBAAAH,EAACI,GAAA,EAAQ,OAAAb,GAAc,WAAWc,EAAKf,GAAW,MAAM,GAAG,cAAAK,GAA6B,GAAGC,GACxF,UAAAC,EAAA,CACH;AAEJ;AAMA,SAASI,EAAgB,EAAE,UAAAK,KAAkC;AAC3D,2BACGC,GAAA,EACE,UAAA,CAAC,EAAE,eAAAC,GAAe,OAAAC,QACjB,gBAAAX;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,qBAAqBW,IAAQ,EAAA;AAAA,MAErC,UAAA;AAAA,QAAAD,sBACEE,GAAA,EAAO,MAAK,WAAU,WAAU,qBAC/B,UAAA,gBAAAV,EAACW,GAAA,EAAiB,MAAK,KAAA,CAAK,GAC9B,IAEA,gBAAAX,EAAC,UAAK,WAAU,4BAA2B,eAAY,QAAO;AAAA,QAE/DM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAGP;AAEJ;"}
1
+ {"version":3,"file":"Tree.js","sources":["../../../../../src/ui/primitives/Tree/Tree.tsx"],"sourcesContent":["import type { CSSProperties, Key, ReactNode } from \"react\";\nimport clsx from \"clsx\";\nimport { IconChevronRight } from \"icons\";\nimport { BrandLoader } from \"primitives\";\nimport {\n Button,\n Collection,\n Tree as RACTree,\n TreeItem as RACTreeItem,\n TreeItemContent as RACTreeItemContent,\n type TreeProps as RACTreeProps,\n} from \"react-aria-components\";\nimport \"./tree.css\";\n\nexport interface TreeNode<T = unknown> {\n id: string;\n label: string;\n data?: T;\n /** Signals a node has children before they are fetched, so the chevron renders ahead of a lazy load. */\n hasChildItems?: boolean;\n /** `undefined` = not loaded yet, `[]` = loaded and empty. */\n children?: TreeNode<T>[];\n}\n\nexport type TreeProps<T> = Omit<\n RACTreeProps<TreeNode<T>>,\n \"children\" | \"items\"\n> & {\n items: TreeNode<T>[];\n renderItem: (node: TreeNode<T>) => ReactNode;\n isNodeLoading?: (id: Key) => boolean;\n onItemAction?: (node: TreeNode<T>) => void;\n};\n\nfunction hasExpandableChildren<T>(node: TreeNode<T>): boolean {\n return node.hasChildItems ?? Boolean(node.children && node.children.length > 0);\n}\n\nfunction loadingNodeIdsOf<T>(nodes: TreeNode<T>[], isNodeLoading: (id: Key) => boolean): string[] {\n return nodes.flatMap((node) => [\n ...(isNodeLoading(node.id) ? [node.id] : []),\n ...loadingNodeIdsOf(node.children ?? [], isNodeLoading),\n ]);\n}\n\nexport function Tree<T>({\n className,\n items,\n renderItem,\n isNodeLoading,\n onItemAction,\n dependencies,\n ...props\n}: TreeProps<T>) {\n const loadingNodesSignature = isNodeLoading\n ? JSON.stringify(loadingNodeIdsOf(items, isNodeLoading))\n : \"\";\n const itemDependencies = [...(dependencies ?? []), loadingNodesSignature];\n\n function renderNode(node: TreeNode<T>): ReactNode {\n return (\n <RACTreeItem\n id={node.id}\n textValue={node.label}\n hasChildItems={hasExpandableChildren(node)}\n className=\"tree-item\"\n onAction={onItemAction ? () => onItemAction(node) : undefined}\n >\n <TreeItemContent>{renderItem(node)}</TreeItemContent>\n {node.children && node.children.length > 0 && (\n <Collection items={node.children} dependencies={itemDependencies}>\n {renderNode}\n </Collection>\n )}\n {(isNodeLoading?.(node.id) ?? false) && (\n <RACTreeItem id={`${node.id}::loading`} textValue=\"Loading\" isDisabled className=\"tree-item\">\n <TreeItemContent>\n <BrandLoader aria-hidden variant=\"pulse\" size=\"16\" tone=\"brand\" />\n </TreeItemContent>\n </RACTreeItem>\n )}\n </RACTreeItem>\n );\n }\n\n return (\n <RACTree items={items} className={clsx(className, \"tree\")} dependencies={itemDependencies} {...props}>\n {renderNode}\n </RACTree>\n );\n}\n\ninterface TreeItemContentProps {\n children: ReactNode;\n}\n\nfunction TreeItemContent({ children }: TreeItemContentProps) {\n return (\n <RACTreeItemContent>\n {({ hasChildItems, level }) => (\n <div\n className=\"tree-item-row\"\n style={{ \"--tree-item-depth\": level - 1 } as CSSProperties}\n >\n {hasChildItems ? (\n <Button slot=\"chevron\" className=\"tree-item-chevron\">\n <IconChevronRight size=\"16\" />\n </Button>\n ) : (\n <span className=\"tree-item-chevron-spacer\" aria-hidden=\"true\" />\n )}\n {children}\n </div>\n )}\n </RACTreeItemContent>\n );\n}\n"],"names":["hasExpandableChildren","node","loadingNodeIdsOf","nodes","isNodeLoading","Tree","className","items","renderItem","onItemAction","dependencies","props","loadingNodesSignature","itemDependencies","renderNode","jsxs","RACTreeItem","jsx","TreeItemContent","Collection","BrandLoader","RACTree","clsx","children","RACTreeItemContent","hasChildItems","level","Button","IconChevronRight"],"mappings":";;;;;;AAkCA,SAASA,EAAyBC,GAA4B;AAC5D,SAAOA,EAAK,iBAAiB,GAAQA,EAAK,YAAYA,EAAK,SAAS,SAAS;AAC/E;AAEA,SAASC,EAAoBC,GAAsBC,GAA+C;AAChG,SAAOD,EAAM,QAAQ,CAACF,MAAS;AAAA,IAC7B,GAAIG,EAAcH,EAAK,EAAE,IAAI,CAACA,EAAK,EAAE,IAAI,CAAA;AAAA,IACzC,GAAGC,EAAiBD,EAAK,YAAY,CAAA,GAAIG,CAAa;AAAA,EAAA,CACvD;AACH;AAEO,SAASC,EAAQ;AAAA,EACtB,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,YAAAC;AAAA,EACA,eAAAJ;AAAA,EACA,cAAAK;AAAA,EACA,cAAAC;AAAA,EACA,GAAGC;AACL,GAAiB;AACf,QAAMC,IAAwBR,IAC1B,KAAK,UAAUF,EAAiBK,GAAOH,CAAa,CAAC,IACrD,IACES,IAAmB,CAAC,GAAIH,KAAgB,CAAA,GAAKE,CAAqB;AAExE,WAASE,EAAWb,GAA8B;AAChD,WACE,gBAAAc;AAAA,MAACC;AAAAA,MAAA;AAAA,QACC,IAAIf,EAAK;AAAA,QACT,WAAWA,EAAK;AAAA,QAChB,eAAeD,EAAsBC,CAAI;AAAA,QACzC,WAAU;AAAA,QACV,UAAUQ,IAAe,MAAMA,EAAaR,CAAI,IAAI;AAAA,QAEpD,UAAA;AAAA,UAAA,gBAAAgB,EAACC,GAAA,EAAiB,UAAAV,EAAWP,CAAI,EAAA,CAAE;AAAA,UAClCA,EAAK,YAAYA,EAAK,SAAS,SAAS,KACvC,gBAAAgB,EAACE,GAAA,EAAW,OAAOlB,EAAK,UAAU,cAAcY,GAC7C,UAAAC,GACH;AAAA,YAEAV,KAAA,gBAAAA,EAAgBH,EAAK,QAAO,OAC5B,gBAAAgB,EAACD,GAAA,EAAY,IAAI,GAAGf,EAAK,EAAE,aAAa,WAAU,WAAU,YAAU,IAAC,WAAU,aAC/E,UAAA,gBAAAgB,EAACC,GAAA,EACC,UAAA,gBAAAD,EAACG,KAAY,eAAW,IAAC,SAAQ,SAAQ,MAAK,MAAK,MAAK,QAAA,CAAQ,GAClE,EAAA,CACF;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AAEA,SACE,gBAAAH,EAACI,GAAA,EAAQ,OAAAd,GAAc,WAAWe,EAAKhB,GAAW,MAAM,GAAG,cAAcO,GAAmB,GAAGF,GAC5F,UAAAG,EAAA,CACH;AAEJ;AAMA,SAASI,EAAgB,EAAE,UAAAK,KAAkC;AAC3D,2BACGC,GAAA,EACE,UAAA,CAAC,EAAE,eAAAC,GAAe,OAAAC,QACjB,gBAAAX;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,qBAAqBW,IAAQ,EAAA;AAAA,MAErC,UAAA;AAAA,QAAAD,sBACEE,GAAA,EAAO,MAAK,WAAU,WAAU,qBAC/B,UAAA,gBAAAV,EAACW,GAAA,EAAiB,MAAK,KAAA,CAAK,GAC9B,IAEA,gBAAAX,EAAC,UAAK,WAAU,4BAA2B,eAAY,QAAO;AAAA,QAE/DM;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA,GAGP;AAEJ;"}
@@ -14,7 +14,15 @@ export interface Column<T> {
14
14
  sortValue?: (item: T) => SortableValue;
15
15
  }
16
16
  type SortableValue = string | number | Date | null | undefined;
17
- export interface RowActionDef<T> {
17
+ type RowActionPendingProps = {
18
+ isPending?: false;
19
+ pendingLabel?: string;
20
+ } | {
21
+ isPending: boolean;
22
+ /** Tooltip text shown while `isPending`. */
23
+ pendingLabel: string;
24
+ };
25
+ export type RowActionDef<T> = RowActionPendingProps & {
18
26
  /** Unique key for this action. */
19
27
  key: string;
20
28
  /** aria-label for the button. */
@@ -27,8 +35,8 @@ export interface RowActionDef<T> {
27
35
  noAccessLabel?: string;
28
36
  /** Called with the row item when the button is pressed. */
29
37
  onPress: (item: T) => void;
30
- }
31
- export interface DataTableProps<T extends {
38
+ };
39
+ interface DataTableBaseProps<T extends {
32
40
  id: string;
33
41
  }> {
34
42
  columns: Column<T>[];
@@ -72,22 +80,37 @@ export interface DataTableProps<T extends {
72
80
  maxHeight?: number | string;
73
81
  searchPlaceholder?: string;
74
82
  searchKeys?: (keyof T)[];
75
- isLoading?: boolean;
76
- loadingMessage?: string;
77
83
  emptyMessage?: string;
78
84
  previousLabel?: string;
79
85
  nextLabel?: string;
80
86
  pageSize?: number;
81
87
  nestedColumns?: Column<any>[];
82
- getNestedData?: (item: T) => any[] | Promise<any[]>;
83
- nestedLoadingMessage?: string;
84
88
  nestedEmptyMessage?: string;
85
89
  nestedSearchKeys?: (keyof any)[];
86
90
  nestedSearchPlaceholder?: string;
87
91
  nestedActions?: (item: T) => ReactNode;
88
92
  nestedPageSize?: number;
89
93
  }
94
+ type DataTableLoadingProps = {
95
+ isLoading?: false;
96
+ isRefreshing?: false;
97
+ loadingMessage?: string;
98
+ } | {
99
+ isLoading?: boolean;
100
+ isRefreshing?: boolean;
101
+ loadingMessage: string;
102
+ };
103
+ type DataTableNestedLoadingProps<T> = {
104
+ getNestedData?: undefined;
105
+ nestedLoadingMessage?: string;
106
+ } | {
107
+ getNestedData: (item: T) => any[] | Promise<any[]>;
108
+ nestedLoadingMessage: string;
109
+ };
110
+ export type DataTableProps<T extends {
111
+ id: string;
112
+ }> = DataTableBaseProps<T> & DataTableLoadingProps & DataTableNestedLoadingProps<T>;
90
113
  export declare function DataTable<T extends {
91
114
  id: string;
92
- }>({ columns, data, actions, rowActions, rowActionsLabel, selectable, selectionType, selectedKeys, onSelectionChange, defaultSortDescriptor, sortDescriptor: controlledSortDescriptor, onSortChange, ariaLabel, dense, striped, maxHeight, searchPlaceholder, searchKeys, isLoading, loadingMessage, emptyMessage, previousLabel, nextLabel, pageSize, nestedColumns, getNestedData, nestedLoadingMessage, nestedEmptyMessage, nestedSearchKeys, nestedSearchPlaceholder, nestedActions, nestedPageSize, }: DataTableProps<T>): import("react/jsx-runtime").JSX.Element;
115
+ }>({ columns, data, actions, rowActions, rowActionsLabel, selectable, selectionType, selectedKeys, onSelectionChange, defaultSortDescriptor, sortDescriptor: controlledSortDescriptor, onSortChange, ariaLabel, dense, striped, maxHeight, searchPlaceholder, searchKeys, isLoading, isRefreshing, loadingMessage, emptyMessage, previousLabel, nextLabel, pageSize, nestedColumns, getNestedData, nestedLoadingMessage, nestedEmptyMessage, nestedSearchKeys, nestedSearchPlaceholder, nestedActions, nestedPageSize, }: DataTableProps<T>): import("react/jsx-runtime").JSX.Element;
93
116
  export {};
@@ -0,0 +1,13 @@
1
+ import { type BrandLoaderSize, type BrandLoaderVariant } from "primitives";
2
+ import "./loading-overlay.css";
3
+ export type LoadingOverlayProps = {
4
+ isOpen: boolean;
5
+ label: string;
6
+ message?: string;
7
+ variant?: BrandLoaderVariant;
8
+ size?: BrandLoaderSize;
9
+ delayMs?: number;
10
+ minVisibleMs?: number;
11
+ className?: string;
12
+ };
13
+ export declare function LoadingOverlay({ isOpen, label, message, variant, size, delayMs, minVisibleMs, className, }: LoadingOverlayProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { type LoadingStateProps } from "primitives";
2
+ import "./page-loading-state.css";
3
+ export type PageLoadingStateProps = Omit<LoadingStateProps, "size">;
4
+ export declare function PageLoadingState({ className, ...props }: PageLoadingStateProps): import("react/jsx-runtime").JSX.Element;
@@ -5,10 +5,11 @@ export * from "./ConfirmDialog/ConfirmDialog";
5
5
  export * from "./DataTable/DataTable";
6
6
  export * from "./FormModal/FormModal";
7
7
  export * from "./KeyValue/KeyValue";
8
+ export * from "./LoadingOverlay/LoadingOverlay";
8
9
  export * from "./PageHeader/PageHeader";
10
+ export * from "./PageLoadingState/PageLoadingState";
9
11
  export * from "./Sidebar/Sidebar";
10
12
  export * from "./Widget/Widget";
11
13
  export * from "./WidgetEmptyState/WidgetEmptyState";
12
14
  export * from "./WidgetErrorState/WidgetErrorState";
13
15
  export * from "./WidgetGrid/WidgetGrid";
14
- export * from "./WidgetLoadingState/WidgetLoadingState";
@@ -1,2 +1,3 @@
1
+ export * from "./useLoadingVisibility";
1
2
  export * from "./useMediaQuery";
2
3
  export * from "./useOverlayPortal";
@@ -0,0 +1,3 @@
1
+ type FrameSubscriber = (now: number) => void;
2
+ export declare function useAnimationFrame(onFrame: FrameSubscriber, isEnabled?: boolean): void;
3
+ export {};
@@ -0,0 +1,7 @@
1
+ export type LoadingVisibilityOptions = {
2
+ delayMs?: number;
3
+ minVisibleMs?: number;
4
+ };
5
+ export declare const defaultLoadingDelayMs = 200;
6
+ export declare const defaultLoadingMinVisibleMs = 400;
7
+ export declare function useLoadingVisibility(isLoading: boolean, { delayMs, minVisibleMs, }?: LoadingVisibilityOptions): boolean;
@@ -0,0 +1,25 @@
1
+ import { type ComponentPropsWithoutRef } from "react";
2
+ import { type BrandLoaderVariant } from "./brandLoaderVariants";
3
+ import { type BrandLoaderSymbol } from "./brandLoaderSymbolContext";
4
+ import "./brand-loader.css";
5
+ export type { BrandLoaderVariant } from "./brandLoaderVariants";
6
+ export { BrandLoaderProvider, type BrandLoaderProviderProps } from "./BrandLoaderProvider";
7
+ export type { BrandLoaderSymbol } from "./brandLoaderSymbolContext";
8
+ export type BrandLoaderSize = "16" | "24" | "32" | "64";
9
+ export type BrandLoaderTone = "accent" | "brand" | "current";
10
+ type BrandLoaderAccessibilityProps = {
11
+ label: string;
12
+ "aria-hidden"?: false;
13
+ } | {
14
+ label?: undefined;
15
+ "aria-hidden": true;
16
+ };
17
+ export type BrandLoaderProps = Omit<ComponentPropsWithoutRef<"span">, "children" | "aria-hidden"> & BrandLoaderAccessibilityProps & {
18
+ variant?: BrandLoaderVariant;
19
+ size?: BrandLoaderSize;
20
+ tone?: BrandLoaderTone;
21
+ speed?: number;
22
+ isPaused?: boolean;
23
+ symbol?: BrandLoaderSymbol;
24
+ };
25
+ export declare function BrandLoader({ label, "aria-hidden": isDecorative, variant, size, tone, speed, isPaused, symbol, className, ...props }: BrandLoaderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,7 @@
1
+ import { type ReactNode } from "react";
2
+ import { type BrandLoaderSymbol } from "./brandLoaderSymbolContext";
3
+ export type BrandLoaderProviderProps = {
4
+ symbol: BrandLoaderSymbol;
5
+ children: ReactNode;
6
+ };
7
+ export declare function BrandLoaderProvider({ symbol, children }: BrandLoaderProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,3 @@
1
+ export type BrandLoaderSymbol = "apipass" | "neutral";
2
+ export declare const BrandLoaderSymbolContext: import("react").Context<BrandLoaderSymbol>;
3
+ export declare function useBrandLoaderSymbol(): BrandLoaderSymbol;
@@ -0,0 +1,33 @@
1
+ export type BrandLoaderVariant = "trace" | "bounce" | "assemble" | "comet" | "pulse" | "sweep";
2
+ export type BrandLoaderElements = {
3
+ strokes: SVGGElement;
4
+ slash: SVGPathElement;
5
+ big: SVGPathElement;
6
+ tri: SVGPathElement;
7
+ ball: SVGEllipseElement | null;
8
+ sweepClip: SVGPolygonElement | null;
9
+ sweepEdge: SVGLineElement | null;
10
+ lengths: {
11
+ slash: number;
12
+ big: number;
13
+ tri: number;
14
+ };
15
+ };
16
+ type BrandLoaderVariantDefinition = {
17
+ period: number;
18
+ render: (progress: number, elements: BrandLoaderElements) => void;
19
+ renderRest: (elements: BrandLoaderElements) => void;
20
+ };
21
+ export declare const brandLoaderViewBox = "-4 -4 48 40";
22
+ export declare const brandLoaderPathLengths: {
23
+ slash: number;
24
+ big: number;
25
+ tri: number;
26
+ };
27
+ export declare const brandLoaderSymbolPaths: {
28
+ slash: string;
29
+ big: string;
30
+ tri: string;
31
+ };
32
+ export declare const brandLoaderVariants: Record<BrandLoaderVariant, BrandLoaderVariantDefinition>;
33
+ export {};
@@ -18,6 +18,7 @@ export declare const ButtonDanger: React.ForwardRefExoticComponent<Omit<ButtonBa
18
18
  } & React.RefAttributes<HTMLElement>>;
19
19
  type ButtonBaseProps = {
20
20
  type?: ComponentPropsWithoutRef<"button">["type"];
21
+ isPending?: boolean;
21
22
  size?: "small" | "medium";
22
23
  variant?: "primary" | "neutral" | "subtle" | "text" | "danger-primary" | "danger-subtle";
23
24
  } & AnchorOrButtonProps;
@@ -0,0 +1,10 @@
1
+ import { type ComponentPropsWithoutRef } from "react";
2
+ import { type BrandLoaderSize, type BrandLoaderVariant } from "../BrandLoader/BrandLoader";
3
+ import "./loading-state.css";
4
+ export type LoadingStateProps = ComponentPropsWithoutRef<"div"> & {
5
+ message: string;
6
+ variant?: BrandLoaderVariant;
7
+ size?: BrandLoaderSize;
8
+ delayMs?: number;
9
+ };
10
+ export declare function LoadingState({ message, variant, size, delayMs, className, ...props }: LoadingStateProps): import("react/jsx-runtime").JSX.Element;
@@ -1,15 +1,24 @@
1
1
  import React from "react";
2
- export interface PermissionGateProps {
2
+ type PermissionGatePendingProps = {
3
+ isPending?: false;
4
+ pendingLabel?: string;
5
+ } | {
6
+ isPending: boolean;
7
+ /** Tooltip text shown while `isPending`. */
8
+ pendingLabel: string;
9
+ };
10
+ export type PermissionGateProps = PermissionGatePendingProps & {
3
11
  /** Whether the current user has permission to perform this action. */
4
12
  isAllowed: boolean;
5
13
  /** Tooltip text shown when the action is not allowed. */
6
14
  noAccessLabel: string;
7
15
  /**
8
- * Either a React element or a render prop that receives `isAllowed`.
9
- * Use the render prop to avoid repeating the permission check inside the child.
16
+ * Either a React element or a render prop that receives `isAllowed` and `isPending`.
17
+ * Use the render prop to avoid repeating the permission check inside the child, e.g.
18
+ * `{(allowed, pending) => <Button isDisabled={!allowed && !pending} isPending={pending}>…</Button>}`.
10
19
  */
11
- children: React.ReactElement | ((isAllowed: boolean) => React.ReactElement);
12
- }
20
+ children: React.ReactElement | ((isAllowed: boolean, isPending: boolean) => React.ReactElement);
21
+ };
13
22
  /**
14
23
  * Wraps any interactive element with a tooltip that appears when `isAllowed` is false.
15
24
  *
@@ -37,4 +46,5 @@ export interface PermissionGateProps {
37
46
  * seguro — é onde o `DataTable` põe o gate nas ações de linha. O `Menu` avisa no
38
47
  * console em desenvolvimento se o gate aparecer em volta de um item.
39
48
  */
40
- export declare function PermissionGate({ isAllowed, noAccessLabel, children, }: PermissionGateProps): import("react/jsx-runtime").JSX.Element;
49
+ export declare function PermissionGate({ isAllowed, noAccessLabel, isPending, pendingLabel, children, }: PermissionGateProps): import("react/jsx-runtime").JSX.Element;
50
+ export {};
@@ -3,6 +3,7 @@ export * from "./Alert/Alert";
3
3
  export * from "./CodeBlock/CodeBlock";
4
4
  export * from "./CodeEditor/CodeEditor";
5
5
  export * from "./Avatar/Avatar";
6
+ export * from "./BrandLoader/BrandLoader";
6
7
  export * from "./Button/Button";
7
8
  export * from "./Checkbox/Checkbox";
8
9
  export * from "./ComboBox/ComboBox";
@@ -18,6 +19,7 @@ export * from "./Image/Image";
18
19
  export * from "./Input/Input";
19
20
  export * from "./Link/Link";
20
21
  export * from "./ListBox/ListBox";
22
+ export * from "./LoadingState/LoadingState";
21
23
  export * from "./Logo/Logo";
22
24
  export * from "./Menu/Menu";
23
25
  export * from "./Navigation/Navigation";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apipass/design-system",
3
- "version": "7.4.7",
3
+ "version": "8.0.0",
4
4
  "type": "module",
5
5
  "description": "APIPass React Design System",
6
6
  "sideEffects": [
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),a=require("../../../vendor/clsx/dist/clsx.cjs");;/* empty css */const n=require("../../icons/IconLoader.cjs");function r({message:t,className:s,...i}){return e.jsxs("div",{role:"status","aria-live":"polite",className:a.clsx("widget-loading-state",s),...i,children:[e.jsx(n.IconLoader,{size:"24",className:"widget-loading-state-spinner"}),e.jsx("span",{className:"widget-loading-state-message",children:t})]})}exports.WidgetLoadingState=r;
2
- //# sourceMappingURL=WidgetLoadingState.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"WidgetLoadingState.cjs","sources":["../../../../../src/ui/components/WidgetLoadingState/WidgetLoadingState.tsx"],"sourcesContent":["import clsx from \"clsx\";\nimport { type ComponentPropsWithoutRef } from \"react\";\nimport { IconLoader } from \"icons\";\nimport \"./widget-loading-state.css\";\n\nexport type WidgetLoadingStateProps = ComponentPropsWithoutRef<\"div\"> & {\n message: string;\n};\n\nexport function WidgetLoadingState({\n message,\n className,\n ...props\n}: WidgetLoadingStateProps) {\n return (\n <div\n role=\"status\"\n aria-live=\"polite\"\n className={clsx(\"widget-loading-state\", className)}\n {...props}\n >\n <IconLoader size=\"24\" className=\"widget-loading-state-spinner\" />\n <span className=\"widget-loading-state-message\">{message}</span>\n </div>\n );\n}\n"],"names":["WidgetLoadingState","message","className","props","jsxs","clsx","jsx","IconLoader"],"mappings":"6PASO,SAASA,EAAmB,CACjC,QAAAC,EACA,UAAAC,EACA,GAAGC,CACL,EAA4B,CAC1B,OACEC,EAAAA,KAAC,MAAA,CACC,KAAK,SACL,YAAU,SACV,UAAWC,EAAAA,KAAK,uBAAwBH,CAAS,EAChD,GAAGC,EAEJ,SAAA,CAAAG,EAAAA,IAACC,EAAAA,WAAA,CAAW,KAAK,KAAK,UAAU,+BAA+B,EAC/DD,EAAAA,IAAC,OAAA,CAAK,UAAU,+BAAgC,SAAAL,CAAA,CAAQ,CAAA,CAAA,CAAA,CAG9D"}
@@ -1,27 +0,0 @@
1
- import { jsxs as s, jsx as e } from "react/jsx-runtime";
2
- import { clsx as o } from "../../../vendor/clsx/dist/clsx.js";
3
- /* empty css */
4
- import { IconLoader as r } from "../../icons/IconLoader.js";
5
- function g({
6
- message: t,
7
- className: i,
8
- ...a
9
- }) {
10
- return /* @__PURE__ */ s(
11
- "div",
12
- {
13
- role: "status",
14
- "aria-live": "polite",
15
- className: o("widget-loading-state", i),
16
- ...a,
17
- children: [
18
- /* @__PURE__ */ e(r, { size: "24", className: "widget-loading-state-spinner" }),
19
- /* @__PURE__ */ e("span", { className: "widget-loading-state-message", children: t })
20
- ]
21
- }
22
- );
23
- }
24
- export {
25
- g as WidgetLoadingState
26
- };
27
- //# sourceMappingURL=WidgetLoadingState.js.map