@doneisbetter/gds-core 2.6.7 → 3.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.
package/dist/server.js CHANGED
@@ -25,6 +25,7 @@ __export(server_exports, {
25
25
  ArticleShell: () => ArticleShell,
26
26
  AuthShell: () => AuthShell,
27
27
  BrowseSurface: () => BrowseSurface,
28
+ ChartTokenPanel: () => ChartTokenPanel,
28
29
  ChoiceChip: () => ChoiceChip,
29
30
  ConsumerDashboardGrid: () => ConsumerDashboardGrid,
30
31
  ConsumerSection: () => ConsumerSection,
@@ -35,6 +36,7 @@ __export(server_exports, {
35
36
  EditorialCard: () => EditorialCard,
36
37
  EditorialHero: () => EditorialHero,
37
38
  EmptyState: () => EmptyState,
39
+ EvidencePanel: () => EvidencePanel,
38
40
  FeatureBand: () => FeatureBand,
39
41
  FilterDrawer: () => FilterDrawer,
40
42
  FoodMenuSection: () => FoodMenuSection,
@@ -48,6 +50,7 @@ __export(server_exports, {
48
50
  MetricCard: () => MetricCard,
49
51
  PROVIDER_IDENTITY_REGISTRY: () => PROVIDER_IDENTITY_REGISTRY,
50
52
  PageHeader: () => PageHeader,
53
+ PeriodSelector: () => PeriodSelector,
51
54
  PlaceholderPanel: () => PlaceholderPanel,
52
55
  PlaybackSurface: () => PlaybackSurface,
53
56
  ProductCard: () => ProductCard,
@@ -64,6 +67,7 @@ __export(server_exports, {
64
67
  ReferenceLinkGrid: () => ReferenceLinkGrid,
65
68
  ReferenceLocaleNotice: () => ReferenceLocaleNotice,
66
69
  ReferenceSection: () => ReferenceSection,
70
+ ReportingSection: () => ReportingSection,
67
71
  SectionPanel: () => SectionPanel,
68
72
  SimpleDataTable: () => SimpleDataTable,
69
73
  SocialAuthButtons: () => SocialAuthButtons,
@@ -79,8 +83,10 @@ __export(server_exports, {
79
83
  gdsLocales: () => gdsLocales,
80
84
  getGdsMessages: () => getGdsMessages,
81
85
  getProviderIdentityLabel: () => getProviderIdentityLabel,
86
+ getProviderIdentityPolicy: () => getProviderIdentityPolicy,
82
87
  getSemanticActionConfig: () => getSemanticActionConfig,
83
88
  getSemanticActionLabel: () => getSemanticActionLabel,
89
+ getSupportedProviderIdentityIds: () => getSupportedProviderIdentityIds,
84
90
  he: () => he,
85
91
  hu: () => hu,
86
92
  isPresentationMode: () => isPresentationMode,
@@ -1654,10 +1660,14 @@ var import_jsx_runtime27 = require("react/jsx-runtime");
1654
1660
  function AuthShell({
1655
1661
  title,
1656
1662
  description,
1663
+ intent = "sign-in",
1657
1664
  brand,
1658
1665
  headerActions,
1659
1666
  footer,
1660
1667
  helper,
1668
+ error,
1669
+ guestAction,
1670
+ supportAction,
1661
1671
  socialAuth,
1662
1672
  dividerLabel = "Or continue with your account",
1663
1673
  children
@@ -1669,12 +1679,18 @@ function AuthShell({
1669
1679
  ] }) : null,
1670
1680
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Card, { withBorder: true, radius: "lg", padding: "xl", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_core25.Stack, { gap: "lg", children: [
1671
1681
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_core25.Stack, { gap: "xs", ta: "center", children: [
1682
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Group, { justify: "center", children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Badge, { variant: "light", color: intent === "account-linking" ? "blue" : intent === "guest-entry" ? "gray" : "teal", children: intent.replace("-", " ") }) }),
1672
1683
  /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Title, { order: 2, children: title }),
1673
1684
  description ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Text, { c: "dimmed", size: "sm", children: description }) : null
1674
1685
  ] }),
1686
+ error ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Alert, { color: "red", variant: "light", role: "alert", children: error }) : null,
1675
1687
  socialAuth ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Box, { children: socialAuth }) : null,
1676
1688
  socialAuth ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Divider, { label: dividerLabel, labelPosition: "center" }) : null,
1677
1689
  children,
1690
+ guestAction || supportAction ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_core25.Group, { justify: "center", gap: "sm", children: [
1691
+ guestAction,
1692
+ supportAction
1693
+ ] }) : null,
1678
1694
  helper ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Text, { size: "sm", c: "dimmed", ta: "center", children: helper }) : null
1679
1695
  ] }) }),
