@meetreeve/ui 0.13.0 → 0.14.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.
package/dist/index.d.mts CHANGED
@@ -632,7 +632,7 @@ declare function ContextSwitcher({ items, activeRefId, onSelect, footer, placeho
632
632
  * errors, and a return-from-OAuth refresh). Every label is derived from the
633
633
  * entry data the client returns — this file must never hardcode a specific
634
634
  * provider's name (an explicit acceptance criterion); a host app supplies
635
- * that entirely through `ConnectableEntry.name` / `.logo` / `.category`.
635
+ * that entirely through `ConnectableEntry.name` / `.logo`.
636
636
  *
637
637
  * Transport-injection precedent: `linkComponent` (DEV-4429/DEV-4391) —
638
638
  * inject the transport, keep behavior in the package. Here the "transport"
@@ -664,7 +664,7 @@ interface ConnectorRoleOption {
664
664
  */
665
665
  interface OrgConnectPolicy {
666
666
  permitted: boolean;
667
- /** Human-readable reason shown on the disabled org option. */
667
+ /** Why org connect isn't permitted (server-authored). */
668
668
  reason?: string | null;
669
669
  /** Role options offered by manage-sharing's "role" grantee type. */
670
670
  role_options?: ConnectorRoleOption[];
package/dist/index.d.ts CHANGED
@@ -632,7 +632,7 @@ declare function ContextSwitcher({ items, activeRefId, onSelect, footer, placeho
632
632
  * errors, and a return-from-OAuth refresh). Every label is derived from the
633
633
  * entry data the client returns — this file must never hardcode a specific
634
634
  * provider's name (an explicit acceptance criterion); a host app supplies
635
- * that entirely through `ConnectableEntry.name` / `.logo` / `.category`.
635
+ * that entirely through `ConnectableEntry.name` / `.logo`.
636
636
  *
637
637
  * Transport-injection precedent: `linkComponent` (DEV-4429/DEV-4391) —
638
638
  * inject the transport, keep behavior in the package. Here the "transport"
@@ -664,7 +664,7 @@ interface ConnectorRoleOption {
664
664
  */
665
665
  interface OrgConnectPolicy {
666
666
  permitted: boolean;
667
- /** Human-readable reason shown on the disabled org option. */
667
+ /** Why org connect isn't permitted (server-authored). */
668
668
  reason?: string | null;
669
669
  /** Role options offered by manage-sharing's "role" grantee type. */
670
670
  role_options?: ConnectorRoleOption[];
package/dist/index.js CHANGED
@@ -1471,7 +1471,6 @@ var DEFAULT_LOAD_ERROR = "Couldn't load connections. Please try again.";
1471
1471
  var DEFAULT_GRANTS_LOAD_ERROR = "Couldn't load sharing. Please try again.";
1472
1472
  var DEFAULT_GRANT_ERROR = "Couldn't share. Please try again.";
1473
1473
  var DEFAULT_REVOKE_ERROR = "Couldn't revoke access. Please try again.";
1474
- var DEFAULT_ORG_DISABLED_REASON = "Org-wide connections aren't available to you.";
1475
1474
  var DEFAULT_CREDENTIAL_ERROR = "Couldn't save that credential. Please try again.";
1476
1475
  var DEFAULT_CREDENTIAL_TEST_ERROR = "Couldn't test that credential. Please try again.";
1477
1476
  var DEFAULT_RECONNECT_MESSAGE = "This connection needs to be reconnected to keep working.";
@@ -1490,11 +1489,6 @@ function capabilityLabel(capability) {
1490
1489
  if (capability === "write") return "Write only";
1491
1490
  return "Read & write";
1492
1491
  }
1493
- function formatSince(since) {
1494
- const parsed = new Date(since);
1495
- if (Number.isNaN(parsed.getTime())) return since;
1496
- return parsed.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
1497
- }
1498
1492
  function errorMessageFrom(err, fallback) {
1499
1493
  return err instanceof Error && err.message ? err.message : fallback;
1500
1494
  }
@@ -1818,7 +1812,7 @@ function ConnectorTile({
1818
1812
  const guide = entry.guide ?? null;
1819
1813
  const canSetUp = !isConnected && (pasteSupported || guide !== null);
1820
1814
  const orgPermitted = entry.org_connect?.permitted === true;
1821
- const orgDisabledReason = entry.org_connect?.reason || DEFAULT_ORG_DISABLED_REASON;
1815
+ const connectKind = orgPermitted ? kind : "personal";
1822
1816
  const attribution = ownerLabel(entry);
1823
1817
  const canDisconnect = isConnected && !shared;
1824
1818
  const canManageSharing = isConnected && entry.connection.owned_by_viewer === true && grantsSupported;
@@ -1846,19 +1840,21 @@ function ConnectorTile({
1846
1840
  ] }),
1847
1841
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1848
1842
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-testid": `connector-capability-${entry.slug}`, children: capabilityLabel(entry.capability) }),
1849
- entry.category && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1843
+ isConnected && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1850
1844
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": "true", children: "\xB7" }),
1851
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "truncate", children: entry.category })
1845
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1846
+ "span",
1847
+ {
1848
+ "data-testid": `connector-connected-${entry.slug}`,
1849
+ className: "inline-flex items-center gap-1",
1850
+ children: [
1851
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "aria-hidden": "true", className: "h-1.5 w-1.5 rounded-full bg-emerald-500" }),
1852
+ "Connected"
1853
+ ]
1854
+ }
1855
+ )
1852
1856
  ] })