1680
1696
  footer ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_core25.Text, { size: "sm", c: "dimmed", ta: "center", children: footer }) : null
@@ -1776,6 +1792,20 @@ function mapVariant(variant = "neutral") {
1776
1792
  function getProviderIdentityLabel(provider, fallbackOverride) {
1777
1793
  return resolveProviderLabel(provider, fallbackOverride);
1778
1794
  }
1795
+ function getSupportedProviderIdentityIds() {
1796
+ return Object.keys(PROVIDER_IDENTITY_REGISTRY);
1797
+ }
1798
+ function getProviderIdentityPolicy(provider) {
1799
+ const meta = getProviderIdentityMeta(provider);
1800
+ return {
1801
+ id: meta.id,
1802
+ supported: meta.supported,
1803
+ providerLabel: meta.providerLabel,
1804
+ colorAuthority: meta.supported ? "provider" : "gds-neutral",
1805
+ minTouchTargetPx: 44,
1806
+ allowedVariants: ["solid", "outline", "neutral"]
1807
+ };
1808
+ }
1779
1809
  function ProviderIdentityMark({ provider }) {
1780
1810
  const meta = getProviderIdentityMeta(provider);
1781
1811
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
@@ -1794,10 +1824,13 @@ function ProviderIdentityButton({
1794
1824
  provider,
1795
1825
  label,
1796
1826
  description,
1827
+ policyNote,
1828
+ error,
1797
1829
  href,
1798
1830
  onClick,
1799
1831
  disabled,
1800
1832
  loading,
1833
+ tenantDisabledReason,
1801
1834
  fullWidth = true,
1802
1835
  size = "md",
1803
1836
  variant = "neutral",
@@ -1807,6 +1840,7 @@ function ProviderIdentityButton({
1807
1840
  }) {
1808
1841
  const meta = getProviderIdentityMeta(provider);
1809
1842
  const buttonLabel = resolveProviderLabel(provider, label);
1843
+ const resolvedDisabled = disabled || Boolean(tenantDisabledReason);
1810
1844
  const buttonProps = href ? {
1811
1845
  component: "a",
1812
1846
  href
@@ -1824,13 +1858,16 @@ function ProviderIdentityButton({
1824
1858
  "aria-label": ariaLabel ?? (typeof buttonLabel === "string" ? buttonLabel : void 0),
1825
1859
  "aria-describedby": describedBy,
1826
1860
  leftSection: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(ProviderIdentityMark, { provider }),
1827
- disabled,
1861
+ disabled: resolvedDisabled,
1828
1862
  loading,
1829
1863
  styles: { root: { minHeight: minTouchTargetPx } },
1830
1864
  ...buttonProps,
1831
1865
  children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_core26.Stack, { gap: 0, align: "flex-start", children: [
1832
1866
  /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Text, { inherit: true, children: buttonLabel }),
1833
- description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Text, { size: "xs", c: "dimmed", lh: 1.2, children: description }) : null
1867
+ description ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Text, { size: "xs", c: "dimmed", lh: 1.2, children: description }) : null,
1868
+ policyNote ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Text, { size: "xs", c: "dimmed", lh: 1.2, children: policyNote }) : null,
1869
+ tenantDisabledReason ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Text, { size: "xs", c: "orange.7", lh: 1.2, children: tenantDisabledReason }) : null,
1870
+ error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_core26.Text, { size: "xs", c: "red.7", lh: 1.2, role: "alert", children: error }) : null
1834
1871
  ] })
1835
1872
  }
1836
1873
  );
@@ -1865,10 +1902,13 @@ function SocialAuthButtons({
1865
1902
  provider: provider.id,
1866
1903
  label: provider.label,
1867
1904
  description: provider.description,
1905
+ policyNote: provider.policyNote,
1906
+ error: provider.error,
1868
1907
  href: provider.href,
1869
1908
  onClick: provider.onClick,
1870
1909
  disabled: provider.disabled,
1871
1910
  loading: provider.loading,
1911
+ tenantDisabledReason: provider.tenantDisabledReason,
1872
1912
  size: provider.size ?? (compact ? "sm" : "md"),
1873
1913
  variant: provider.variant
1874
1914
  }));
@@ -2550,10 +2590,17 @@ function FormField({ label, description, error, children }) {
2550
2590
  var import_jsx_runtime40 = require("react/jsx-runtime");
2551
2591
  var stateLabels = {
2552
2592
  empty: { label: "Empty", color: "gray" },
2593
+ "drag-active": { label: "Drop to select", color: "violet" },
2553
2594
  selected: { label: "Selected", color: "blue" },
2595
+ "preview-loading": { label: "Preview loading", color: "violet" },
2554
2596
  saved: { label: "Saved", color: "teal" },
2555
2597
  invalid: { label: "Needs attention", color: "red" },
2556
- uploading: { label: "Uploading", color: "violet" }
2598
+ uploading: { label: "Uploading", color: "violet" },
2599
+ "upload-failed": { label: "Upload failed", color: "red" },
2600
+ "unsupported-type": { label: "Unsupported type", color: "red" },
2601
+ "too-large": { label: "Too large", color: "red" },
2602
+ removed: { label: "Removed", color: "gray" },
2603
+ readonly: { label: "Read only", color: "gray" }
2557
2604
  };
2558
2605
  function MediaField({
2559
2606
  label,
@@ -2566,17 +2613,24 @@ function MediaField({
2566
2613
  policyText,
2567
2614
  error,
2568
2615
  retryAction,
2616
+ replaceAction,
2569
2617
  onRemove,
2570
2618
  onReset,
2571
2619
  removeAction,
2572
2620
  resetAction,
2573
2621
  statusAction,
2622
+ acceptedTypes,
2623
+ maxSize,
2624
+ progress,
2625
+ readonly = false,
2574
2626
  state = "empty",
2575
2627
  mode = "stacked"
2576
2628
  }) {
2577
- const stateBadge = stateLabels[state];
2578
- const resolvedRemoveAction = removeAction ?? (onRemove ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Button, { type: "button", variant: "light", color: "red", onClick: onRemove, children: "Remove" }) : null);
2579
- const resolvedResetAction = resetAction ?? (onReset ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Button, { type: "button", variant: "default", onClick: onReset, children: "Reset" }) : null);
2629
+ const resolvedState = readonly ? "readonly" : state;
2630
+ const stateBadge = stateLabels[resolvedState];
2631
+ const resolvedRemoveAction = removeAction ?? (!readonly && onRemove ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Button, { type: "button", variant: "light", color: "red", onClick: onRemove, children: "Remove" }) : null);
2632
+ const resolvedResetAction = resetAction ?? (!readonly && onReset ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Button, { type: "button", variant: "default", onClick: onReset, children: "Reset" }) : null);
2633
+ const boundedProgress = typeof progress === "number" ? Math.max(0, Math.min(100, progress)) : void 0;
2580
2634
  return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
2581
2635
  FormField,
2582
2636
  {
@@ -2589,7 +2643,14 @@ function MediaField({
2589
2643
  statusAction
2590
2644
  ] }) }),
2591
2645
  preview ? preview : null,