1853
1857
  ] }),
1854
- isConnected && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1855
- "p",
1856
- {
1857
- "data-testid": `connector-connected-since-${entry.slug}`,
1858
- className: "text-xs text-muted-foreground",
1859
- children: entry.connection.since ? `Connected since ${formatSince(entry.connection.since)}` : "Connected"
1860
- }
1861
- ),
1862
1858
  isConnected && !shared && entry.connection.account_label && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1863
1859
  "p",
1864
1860
  {
@@ -1895,7 +1891,7 @@ function ConnectorTile({
1895
1891
  children: attribution
1896
1892
  }
1897
1893
  ),
1898
- !isConnected && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1894
+ !isConnected && orgPermitted && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1899
1895
  "div",
1900
1896
  {
1901
1897
  "data-testid": `connector-kind-toggle-${entry.slug}`,
@@ -1910,6 +1906,7 @@ function ConnectorTile({
1910
1906
  "data-testid": `connector-kind-personal-${entry.slug}`,
1911
1907
  "aria-pressed": kind === "personal",
1912
1908
  disabled: isConnecting,
1909
+ title: "Just for you",
1913
1910
  onClick: () => setKind("personal"),
1914
1911
  className: cn(
1915
1912
  "rounded-full border px-2 py-0.5 text-[11px]",
@@ -1919,28 +1916,21 @@ function ConnectorTile({
1919
1916
  children: "Personal"
1920
1917
  }
1921
1918
  ),
1922
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1919
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1923
1920
  "button",
1924
1921
  {
1925
1922
  type: "button",
1926
1923
  "data-testid": `connector-kind-org-${entry.slug}`,
1927
1924
  "aria-pressed": kind === "org",
1928
- disabled: isConnecting || !orgPermitted,
1929
- title: orgPermitted ? void 0 : orgDisabledReason,
1925
+ disabled: isConnecting,
1926
+ title: "For your whole org",
1930
1927
  onClick: () => setKind("org"),
1931
1928
  className: cn(
1932
1929
  "rounded-full border px-2 py-0.5 text-[11px]",
1933
1930
  kind === "org" ? "border-primary bg-primary/10 font-medium" : "border-border text-muted-foreground",
1934
1931
  "disabled:opacity-50"
1935
1932
  ),
1936
- children: [
1937
- "Org",
1938
- !orgPermitted && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "sr-only", children: [
1939
- " (",
1940
- orgDisabledReason,
1941
- ")"
1942
- ] })
1943
- ]
1933
+ children: "Org"
1944
1934
  }
1945
1935
  )
1946
1936
  ]
@@ -1960,7 +1950,11 @@ function ConnectorTile({
1960
1950
  children: isConnecting ? "Reconnecting\u2026" : "Reconnect"
1961
1951
  }
1962
1952
  ),
1963
- canDisconnect && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1953
+ canDisconnect && // DEV-11580: the revoke reassurance lives in the title only —
1954
+ // as an always-visible paragraph it wrapped to four lines
1955
+ // beside every connected tile. Muted until hover so a
1956
+ // destructive action isn't the loudest thing on the tile.
1957
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1964
1958
  "button",
1965
1959
  {
1966
1960
  type: "button",
@@ -1968,27 +1962,10 @@ function ConnectorTile({
1968
1962
  title: DISCONNECT_REVOKES_HINT,
1969
1963
  onClick: () => onDisconnect(entry),
1970
1964
  disabled: isDisconnecting || isConnecting,
1971
- className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-medium text-destructive hover:bg-destructive/10 disabled:opacity-50",
1965
+ className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:opacity-50",
1972
1966
  children: isDisconnecting ? "Disconnecting\u2026" : "Disconnect"
1973
1967
  }
1974
1968
  ),
1975
- canDisconnect && // Outcome-eval finding (DEV-7873): with no width cap, this
1976
- // paragraph's one long sentence forced the WHOLE shrink-0
1977
- // button column to grow to its natural (unwrapped) width,
1978
- // squeezing the sibling `min-w-0 flex-1` text column down to
1979
- // one word per line at any realistic tile width. RTL's jsdom
1980
- // tests never caught it — jsdom doesn't lay out real flexbox
1981
- // sizing, so every textContent assertion still passed. A
1982
- // narrow max-width forces the hint to wrap within the same
1983
- // footprint as the button above it instead.
1984
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1985
- "p",
1986
- {
1987
- "data-testid": `connector-disconnect-hint-${entry.slug}`,
1988
- className: "max-w-28 text-right text-[11px] text-muted-foreground",
1989
- children: DISCONNECT_REVOKES_HINT
1990
- }
1991
- ),
1992
1969
  canManageSharing && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1993
1970
  "button",
1994
1971
  {
@@ -2006,7 +1983,7 @@ function ConnectorTile({
2006
1983
  {
2007
1984
  type: "button",
2008
1985
  "data-testid": `connector-connect-${entry.slug}`,
2009
- onClick: () => onConnect(entry, kind),
1986
+ onClick: () => onConnect(entry, connectKind),
2010
1987
  disabled: isConnecting,
2011
1988
  className: "shrink-0 rounded-md bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground disabled:opacity-50",
2012
1989
  children: isConnecting ? "Connecting\u2026" : "Connect"
@@ -2039,7 +2016,7 @@ function ConnectorTile({
2039
2016
  {
2040
2017
  entry,
2041
2018
  fields: credentialFields,
2042
- kind,
2019
+ kind: connectKind,
2043
2020
  verify: guide?.verify ?? null,
2044
2021
  testSupported: credentialTestSupported,
2045
2022
  onSubmitCredentials,
package/dist/index.mjs CHANGED
@@ -1415,7 +1415,6 @@ var DEFAULT_LOAD_ERROR = "Couldn't load connections. Please try again.";
1415
1415
  var DEFAULT_GRANTS_LOAD_ERROR = "Couldn't load sharing. Please try again.";
1416
1416
  var DEFAULT_GRANT_ERROR = "Couldn't share. Please try again.";
1417
1417
  var DEFAULT_REVOKE_ERROR = "Couldn't revoke access. Please try again.";
1418
- var DEFAULT_ORG_DISABLED_REASON = "Org-wide connections aren't available to you.";
1419
1418
  var DEFAULT_CREDENTIAL_ERROR = "Couldn't save that credential. Please try again.";
1420
1419
  var DEFAULT_CREDENTIAL_TEST_ERROR = "Couldn't test that credential. Please try again.";
1421
1420
  var DEFAULT_RECONNECT_MESSAGE = "This connection needs to be reconnected to keep working.";
@@ -1434,11 +1433,6 @@ function capabilityLabel(capability) {
1434
1433
  if (capability === "write") return "Write only";
1435
1434
  return "Read & write";
1436
1435
  }
1437
- function formatSince(since) {
1438
- const parsed = new Date(since);
1439
- if (Number.isNaN(parsed.getTime())) return since;
1440
- return parsed.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
1441
- }
1442
1436
  function errorMessageFrom(err, fallback) {
1443
1437
  return err instanceof Error && err.message ? err.message : fallback;
1444
1438
  }
@@ -1762,7 +1756,7 @@ function ConnectorTile({
1762
1756
  const guide = entry.guide ?? null;
1763
1757
  const canSetUp = !isConnected && (pasteSupported || guide !== null);
1764
1758
  const orgPermitted = entry.org_connect?.permitted === true;
1765
- const orgDisabledReason = entry.org_connect?.reason || DEFAULT_ORG_DISABLED_REASON;
1759
+ const connectKind = orgPermitted ? kind : "personal";
1766
1760
  const attribution = ownerLabel(entry);
1767
1761
  const canDisconnect = isConnected && !shared;
1768
1762
  const canManageSharing = isConnected && entry.connection.owned_by_viewer === true && grantsSupported;
@@ -1790,19 +1784,21 @@ function ConnectorTile({
1790
1784
  ] }),
1791
1785
  /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [
1792
1786
  /* @__PURE__ */ jsx8("span", { "data-testid": `connector-capability-${entry.slug}`, children: capabilityLabel(entry.capability) }),
1793
- entry.category && /* @__PURE__ */ jsxs7(Fragment4, { children: [
1787
+ isConnected && /* @__PURE__ */ jsxs7(Fragment4, { children: [
1794
1788
  /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", children: "\xB7" }),
1795
- /* @__PURE__ */ jsx8("span", { className: "truncate", children: entry.category })
1789
+ /* @__PURE__ */ jsxs7(
1790
+ "span",
1791
+ {
1792
+ "data-testid": `connector-connected-${entry.slug}`,
1793
+ className: "inline-flex items-center gap-1",
1794
+ children: [
1795
+ /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "h-1.5 w-1.5 rounded-full bg-emerald-500" }),
1796
+ "Connected"
1797
+ ]
1798
+ }
1799
+ )
1796
1800
  ] })
1797
1801
  ] }),
1798
- isConnected && /* @__PURE__ */ jsx8(
1799
- "p",
1800
- {
1801
- "data-testid": `connector-connected-since-${entry.slug}`,
1802
- className: "text-xs text-muted-foreground",
1803
- children: entry.connection.since ? `Connected since ${formatSince(entry.connection.since)}` : "Connected"
1804
- }
1805
- ),
1806
1802
  isConnected && !shared && entry.connection.account_label && /* @__PURE__ */ jsxs7(
1807
1803
  "p",
1808
1804
  {
@@ -1839,7 +1835,7 @@ function ConnectorTile({
1839
1835
  children: attribution
1840
1836
  }
1841
1837
  ),
1842
- !isConnected && /* @__PURE__ */ jsxs7(
1838
+ !isConnected && orgPermitted && /* @__PURE__ */ jsxs7(
1843
1839
  "div",
1844
1840
  {
1845
1841
  "data-testid": `connector-kind-toggle-${entry.slug}`,
@@ -1854,6 +1850,7 @@ function ConnectorTile({
1854
1850
  "data-testid": `connector-kind-personal-${entry.slug}`,
1855
1851
  "aria-pressed": kind === "personal",
1856
1852
  disabled: isConnecting,
1853
+ title: "Just for you",
1857
1854
  onClick: () => setKind("personal"),
1858
1855
  className: cn(
1859
1856
  "rounded-full border px-2 py-0.5 text-[11px]",
@@ -1863,28 +1860,21 @@ function ConnectorTile({
1863
1860
  children: "Personal"
1864
1861
  }
1865
1862
  ),
1866
- /* @__PURE__ */ jsxs7(
1863
+ /* @__PURE__ */ jsx8(
1867
1864
  "button",
1868
1865
  {
1869
1866
  type: "button",
1870
1867
  "data-testid": `connector-kind-org-${entry.slug}`,
1871
1868
  "aria-pressed": kind === "org",
1872
- disabled: isConnecting || !orgPermitted,
1873
- title: orgPermitted ? void 0 : orgDisabledReason,
1869
+ disabled: isConnecting,
1870
+ title: "For your whole org",
1874
1871
  onClick: () => setKind("org"),
1875
1872
  className: cn(
1876
1873
  "rounded-full border px-2 py-0.5 text-[11px]",
1877
1874
  kind === "org" ? "border-primary bg-primary/10 font-medium" : "border-border text-muted-foreground",
1878
1875
  "disabled:opacity-50"
1879
1876
  ),
1880
- children: [
1881
- "Org",
1882
- !orgPermitted && /* @__PURE__ */ jsxs7("span", { className: "sr-only", children: [
1883
- " (",
1884
- orgDisabledReason,
1885
- ")"
1886
- ] })
1887
- ]
1877
+ children: "Org"
1888
1878
  }
1889
1879
  )
1890
1880
  ]
@@ -1904,7 +1894,11 @@ function ConnectorTile({
1904
1894
  children: isConnecting ? "Reconnecting\u2026" : "Reconnect"
1905
1895
  }
1906
1896
  ),
1907
- canDisconnect && /* @__PURE__ */ jsx8(
1897
+ canDisconnect && // DEV-11580: the revoke reassurance lives in the title only —
1898
+ // as an always-visible paragraph it wrapped to four lines
1899
+ // beside every connected tile. Muted until hover so a
1900
+ // destructive action isn't the loudest thing on the tile.
1901
+ /* @__PURE__ */ jsx8(
1908
1902
  "button",
1909
1903
  {
1910
1904
  type: "button",
@@ -1912,27 +1906,10 @@ function ConnectorTile({
1912
1906
  title: DISCONNECT_REVOKES_HINT,
1913
1907
  onClick: () => onDisconnect(entry),
1914
1908
  disabled: isDisconnecting || isConnecting,
1915
- className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-medium text-destructive hover:bg-destructive/10 disabled:opacity-50",
1909
+ className: "shrink-0 rounded-md px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive disabled:opacity-50",
1916
1910
  children: isDisconnecting ? "Disconnecting\u2026" : "Disconnect"
1917
1911
  }
1918
1912
  ),
1919
- canDisconnect && // Outcome-eval finding (DEV-7873): with no width cap, this
1920
- // paragraph's one long sentence forced the WHOLE shrink-0
1921
- // button column to grow to its natural (unwrapped) width,
1922
- // squeezing the sibling `min-w-0 flex-1` text column down to
1923
- // one word per line at any realistic tile width. RTL's jsdom
1924
- // tests never caught it — jsdom doesn't lay out real flexbox
1925
- // sizing, so every textContent assertion still passed. A
1926
- // narrow max-width forces the hint to wrap within the same
1927
- // footprint as the button above it instead.
1928
- /* @__PURE__ */ jsx8(
1929
- "p",
1930
- {
1931
- "data-testid": `connector-disconnect-hint-${entry.slug}`,
1932
- className: "max-w-28 text-right text-[11px] text-muted-foreground",
1933
- children: DISCONNECT_REVOKES_HINT
1934
- }
1935
- ),
1936
1913
  canManageSharing && /* @__PURE__ */ jsx8(
1937
1914
  "button",
1938
1915
  {
@@ -1950,7 +1927,7 @@ function ConnectorTile({
1950
1927
  {
1951
1928
  type: "button",
1952
1929
  "data-testid": `connector-connect-${entry.slug}`,
1953
- onClick: () => onConnect(entry, kind),
1930
+ onClick: () => onConnect(entry, connectKind),
1954
1931
  disabled: isConnecting,
1955
1932
  className: "shrink-0 rounded-md bg-primary px-2.5 py-1 text-xs font-medium text-primary-foreground disabled:opacity-50",
1956
1933
  children: isConnecting ? "Connecting\u2026" : "Connect"
@@ -1983,7 +1960,7 @@ function ConnectorTile({
1983
1960
  {
1984
1961
  entry,
1985
1962
  fields: credentialFields,
1986
- kind,
1963
+ kind: connectKind,
1987
1964
  verify: guide?.verify ?? null,
1988
1965
  testSupported: credentialTestSupported,
1989
1966
  onSubmitCredentials,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meetreeve/ui",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Shared brand-adaptive UI primitives for MindFortress frontends — min-size tokens, a favicon→logo→monogram BrandGlyph, a responsive header that keeps the search bar usable on mobile, and AppSidebar's viewport-driven auto-collapse ladder.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",