2592
- uploadControl || urlInput ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
2646
+ typeof boundedProgress === "number" ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Stack, { gap: 4, children: [
2647
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Progress, { value: boundedProgress, "aria-label": "Upload progress" }),
2648
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Text, { size: "xs", c: "dimmed", children: [
2649
+ boundedProgress,
2650
+ "% complete"
2651
+ ] })
2652
+ ] }) : null,
2653
+ (uploadControl || urlInput) && !readonly ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
2593
2654
  /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Divider, {}),
2594
2655
  /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Stack, { gap: "sm", style: mode === "split" ? { display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))" } : void 0, children: [
2595
2656
  uploadControl,
@@ -2598,9 +2659,14 @@ function MediaField({
2598
2659
  ] }) : null,
2599
2660
  value ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Text, { size: "sm", c: "dimmed", style: { wordBreak: "break-all" }, children: value }) : null,
2600
2661
  helpText ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Text, { size: "sm", c: "dimmed", children: helpText }) : null,
2662
+ acceptedTypes || maxSize ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Group, { gap: "xs", wrap: "wrap", children: [
2663
+ acceptedTypes ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Badge, { variant: "outline", color: "gray", children: acceptedTypes }) : null,
2664
+ maxSize ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Badge, { variant: "outline", color: "gray", children: maxSize }) : null
2665
+ ] }) : null,
2601
2666
  policyText ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_core38.Text, { size: "sm", c: error ? "red.7" : "dimmed", children: policyText }) : null,
2602
2667
  typeof error !== "string" && error ? error : null,
2603
- resolvedRemoveAction || resolvedResetAction ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Group, { gap: "sm", children: [
2668
+ replaceAction || resolvedRemoveAction || resolvedResetAction || retryAction ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_core38.Group, { gap: "sm", children: [
2669
+ replaceAction,
2604
2670
  resolvedResetAction,
2605
2671
  retryAction,
2606
2672
  resolvedRemoveAction
@@ -2636,17 +2702,31 @@ function MediaCard({ title, image, description, status, overlay, actions = [] })
2636
2702
  // src/AccessSummary.tsx
2637
2703
  var import_core40 = require("@mantine/core");
2638
2704
  var import_jsx_runtime42 = require("react/jsx-runtime");
2639
- function AccessSummary({ title, roles, scope, blocked = false, description }) {
2705
+ var accessStateMeta = {
2706
+ allowed: { label: "Allowed", color: "teal" },
2707
+ blocked: { label: "Blocked", color: "red" },
2708
+ forbidden: { label: "Forbidden", color: "red" },
2709
+ expired: { label: "Expired", color: "orange" },
2710
+ "permission-limited": { label: "Permission limited", color: "grape" }
2711
+ };
2712
+ function AccessSummary({ title, roles, scope, blocked = false, state, owner, recoveryHint, description }) {
2713
+ const resolvedState = state ?? (blocked ? "blocked" : "allowed");
2714
+ const meta = accessStateMeta[resolvedState];
2640
2715
  return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Card, { withBorder: true, radius: "lg", padding: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.Stack, { gap: "sm", children: [
2641
2716
  /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.Group, { justify: "space-between", align: "center", children: [
2642
2717
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Title, { order: 4, children: title }),
2643
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Badge, { color: blocked ? "red" : "teal", variant: "light", children: blocked ? "Blocked" : "Allowed" })
2718
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Badge, { color: meta.color, variant: "light", children: meta.label })
2644
2719
  ] }),
2645
2720
  /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Group, { gap: "xs", children: roles.map((role) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Badge, { variant: "outline", children: role }, role)) }),
2646
2721
  scope ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.Text, { size: "sm", c: "dimmed", children: [
2647
2722
  "Scope: ",
2648
2723
  scope
2649
2724
  ] }) : null,
2725
+ owner ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_core40.Text, { size: "sm", c: "dimmed", children: [
2726
+ "Owner: ",
2727
+ owner
2728
+ ] }) : null,
2729
+ recoveryHint ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Text, { size: "sm", c: resolvedState === "allowed" ? "dimmed" : "red.7", children: recoveryHint }) : null,
2650
2730
  description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_core40.Text, { size: "sm", children: description }) : null
2651
2731
  ] }) });
2652
2732
  }
@@ -2812,6 +2892,202 @@ function StatsSection({
2812
2892
  ] });
2813
2893
  }
2814
2894
 
2895
+ // src/PeriodSelector.tsx
2896
+ var import_core46 = require("@mantine/core");
2897
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2898
+ function PeriodSelector({
2899
+ label,
2900
+ description,
2901
+ value,
2902
+ options,
2903
+ onChange,
2904
+ timezone,
2905
+ scope,
2906
+ helperText,
2907
+ error,
2908
+ stale = false,
2909
+ filtered = false,
2910
+ disabled = false
2911
+ }) {
2912
+ const selectedOption = options.find((option) => option.value === value);
2913
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(FormField, { label, description, error, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Stack, { gap: "sm", children: [
2914
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
2915
+ "select",
2916
+ {
2917
+ "aria-label": typeof label === "string" ? label : "Reporting period",
2918
+ value,
2919
+ disabled,
2920
+ onChange: (event) => onChange?.(event.currentTarget.value),
2921
+ children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("option", { value: option.value, children: option.label }, option.value))
2922
+ }
2923
+ ),
2924
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Group, { gap: "xs", wrap: "wrap", children: [
2925
+ timezone ? /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_core46.Badge, { variant: "outline", color: "gray", children: [
2926
+ "Timezone: ",
2927
+ timezone
2928
+ ] }) : null,
2929
+ filtered ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Badge, { variant: "light", color: "blue", children: "Filtered" }) : null,
2930
+ stale ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Badge, { variant: "light", color: "orange", children: "Stale data" }) : null,
2931
+ scope ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Badge, { variant: "outline", color: "gray", children: scope }) : null
2932
+ ] }),
2933
+ selectedOption?.description ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Text, { size: "sm", c: "dimmed", children: selectedOption.description }) : null,
2934
+ helperText ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_core46.Text, { size: "sm", c: "dimmed", children: helperText }) : null
2935
+ ] }) });
2936
+ }
2937
+
2938
+ // src/EvidencePanel.tsx
2939
+ var import_core47 = require("@mantine/core");
2940
+ var import_jsx_runtime49 = require("react/jsx-runtime");
2941
+ var stateTone2 = {
2942
+ current: { label: "Current", color: "teal" },
2943
+ stale: { label: "Stale", color: "orange" },
2944
+ partial: { label: "Partial data", color: "yellow" },
2945
+ "permission-limited": { label: "Permission limited", color: "grape" },
2946
+ loading: { label: "Loading", color: "blue" },
2947
+ empty: { label: "No evidence", color: "gray" },
2948
+ error: { label: "Needs attention", color: "red" }
2949
+ };
2950
+ function EvidencePanel({
2951
+ title,
2952
+ description,
2953
+ source,
2954
+ freshness,
2955
+ confidence,
2956
+ state = "current",
2957
+ evidenceCount,
2958
+ permissionNote,
2959
+ retryAction,
2960
+ details,
2961
+ children
2962
+ }) {
2963
+ const tone = stateTone2[state];
2964
+ const isProblem = state === "error" || state === "permission-limited" || state === "stale" || state === "partial";
2965
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Stack, { gap: "md", children: [
2966
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
2967
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Stack, { gap: 4, children: [
2968
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Title, { order: 4, children: title }),
2969
+ description ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Text, { size: "sm", c: "dimmed", children: description }) : null
2970
+ ] }),
2971
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Badge, { variant: "light", color: tone.color, children: tone.label })
2972
+ ] }),
2973
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Group, { gap: "xs", wrap: "wrap", children: [
2974
+ source ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Badge, { variant: "outline", color: "gray", children: [
2975
+ "Source: ",
2976
+ source
2977
+ ] }) : null,
2978
+ freshness ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Badge, { variant: "outline", color: "gray", children: [
2979
+ "Freshness: ",
2980
+ freshness
2981
+ ] }) : null,
2982
+ confidence ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Badge, { variant: "outline", color: "gray", children: [
2983
+ "Confidence: ",
2984
+ confidence
2985
+ ] }) : null,
2986
+ typeof evidenceCount === "number" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_core47.Badge, { variant: "outline", color: "gray", children: [
2987
+ "Evidence: ",
2988
+ evidenceCount
2989
+ ] }) : null
2990
+ ] }),
2991
+ permissionNote ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_core47.Alert, { color: isProblem ? tone.color : "gray", variant: "light", children: permissionNote }) : null,
2992
+ details,
2993
+ children,
2994
+ retryAction
2995
+ ] }) });
2996
+ }
2997
+
2998
+ // src/ChartTokenPanel.tsx
2999
+ var import_core48 = require("@mantine/core");
3000
+ var import_jsx_runtime50 = require("react/jsx-runtime");
3001
+ function ChartTokenPanel({
3002
+ title,
3003
+ description,
3004
+ summary,
3005
+ state = "ready",
3006
+ legend = [],
3007
+ children,
3008
+ tableFallback,
3009
+ retryAction
3010
+ }) {
3011
+ if (state === "loading") {
3012
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(StateBlock, { variant: "loading", title: "Loading chart", description: summary, compact: true, action: retryAction });
3013
+ }
3014
+ if (state === "empty") {
3015
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(StateBlock, { variant: "empty", title: "No chart data", description: summary, compact: true, action: retryAction });
3016
+ }
3017
+ if (state === "below-threshold") {
3018
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(StateBlock, { variant: "not-enough-data", title: "Not enough data for chart", description: summary, compact: true, action: retryAction });
3019
+ }
3020
+ if (state === "error") {
3021
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(StateBlock, { variant: "error", title: "Unable to load chart", description: summary, compact: true, action: retryAction });
3022
+ }
3023
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core48.Stack, { gap: "md", children: [
3024
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core48.Group, { justify: "space-between", align: "flex-start", gap: "sm", children: [
3025
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core48.Stack, { gap: 4, children: [
3026
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Title, { order: 4, children: title }),
3027
+ description ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Text, { size: "sm", c: "dimmed", children: description }) : null
3028
+ ] }),
3029
+ state !== "ready" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Badge, { variant: "light", color: state === "permission-limited" ? "grape" : "yellow", children: state.replace("-", " ") }) : null
3030
+ ] }),
3031
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Text, { size: "sm", children: summary }),
3032
+ legend.length ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Group, { gap: "xs", wrap: "wrap", "aria-label": "Chart legend", children: legend.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core48.Badge, { variant: "outline", color: "gray", title: typeof item.description === "string" ? item.description : void 0, children: [
3033
+ item.label,
3034
+ ": ",
3035
+ item.token
3036
+ ] }, `${String(item.label)}-${index}`)) }) : null,
3037
+ children,
3038
+ tableFallback ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_core48.Stack, { gap: "xs", children: [
3039
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(import_core48.Text, { size: "sm", fw: 600, children: "Accessible data fallback" }),
3040
+ tableFallback
3041
+ ] }) : null
3042
+ ] }) });
3043
+ }
3044
+
3045
+ // src/ReportingSection.tsx
3046
+ var import_core49 = require("@mantine/core");
3047
+ var import_jsx_runtime51 = require("react/jsx-runtime");
3048
+ function ReportingSection({
3049
+ title,
3050
+ description,
3051
+ state = "ready",
3052
+ periodControl,
3053
+ evidence,
3054
+ metrics,
3055
+ chart,
3056
+ table,
3057
+ action,
3058
+ stateMessage,
3059
+ retryAction
3060
+ }) {
3061
+ let stateBlock = null;
3062
+ if (state === "loading") {
3063
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StateBlock, { variant: "loading", title: "Loading report", description: stateMessage ?? "The reporting surface is synchronizing.", compact: true });
3064
+ } else if (state === "empty") {
3065
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StateBlock, { variant: "empty", title: "No report data", description: stateMessage ?? "No records match this reporting scope yet.", compact: true });
3066
+ } else if (state === "error") {
3067
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StateBlock, { variant: "error", title: "Unable to load report", description: stateMessage ?? "The report could not be prepared.", compact: true, action: retryAction });
3068
+ } else if (state === "below-threshold") {
3069
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StateBlock, { variant: "not-enough-data", title: "Not enough data", description: stateMessage ?? "This report is hidden until the threshold is met.", compact: true });
3070
+ } else if (state === "permission-limited") {
3071
+ stateBlock = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StateBlock, { variant: "permission", title: "Permission-limited report", description: stateMessage ?? "Some evidence is hidden by access rules.", compact: true, action: retryAction });
3072
+ }
3073
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Paper, { withBorder: true, radius: "xl", p: "lg", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Stack, { gap: "lg", children: [
3074
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Group, { justify: "space-between", align: "flex-start", gap: "md", children: [
3075
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_core49.Stack, { gap: 4, children: [
3076
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Title, { order: 3, children: title }),
3077
+ description ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_core49.Text, { size: "sm", c: "dimmed", children: description }) : null
3078
+ ] }),
3079
+ action
3080
+ ] }),
3081
+ periodControl,
3082
+ (state === "partial" || state === "stale" || state === "filtered") && stateMessage ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StateBlock, { variant: "info", title: state === "partial" ? "Partial report" : state === "stale" ? "Stale report" : "Filtered report", description: stateMessage, compact: true }) : null,
3083
+ stateBlock,
3084
+ metrics,
3085
+ chart,
3086
+ table,
3087
+ evidence
3088
+ ] }) });
3089
+ }
3090
+
2815
3091
  // src/locales/ar.ts
2816
3092
  var ar = {
2817
3093
  "gds.action.settings": "\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A",
@@ -4121,6 +4397,7 @@ function getGdsMessages(locale) {
4121
4397
  ArticleShell,
4122
4398
  AuthShell,
4123
4399
  BrowseSurface,
4400
+ ChartTokenPanel,
4124
4401
  ChoiceChip,
4125
4402
  ConsumerDashboardGrid,
4126
4403
  ConsumerSection,
@@ -4131,6 +4408,7 @@ function getGdsMessages(locale) {
4131
4408
  EditorialCard,
4132
4409
  EditorialHero,
4133
4410
  EmptyState,
4411
+ EvidencePanel,
4134
4412
  FeatureBand,
4135
4413
  FilterDrawer,
4136
4414
  FoodMenuSection,
@@ -4144,6 +4422,7 @@ function getGdsMessages(locale) {
4144
4422
  MetricCard,
4145
4423
  PROVIDER_IDENTITY_REGISTRY,
4146
4424
  PageHeader,
4425
+ PeriodSelector,
4147
4426
  PlaceholderPanel,
4148
4427
  PlaybackSurface,
4149
4428
  ProductCard,
@@ -4160,6 +4439,7 @@ function getGdsMessages(locale) {
4160
4439
  ReferenceLinkGrid,
4161
4440
  ReferenceLocaleNotice,
4162
4441
  ReferenceSection,
4442
+ ReportingSection,
4163
4443
  SectionPanel,
4164
4444
  SimpleDataTable,
4165
4445
  SocialAuthButtons,
@@ -4175,8 +4455,10 @@ function getGdsMessages(locale) {
4175
4455
  gdsLocales,
4176
4456
  getGdsMessages,
4177
4457
  getProviderIdentityLabel,
4458
+ getProviderIdentityPolicy,
4178
4459
  getSemanticActionConfig,
4179
4460
  getSemanticActionLabel,
4461
+ getSupportedProviderIdentityIds,
4180
4462
  he,
4181
4463
  hu,
4182
4464
  isPresentationMode,
package/dist/server.mjs CHANGED
@@ -4,6 +4,7 @@ import {
4
4
  ArticleShell,
5
5
  AuthShell,
6
6
  BrowseSurface,
7
+ ChartTokenPanel,
7
8
  ChoiceChip,
8
9
  ConsumerDashboardGrid,
9
10
  ConsumerSection,
@@ -14,6 +15,7 @@ import {
14
15
  EditorialCard,
15
16
  EditorialHero,
16
17
  EmptyState,
18
+ EvidencePanel,
17
19
  FeatureBand,
18
20
  FilterDrawer,
19
21
  FoodMenuSection,
@@ -27,6 +29,7 @@ import {
27
29
  MetricCard,
28
30
  PROVIDER_IDENTITY_REGISTRY,
29
31
  PageHeader,
32
+ PeriodSelector,
30
33
  PlaceholderPanel,
31
34
  PlaybackSurface,
32
35
  ProductCard,
@@ -43,6 +46,7 @@ import {
43
46
  ReferenceLinkGrid,
44
47
  ReferenceLocaleNotice,
45
48
  ReferenceSection,
49
+ ReportingSection,
46
50
  SectionPanel,
47
51
  SimpleDataTable,
48
52
  SocialAuthButtons,
@@ -58,8 +62,10 @@ import {
58
62
  gdsLocales,
59
63
  getGdsMessages,
60
64
  getProviderIdentityLabel,
65
+ getProviderIdentityPolicy,
61
66
  getSemanticActionConfig,
62
67
  getSemanticActionLabel,
68
+ getSupportedProviderIdentityIds,
63
69
  he,
64
70
  hu,
65
71
  isPresentationMode,
@@ -69,13 +75,14 @@ import {
69
75
  resolveSemanticActionConfig,
70
76
  resolveSurfacePresentationStyles,
71
77
  ru
72
- } from "./chunk-LH2KMMXT.mjs";
78
+ } from "./chunk-P7ICTEEB.mjs";
73
79
  export {
74
80
  AccentPanel,
75
81
  AccessSummary,
76
82
  ArticleShell,
77
83
  AuthShell,
78
84
  BrowseSurface,
85
+ ChartTokenPanel,
79
86
  ChoiceChip,
80
87
  ConsumerDashboardGrid,
81
88
  ConsumerSection,
@@ -86,6 +93,7 @@ export {
86
93
  EditorialCard,
87
94
  EditorialHero,
88
95
  EmptyState,
96
+ EvidencePanel,
89
97
  FeatureBand,
90
98
  FilterDrawer,
91
99
  FoodMenuSection,
@@ -99,6 +107,7 @@ export {
99
107
  MetricCard,
100
108
  PROVIDER_IDENTITY_REGISTRY,
101
109
  PageHeader,
110
+ PeriodSelector,
102
111
  PlaceholderPanel,
103
112
  PlaybackSurface,
104
113
  ProductCard,
@@ -115,6 +124,7 @@ export {
115
124
  ReferenceLinkGrid,
116
125
  ReferenceLocaleNotice,
117
126
  ReferenceSection,
127
+ ReportingSection,
118
128
  SectionPanel,
119
129
  SimpleDataTable,
120
130
  SocialAuthButtons,
@@ -130,8 +140,10 @@ export {
130
140
  gdsLocales,
131
141
  getGdsMessages,
132
142
  getProviderIdentityLabel,
143
+ getProviderIdentityPolicy,
133
144
  getSemanticActionConfig,
134
145
  getSemanticActionLabel,
146
+ getSupportedProviderIdentityIds,
135
147
  he,
136
148
  hu,
137
149
  isPresentationMode,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doneisbetter/gds-core",
3
- "version": "2.6.7",
3
+ "version": "3.0.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -38,7 +38,7 @@
38
38
  "dev": "tsup --watch"
39
39
  },
40
40
  "peerDependencies": {
41
- "@doneisbetter/gds-theme": "^2.6.7",
41
+ "@doneisbetter/gds-theme": "^3.0.0",
42
42
  "@mantine/core": "^7.9.0 || ^8.3.0 || ^9.0.0",
43
43
  "@mantine/hooks": "^7.9.0 || ^8.3.0 || ^9.0.0",
44
44
  "@tabler/icons-react": "^3.5.0",