@trops/dash-core 0.1.139 → 0.1.141

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.esm.js CHANGED
@@ -31240,7 +31240,8 @@ var GENERATE_MODES = {
31240
31240
  NONE: null,
31241
31241
  PRESETS: "presets",
31242
31242
  COLOR: "color",
31243
- WIZARD: "wizard"
31243
+ WIZARD: "wizard",
31244
+ CHOOSER: "chooser"
31244
31245
  };
31245
31246
 
31246
31247
  // ─── Preset Gallery ──────────────────────────────────────────────────────
@@ -31534,7 +31535,7 @@ var ThemeQuickCreate = function ThemeQuickCreate(_ref8) {
31534
31535
  className: "text-sm font-semibold opacity-50",
31535
31536
  children: "Generation Method"
31536
31537
  }), /*#__PURE__*/jsxs("div", {
31537
- className: "grid grid-cols-2 gap-2",
31538
+ className: "flex flex-col gap-2",
31538
31539
  children: [/*#__PURE__*/jsx(MethodCard, {
31539
31540
  icon: "swatchbook",
31540
31541
  title: "Presets",
@@ -31551,15 +31552,15 @@ var ThemeQuickCreate = function ThemeQuickCreate(_ref8) {
31551
31552
  onClick: function onClick() {
31552
31553
  return handleMethodSelect("random");
31553
31554
  }
31555
+ }), /*#__PURE__*/jsx(MethodCard, {
31556
+ icon: "droplet",
31557
+ title: "From Color",
31558
+ subtitle: "Build from a base color with harmony rules",
31559
+ selected: wizardMethod === "color",
31560
+ onClick: function onClick() {
31561
+ return handleMethodSelect("color");
31562
+ }
31554
31563
  })]
31555
- }), /*#__PURE__*/jsx(MethodCard, {
31556
- icon: "droplet",
31557
- title: "From Color",
31558
- subtitle: "Build from a base color with harmony rules",
31559
- selected: wizardMethod === "color",
31560
- onClick: function onClick() {
31561
- return handleMethodSelect("color");
31562
- }
31563
31564
  })]
31564
31565
  }), wizardMethod === "presets" && /*#__PURE__*/jsx(PresetGallery, {
31565
31566
  onSelect: function onSelect(preset) {
@@ -31586,126 +31587,836 @@ var ThemeQuickCreate = function ThemeQuickCreate(_ref8) {
31586
31587
  });
31587
31588
  };
31588
31589
 
31589
- function ownKeys$b(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
31590
- function _objectSpread$b(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$b(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$b(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
31591
- var ThemeManagerModal = function ThemeManagerModal(_ref) {
31592
- var open = _ref.open,
31593
- setIsOpen = _ref.setIsOpen;
31590
+ var ChooserCard = function ChooserCard(_ref) {
31591
+ var icon = _ref.icon,
31592
+ title = _ref.title,
31593
+ subtitle = _ref.subtitle,
31594
+ onClick = _ref.onClick;
31595
+ return /*#__PURE__*/jsxs("div", {
31596
+ className: "flex flex-col gap-1.5 p-4 rounded-lg cursor-pointer transition-all bg-white/5 hover:bg-white/10 hover:ring-1 hover:ring-white/20",
31597
+ onClick: onClick,
31598
+ children: [/*#__PURE__*/jsxs("div", {
31599
+ className: "flex flex-row items-center gap-2",
31600
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
31601
+ icon: icon,
31602
+ className: "h-3.5 w-3.5 opacity-50"
31603
+ }), /*#__PURE__*/jsx("span", {
31604
+ className: "text-sm font-medium",
31605
+ children: title
31606
+ })]
31607
+ }), /*#__PURE__*/jsx("span", {
31608
+ className: "text-xs opacity-40",
31609
+ children: subtitle
31610
+ })]
31611
+ });
31612
+ };
31613
+ var ThemeNewChooser = function ThemeNewChooser(_ref2) {
31614
+ var onSearchThemes = _ref2.onSearchThemes,
31615
+ onCreateNew = _ref2.onCreateNew;
31616
+ return /*#__PURE__*/jsxs("div", {
31617
+ className: "flex flex-col gap-6 p-6 overflow-y-auto flex-1 min-h-0",
31618
+ children: [/*#__PURE__*/jsx("span", {
31619
+ className: "text-sm font-semibold opacity-50",
31620
+ children: "Add a Theme"
31621
+ }), /*#__PURE__*/jsxs("div", {
31622
+ className: "grid grid-cols-2 gap-3",
31623
+ children: [/*#__PURE__*/jsx(ChooserCard, {
31624
+ icon: "magnifying-glass",
31625
+ title: "Search for Themes",
31626
+ subtitle: "Browse the theme marketplace",
31627
+ onClick: onSearchThemes
31628
+ }), /*#__PURE__*/jsx(ChooserCard, {
31629
+ icon: "wand-magic-sparkles",
31630
+ title: "Create New",
31631
+ subtitle: "Build from presets, random palettes, or color harmony rules",
31632
+ onClick: onCreateNew
31633
+ })]
31634
+ })]
31635
+ });
31636
+ };
31637
+
31638
+ /**
31639
+ * Shared Tailwind color utilities.
31640
+ *
31641
+ * Single source of truth for mapping Tailwind color family names to hex values.
31642
+ * Used by both renderer components (theme detail/discovery) and electron
31643
+ * controllers (theme publish/install).
31644
+ */
31645
+
31646
+ // Tailwind color family name → representative hex (500 shade)
31647
+ var TAILWIND_COLORS = {
31648
+ slate: "#64748b",
31649
+ gray: "#6b7280",
31650
+ zinc: "#71717a",
31651
+ neutral: "#737373",
31652
+ stone: "#78716c",
31653
+ red: "#ef4444",
31654
+ orange: "#f97316",
31655
+ amber: "#f59e0b",
31656
+ yellow: "#eab308",
31657
+ lime: "#84cc16",
31658
+ green: "#22c55e",
31659
+ emerald: "#10b981",
31660
+ teal: "#14b8a6",
31661
+ cyan: "#06b6d4",
31662
+ sky: "#0ea5e9",
31663
+ blue: "#3b82f6",
31664
+ indigo: "#6366f1",
31665
+ violet: "#8b5cf6",
31666
+ purple: "#a855f7",
31667
+ fuchsia: "#d946ef",
31668
+ pink: "#ec4899",
31669
+ rose: "#f43f5e"
31670
+ };
31671
+
31672
+ /**
31673
+ * Convert a color value to a CSS-usable color.
31674
+ * If it's a Tailwind family name, map to its hex 500 shade.
31675
+ * If it already looks like a hex/rgb/hsl value, return as-is.
31676
+ */
31677
+ function toDisplayColor(value) {
31678
+ if (!value) return "";
31679
+ var lower = value.toLowerCase().trim();
31680
+ return TAILWIND_COLORS[lower] || value;
31681
+ }
31682
+
31683
+ function adjustColor(hex, amount) {
31684
+ if (!hex || !hex.startsWith("#")) return hex;
31685
+ var num = parseInt(hex.slice(1), 16);
31686
+ var r = Math.min(255, Math.max(0, (num >> 16 & 0xff) + Math.round(255 * amount)));
31687
+ var g = Math.min(255, Math.max(0, (num >> 8 & 0xff) + Math.round(255 * amount)));
31688
+ var b = Math.min(255, Math.max(0, (num & 0xff) + Math.round(255 * amount)));
31689
+ return "#".concat((r << 16 | g << 8 | b).toString(16).padStart(6, "0"));
31690
+ }
31691
+
31692
+ /**
31693
+ * ThemePreviewMockup — renders a mini dashboard mockup using theme colors.
31694
+ */
31695
+ var ThemePreviewMockup = function ThemePreviewMockup(_ref) {
31696
+ var colors = _ref.colors;
31697
+ var primary = colors.primary,
31698
+ secondary = colors.secondary,
31699
+ tertiary = colors.tertiary,
31700
+ neutral = colors.neutral;
31701
+ var bg = neutral || adjustColor(primary, -0.6);
31702
+ var sidebar = adjustColor(primary, -0.5);
31703
+ var header = adjustColor(primary, -0.4);
31704
+ return /*#__PURE__*/jsxs("div", {
31705
+ className: "flex flex-col gap-2",
31706
+ children: [/*#__PURE__*/jsx("span", {
31707
+ className: "text-xs font-semibold opacity-50",
31708
+ children: "PREVIEW"
31709
+ }), /*#__PURE__*/jsx("div", {
31710
+ className: "rounded-lg overflow-hidden border border-white/10",
31711
+ style: {
31712
+ backgroundColor: bg,
31713
+ minHeight: 160
31714
+ },
31715
+ children: /*#__PURE__*/jsxs("div", {
31716
+ className: "flex flex-row h-full",
31717
+ style: {
31718
+ minHeight: 160
31719
+ },
31720
+ children: [/*#__PURE__*/jsxs("div", {
31721
+ className: "flex flex-col gap-1.5 p-2 w-24 flex-shrink-0",
31722
+ style: {
31723
+ backgroundColor: sidebar
31724
+ },
31725
+ children: [/*#__PURE__*/jsx("div", {
31726
+ className: "h-2 w-12 rounded-sm opacity-60",
31727
+ style: {
31728
+ backgroundColor: primary
31729
+ }
31730
+ }), /*#__PURE__*/jsx("div", {
31731
+ className: "h-2 w-16 rounded-sm opacity-30",
31732
+ style: {
31733
+ backgroundColor: secondary
31734
+ }
31735
+ }), /*#__PURE__*/jsx("div", {
31736
+ className: "h-2 w-10 rounded-sm opacity-30",
31737
+ style: {
31738
+ backgroundColor: secondary
31739
+ }
31740
+ }), /*#__PURE__*/jsx("div", {
31741
+ className: "h-2 w-14 rounded-sm opacity-30",
31742
+ style: {
31743
+ backgroundColor: secondary
31744
+ }
31745
+ })]
31746
+ }), /*#__PURE__*/jsxs("div", {
31747
+ className: "flex flex-col flex-1 min-w-0",
31748
+ children: [/*#__PURE__*/jsxs("div", {
31749
+ className: "flex items-center gap-2 px-3 py-2",
31750
+ style: {
31751
+ backgroundColor: header
31752
+ },
31753
+ children: [/*#__PURE__*/jsx("div", {
31754
+ className: "h-2 w-20 rounded-sm opacity-70",
31755
+ style: {
31756
+ backgroundColor: primary
31757
+ }
31758
+ }), /*#__PURE__*/jsx("div", {
31759
+ className: "flex-1"
31760
+ }), /*#__PURE__*/jsx("div", {
31761
+ className: "h-2 w-8 rounded-sm opacity-40",
31762
+ style: {
31763
+ backgroundColor: tertiary || secondary
31764
+ }
31765
+ })]
31766
+ }), /*#__PURE__*/jsxs("div", {
31767
+ className: "grid grid-cols-3 gap-2 p-3 flex-1",
31768
+ children: [/*#__PURE__*/jsxs("div", {
31769
+ className: "rounded p-2 flex flex-col gap-1.5",
31770
+ style: {
31771
+ backgroundColor: adjustColor(primary, -0.35)
31772
+ },
31773
+ children: [/*#__PURE__*/jsx("div", {
31774
+ className: "h-1.5 w-10 rounded-sm",
31775
+ style: {
31776
+ backgroundColor: primary,
31777
+ opacity: 0.7
31778
+ }
31779
+ }), /*#__PURE__*/jsx("div", {
31780
+ className: "h-8 w-full rounded-sm",
31781
+ style: {
31782
+ backgroundColor: secondary,
31783
+ opacity: 0.3
31784
+ }
31785
+ }), /*#__PURE__*/jsx("div", {
31786
+ className: "h-1.5 w-12 rounded-sm",
31787
+ style: {
31788
+ backgroundColor: tertiary || secondary,
31789
+ opacity: 0.4
31790
+ }
31791
+ })]
31792
+ }), /*#__PURE__*/jsxs("div", {
31793
+ className: "rounded p-2 flex flex-col gap-1.5",
31794
+ style: {
31795
+ backgroundColor: adjustColor(primary, -0.35)
31796
+ },
31797
+ children: [/*#__PURE__*/jsx("div", {
31798
+ className: "h-1.5 w-8 rounded-sm",
31799
+ style: {
31800
+ backgroundColor: secondary,
31801
+ opacity: 0.7
31802
+ }
31803
+ }), /*#__PURE__*/jsxs("div", {
31804
+ className: "flex flex-row gap-1 flex-1",
31805
+ children: [/*#__PURE__*/jsx("div", {
31806
+ className: "flex-1 rounded-sm",
31807
+ style: {
31808
+ backgroundColor: primary,
31809
+ opacity: 0.25
31810
+ }
31811
+ }), /*#__PURE__*/jsx("div", {
31812
+ className: "flex-1 rounded-sm",
31813
+ style: {
31814
+ backgroundColor: tertiary || secondary,
31815
+ opacity: 0.25
31816
+ }
31817
+ })]
31818
+ })]
31819
+ }), /*#__PURE__*/jsxs("div", {
31820
+ className: "rounded p-2 flex flex-col gap-1.5",
31821
+ style: {
31822
+ backgroundColor: adjustColor(primary, -0.35)
31823
+ },
31824
+ children: [/*#__PURE__*/jsx("div", {
31825
+ className: "h-1.5 w-12 rounded-sm",
31826
+ style: {
31827
+ backgroundColor: tertiary || primary,
31828
+ opacity: 0.7
31829
+ }
31830
+ }), /*#__PURE__*/jsx("div", {
31831
+ className: "h-4 w-full rounded-sm",
31832
+ style: {
31833
+ backgroundColor: primary,
31834
+ opacity: 0.2
31835
+ }
31836
+ }), /*#__PURE__*/jsx("div", {
31837
+ className: "h-4 w-full rounded-sm",
31838
+ style: {
31839
+ backgroundColor: secondary,
31840
+ opacity: 0.2
31841
+ }
31842
+ })]
31843
+ })]
31844
+ })]
31845
+ })]
31846
+ })
31847
+ })]
31848
+ });
31849
+ };
31850
+
31851
+ /**
31852
+ * RegistryThemeDetail — detail panel for a registry theme package.
31853
+ *
31854
+ * Shows package header, color preview swatches, description, tags, and install button.
31855
+ */
31856
+ var RegistryThemeDetail = function RegistryThemeDetail(_ref2) {
31857
+ var themePackage = _ref2.themePackage,
31858
+ appId = _ref2.appId,
31859
+ onInstallComplete = _ref2.onInstallComplete;
31594
31860
  var _useContext = useContext(ThemeContext),
31595
- changeThemesForApplication = _useContext.changeThemesForApplication,
31596
- rawThemes = _useContext.rawThemes,
31597
- themes = _useContext.themes,
31598
- changeCurrentTheme = _useContext.changeCurrentTheme,
31599
- changeThemeVariant = _useContext.changeThemeVariant,
31600
- currentTheme = _useContext.currentTheme;
31601
- var _useContext2 = useContext(AppContext),
31602
- dashApi = _useContext2.dashApi,
31603
- credentials = _useContext2.credentials,
31604
- settings = _useContext2.settings;
31605
- var _useState = useState(null),
31861
+ currentTheme = _useContext.currentTheme,
31862
+ changeThemesForApplication = _useContext.changeThemesForApplication;
31863
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
31864
+ grow: false
31865
+ });
31866
+ var _useState = useState(false),
31606
31867
  _useState2 = _slicedToArray(_useState, 2),
31607
- themeSelected = _useState2[0],
31608
- setThemeSelected = _useState2[1];
31868
+ isInstalling = _useState2[0],
31869
+ setIsInstalling = _useState2[1];
31609
31870
  var _useState3 = useState(null),
31610
31871
  _useState4 = _slicedToArray(_useState3, 2),
31611
- rawThemeSelected = _useState4[0],
31612
- setRawThemeSelected = _useState4[1];
31613
- var _useState5 = useState(null),
31614
- _useState6 = _slicedToArray(_useState5, 2),
31615
- themeKeySelected = _useState6[0],
31616
- setThemeKeySelected = _useState6[1];
31617
- var _useState7 = useState(false),
31618
- _useState8 = _slicedToArray(_useState7, 2),
31619
- isEditing = _useState8[0],
31620
- setIsEditing = _useState8[1];
31621
- var _useState9 = useState(false),
31622
- _useState0 = _slicedToArray(_useState9, 2),
31623
- isCreating = _useState0[0],
31624
- setIsCreating = _useState0[1];
31625
- var _useState1 = useState(""),
31626
- _useState10 = _slicedToArray(_useState1, 2),
31627
- wizardName = _useState10[0],
31628
- setWizardName = _useState10[1];
31629
- var _useState11 = useState(null),
31630
- _useState12 = _slicedToArray(_useState11, 2),
31631
- wizardMethod = _useState12[0],
31632
- setWizardMethod = _useState12[1];
31633
- var _useState13 = useState(null),
31634
- _useState14 = _slicedToArray(_useState13, 2),
31635
- wizardTheme = _useState14[0],
31636
- setWizardTheme = _useState14[1];
31637
- var _React$useState = React__default.useState(),
31638
- _React$useState2 = _slicedToArray(_React$useState, 2),
31639
- updateState = _React$useState2[1];
31640
- var forceUpdate = React__default.useCallback(function () {
31641
- return updateState({});
31642
- }, []);
31643
- var footerStyles = getStylesForItem(themeObjects.PANEL_FOOTER, currentTheme, {});
31644
- useEffect(function () {
31645
- if (open === false) {
31646
- setThemeSelected(null);
31647
- setRawThemeSelected(null);
31648
- setThemeKeySelected(null);
31649
- setIsCreating(false);
31650
- } else {
31651
- if (themeKeySelected === null && themes) {
31652
- var themeKeyTemp = settings && "theme" in settings ? settings["theme"] in themes ? settings["theme"] : Object.keys(themes)[0] : Object.keys(themes)[0];
31653
- var themeModel = ThemeModel(rawThemes[themeKeyTemp]);
31654
- setThemeKeySelected(function () {
31655
- return themeKeyTemp;
31656
- });
31657
- setThemeSelected(function () {
31658
- return themeModel;
31659
- });
31660
- setRawThemeSelected(function () {
31661
- return rawThemes[themeKeyTemp];
31662
- });
31663
- }
31664
- }
31665
- }, [open, themes, rawThemes, settings, themeKeySelected]);
31666
- function handleThemeSelected(themeUpdated, themeKey) {
31667
- var newRawThemeSelected = deepCopy(rawThemeSelected);
31668
- if (newRawThemeSelected !== null) {
31669
- Object.keys(themeUpdated).forEach(function (k) {
31670
- newRawThemeSelected[k] = themeUpdated[k];
31671
- });
31672
- } else {
31673
- newRawThemeSelected = deepCopy(themeUpdated);
31674
- }
31675
- setRawThemeSelected(function () {
31676
- return newRawThemeSelected;
31677
- });
31678
- var newTheme = ThemeModel(deepCopy(newRawThemeSelected));
31679
- setThemeKeySelected(function () {
31680
- return themeKey;
31681
- });
31682
- setThemeSelected(function () {
31683
- return newTheme;
31684
- });
31685
- forceUpdate();
31686
- }
31687
- function handleStartCreateTheme() {
31688
- setIsCreating(true);
31689
- setIsEditing(false);
31690
- setWizardName("");
31691
- setWizardMethod(null);
31692
- setWizardTheme(null);
31872
+ installResult = _useState4[0],
31873
+ setInstallResult = _useState4[1];
31874
+ var pkg = themePackage;
31875
+ if (!pkg) return null;
31876
+ var rawColors = pkg.colors || {};
31877
+ // Also check top-level fields for themes that store colors directly
31878
+ var colors = {
31879
+ primary: toDisplayColor(rawColors.primary || pkg.primary || ""),
31880
+ secondary: toDisplayColor(rawColors.secondary || pkg.secondary || ""),
31881
+ tertiary: toDisplayColor(rawColors.tertiary || pkg.tertiary || ""),
31882
+ neutral: toDisplayColor(rawColors.neutral || pkg.neutral || "")
31883
+ };
31884
+ function handleInstall() {
31885
+ return _handleInstall.apply(this, arguments);
31693
31886
  }
31694
- function handleWizardComplete() {
31695
- if (!wizardTheme || !wizardName.trim()) return;
31696
- var key = wizardTheme.id || "theme-".concat(Date.now());
31697
- var finalTheme = _objectSpread$b(_objectSpread$b({}, wizardTheme), {}, {
31698
- id: key,
31699
- name: wizardName.trim()
31700
- });
31701
- if (dashApi) {
31702
- dashApi.saveTheme(credentials.appId, key, finalTheme, function (e, message) {
31703
- changeThemesForApplication(message["themes"]);
31704
- setIsCreating(false);
31705
- setIsEditing(false);
31706
- var newThemes = message["themes"];
31707
- if (newThemes && newThemes[key]) {
31708
- setThemeKeySelected(key);
31887
+ function _handleInstall() {
31888
+ _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
31889
+ var result, _t;
31890
+ return _regeneratorRuntime.wrap(function (_context) {
31891
+ while (1) switch (_context.prev = _context.next) {
31892
+ case 0:
31893
+ if (!(!appId || !pkg.name)) {
31894
+ _context.next = 1;
31895
+ break;
31896
+ }
31897
+ return _context.abrupt("return");
31898
+ case 1:
31899
+ setIsInstalling(true);
31900
+ setInstallResult(null);
31901
+ _context.prev = 2;
31902
+ _context.next = 3;
31903
+ return window.mainApi.themes.installThemeFromRegistry(appId, pkg.name);
31904
+ case 3:
31905
+ result = _context.sent;
31906
+ setInstallResult({
31907
+ status: result !== null && result !== void 0 && result.success ? "success" : "error",
31908
+ message: result !== null && result !== void 0 && result.success ? "Theme \"".concat(result.themeKey || pkg.displayName || pkg.name, "\" installed successfully.") : (result === null || result === void 0 ? void 0 : result.error) || "Installation failed."
31909
+ });
31910
+ if (result !== null && result !== void 0 && result.success) {
31911
+ // Refresh ThemeContext with updated themes
31912
+ if (result.themes) {
31913
+ changeThemesForApplication(result.themes);
31914
+ }
31915
+ if (onInstallComplete) {
31916
+ onInstallComplete(result);
31917
+ }
31918
+ }
31919
+ _context.next = 5;
31920
+ break;
31921
+ case 4:
31922
+ _context.prev = 4;
31923
+ _t = _context["catch"](2);
31924
+ setInstallResult({
31925
+ status: "error",
31926
+ message: _t.message || "Failed to install theme."
31927
+ });
31928
+ case 5:
31929
+ _context.prev = 5;
31930
+ setIsInstalling(false);
31931
+ return _context.finish(5);
31932
+ case 6:
31933
+ case "end":
31934
+ return _context.stop();
31935
+ }
31936
+ }, _callee, null, [[2, 4, 5, 6]]);
31937
+ }));
31938
+ return _handleInstall.apply(this, arguments);
31939
+ }
31940
+ var colorEntries = [{
31941
+ label: "Primary",
31942
+ value: colors.primary
31943
+ }, {
31944
+ label: "Secondary",
31945
+ value: colors.secondary
31946
+ }, {
31947
+ label: "Tertiary",
31948
+ value: colors.tertiary
31949
+ }, {
31950
+ label: "Neutral",
31951
+ value: colors.neutral
31952
+ }].filter(function (c) {
31953
+ return c.value;
31954
+ });
31955
+ return /*#__PURE__*/jsxs("div", {
31956
+ className: "flex flex-col flex-1 min-h-0",
31957
+ children: [/*#__PURE__*/jsxs("div", {
31958
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
31959
+ children: [/*#__PURE__*/jsxs("div", {
31960
+ className: "flex flex-row items-center gap-3",
31961
+ children: [/*#__PURE__*/jsx("div", {
31962
+ className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
31963
+ children: /*#__PURE__*/jsx(FontAwesomeIcon, {
31964
+ icon: "palette",
31965
+ className: "h-5 w-5"
31966
+ })
31967
+ }), /*#__PURE__*/jsxs("div", {
31968
+ children: [/*#__PURE__*/jsx(SubHeading3, {
31969
+ title: pkg.displayName || pkg.name,
31970
+ padding: false
31971
+ }), /*#__PURE__*/jsxs("div", {
31972
+ className: "flex items-center gap-2 mt-0.5",
31973
+ children: [/*#__PURE__*/jsxs("span", {
31974
+ className: "text-sm opacity-60",
31975
+ children: ["by ", pkg.author || "Unknown"]
31976
+ }), pkg.version && /*#__PURE__*/jsxs("span", {
31977
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
31978
+ children: ["v", pkg.version]
31979
+ })]
31980
+ })]
31981
+ })]
31982
+ }), /*#__PURE__*/jsx("hr", {
31983
+ className: currentTheme["border-primary-medium"]
31984
+ }), colorEntries.length > 0 && /*#__PURE__*/jsx(ThemePreviewMockup, {
31985
+ colors: colors
31986
+ }), colorEntries.length > 0 && /*#__PURE__*/jsx("div", {
31987
+ className: "flex flex-row gap-3",
31988
+ children: colorEntries.map(function (_ref3) {
31989
+ var label = _ref3.label,
31990
+ value = _ref3.value;
31991
+ return /*#__PURE__*/jsxs("div", {
31992
+ className: "flex flex-col items-center gap-1 flex-1",
31993
+ children: [/*#__PURE__*/jsx("div", {
31994
+ className: "h-8 w-8 rounded border-2 border-white/20",
31995
+ style: {
31996
+ backgroundColor: value
31997
+ }
31998
+ }), /*#__PURE__*/jsx("span", {
31999
+ className: "text-[10px] opacity-50",
32000
+ children: label
32001
+ }), /*#__PURE__*/jsx("span", {
32002
+ className: "text-[10px] opacity-30 font-mono",
32003
+ children: value
32004
+ })]
32005
+ }, label);
32006
+ })
32007
+ }), pkg.description && /*#__PURE__*/jsx("p", {
32008
+ className: "text-sm",
32009
+ children: pkg.description
32010
+ }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsx("div", {
32011
+ className: "flex flex-wrap gap-1",
32012
+ children: pkg.tags.map(function (tag) {
32013
+ return /*#__PURE__*/jsx("span", {
32014
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
32015
+ children: tag
32016
+ }, tag);
32017
+ })
32018
+ }), installResult && /*#__PURE__*/jsx("div", {
32019
+ className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
32020
+ children: /*#__PURE__*/jsxs("div", {
32021
+ className: "flex items-center gap-2",
32022
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
32023
+ icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
32024
+ className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
32025
+ }), /*#__PURE__*/jsx("span", {
32026
+ className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
32027
+ children: installResult.message
32028
+ })]
32029
+ })
32030
+ })]
32031
+ }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsx("div", {
32032
+ className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
32033
+ children: /*#__PURE__*/jsx(Button, {
32034
+ title: isInstalling ? "Installing..." : "Install Theme",
32035
+ bgColor: "bg-blue-600",
32036
+ hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
32037
+ textSize: "text-sm",
32038
+ padding: "py-1.5 px-4",
32039
+ onClick: handleInstall,
32040
+ disabled: isInstalling
32041
+ })
32042
+ })]
32043
+ });
32044
+ };
32045
+
32046
+ var ThemeColorDots = function ThemeColorDots(_ref) {
32047
+ var theme = _ref.theme,
32048
+ colors = _ref.colors,
32049
+ _ref$size = _ref.size,
32050
+ size = _ref$size === void 0 ? "h-2.5 w-2.5" : _ref$size;
32051
+ var c = colors || {};
32052
+ var values = [toDisplayColor(c.primary || (theme === null || theme === void 0 ? void 0 : theme.primary) || ""), toDisplayColor(c.secondary || (theme === null || theme === void 0 ? void 0 : theme.secondary) || ""), toDisplayColor(c.tertiary || (theme === null || theme === void 0 ? void 0 : theme.tertiary) || "")].filter(Boolean);
32053
+ if (values.length === 0) return null;
32054
+ return /*#__PURE__*/jsx("span", {
32055
+ className: "flex items-center gap-0.5",
32056
+ children: values.map(function (color, i) {
32057
+ return /*#__PURE__*/jsx("span", {
32058
+ className: "".concat(size, " rounded-sm border border-white/20 flex-shrink-0"),
32059
+ style: {
32060
+ backgroundColor: color
32061
+ }
32062
+ }, i);
32063
+ })
32064
+ });
32065
+ };
32066
+
32067
+ var DiscoverThemesDetail = function DiscoverThemesDetail(_ref) {
32068
+ var onBack = _ref.onBack,
32069
+ appId = _ref.appId,
32070
+ onInstallComplete = _ref.onInstallComplete;
32071
+ var _useContext = useContext(ThemeContext),
32072
+ currentTheme = _useContext.currentTheme;
32073
+ var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
32074
+ grow: false
32075
+ });
32076
+ var _useState = useState([]),
32077
+ _useState2 = _slicedToArray(_useState, 2),
32078
+ packages = _useState2[0],
32079
+ setPackages = _useState2[1];
32080
+ var _useState3 = useState(false),
32081
+ _useState4 = _slicedToArray(_useState3, 2),
32082
+ isLoading = _useState4[0],
32083
+ setIsLoading = _useState4[1];
32084
+ var _useState5 = useState(null),
32085
+ _useState6 = _slicedToArray(_useState5, 2),
32086
+ error = _useState6[0],
32087
+ setError = _useState6[1];
32088
+ var _useState7 = useState(""),
32089
+ _useState8 = _slicedToArray(_useState7, 2),
32090
+ searchQuery = _useState8[0],
32091
+ setSearchQuery = _useState8[1];
32092
+ var _useState9 = useState(null),
32093
+ _useState0 = _slicedToArray(_useState9, 2),
32094
+ selectedPackageName = _useState0[0],
32095
+ setSelectedPackageName = _useState0[1];
32096
+ var search = useCallback(/*#__PURE__*/function () {
32097
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
32098
+ var _window$mainApi;
32099
+ var result, _t;
32100
+ return _regeneratorRuntime.wrap(function (_context) {
32101
+ while (1) switch (_context.prev = _context.next) {
32102
+ case 0:
32103
+ if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchThemes) {
32104
+ _context.next = 1;
32105
+ break;
32106
+ }
32107
+ setPackages([]);
32108
+ return _context.abrupt("return");
32109
+ case 1:
32110
+ setIsLoading(true);
32111
+ setError(null);
32112
+ _context.prev = 2;
32113
+ _context.next = 3;
32114
+ return window.mainApi.registry.searchThemes(query || "", {});
32115
+ case 3:
32116
+ result = _context.sent;
32117
+ setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
32118
+ _context.next = 5;
32119
+ break;
32120
+ case 4:
32121
+ _context.prev = 4;
32122
+ _t = _context["catch"](2);
32123
+ setError(_t.message || "Failed to search theme registry");
32124
+ setPackages([]);
32125
+ case 5:
32126
+ _context.prev = 5;
32127
+ setIsLoading(false);
32128
+ return _context.finish(5);
32129
+ case 6:
32130
+ case "end":
32131
+ return _context.stop();
32132
+ }
32133
+ }, _callee, null, [[2, 4, 5, 6]]);
32134
+ }));
32135
+ return function (_x) {
32136
+ return _ref2.apply(this, arguments);
32137
+ };
32138
+ }(), []);
32139
+
32140
+ // Debounce search on query changes
32141
+ useEffect(function () {
32142
+ var timer = setTimeout(function () {
32143
+ search(searchQuery);
32144
+ }, 300);
32145
+ return function () {
32146
+ return clearTimeout(timer);
32147
+ };
32148
+ // eslint-disable-next-line react-hooks/exhaustive-deps
32149
+ }, [searchQuery]);
32150
+ var retry = function retry() {
32151
+ return search(searchQuery);
32152
+ };
32153
+ var selectedPackage = selectedPackageName ? packages.find(function (p) {
32154
+ return p.name === selectedPackageName;
32155
+ }) : null;
32156
+
32157
+ // If a package is selected, show its detail inline
32158
+ if (selectedPackage) {
32159
+ return /*#__PURE__*/jsxs("div", {
32160
+ className: "flex flex-col flex-1 min-h-0",
32161
+ children: [/*#__PURE__*/jsx("div", {
32162
+ className: "flex-shrink-0 px-4 pt-4",
32163
+ children: /*#__PURE__*/jsxs("button", {
32164
+ type: "button",
32165
+ onClick: function onClick() {
32166
+ return setSelectedPackageName(null);
32167
+ },
32168
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
32169
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
32170
+ icon: "arrow-left",
32171
+ className: "h-3 w-3"
32172
+ }), /*#__PURE__*/jsx("span", {
32173
+ children: "Back"
32174
+ })]
32175
+ })
32176
+ }), /*#__PURE__*/jsx(RegistryThemeDetail, {
32177
+ themePackage: selectedPackage,
32178
+ appId: appId,
32179
+ onInstallComplete: onInstallComplete
32180
+ })]
32181
+ });
32182
+ }
32183
+
32184
+ // Package list view
32185
+ var listBody;
32186
+ if (isLoading) {
32187
+ listBody = /*#__PURE__*/jsx("div", {
32188
+ className: "flex items-center justify-center py-12",
32189
+ children: /*#__PURE__*/jsxs("div", {
32190
+ className: "text-center",
32191
+ children: [/*#__PURE__*/jsx("div", {
32192
+ className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
32193
+ }), /*#__PURE__*/jsx(Paragraph, {
32194
+ className: "text-sm opacity-50",
32195
+ children: "Loading themes..."
32196
+ })]
32197
+ })
32198
+ });
32199
+ } else if (error) {
32200
+ listBody = /*#__PURE__*/jsxs("div", {
32201
+ className: "px-4 py-8 text-center",
32202
+ children: [/*#__PURE__*/jsx(Paragraph, {
32203
+ className: "text-sm text-red-400 mb-3",
32204
+ children: error
32205
+ }), /*#__PURE__*/jsx(Button, {
32206
+ title: "Retry",
32207
+ bgColor: "bg-gray-700",
32208
+ hoverBackgroundColor: "hover:bg-gray-600",
32209
+ textSize: "text-sm",
32210
+ padding: "py-1 px-3",
32211
+ onClick: retry
32212
+ })]
32213
+ });
32214
+ } else if (packages.length === 0) {
32215
+ listBody = /*#__PURE__*/jsx("div", {
32216
+ className: "px-4 py-8 text-center",
32217
+ children: /*#__PURE__*/jsx(Paragraph, {
32218
+ className: "text-sm opacity-50",
32219
+ children: searchQuery ? "No themes match your search." : "No theme packages available."
32220
+ })
32221
+ });
32222
+ } else {
32223
+ listBody = /*#__PURE__*/jsx("div", {
32224
+ className: "space-y-1",
32225
+ children: packages.map(function (pkg) {
32226
+ return /*#__PURE__*/jsx(Sidebar.Item, {
32227
+ icon: /*#__PURE__*/jsx(FontAwesomeIcon, {
32228
+ icon: "palette",
32229
+ className: "h-3.5 w-3.5"
32230
+ }),
32231
+ badge: /*#__PURE__*/jsx(ThemeColorDots, {
32232
+ colors: pkg.colors,
32233
+ theme: pkg
32234
+ }),
32235
+ onClick: function onClick() {
32236
+ return setSelectedPackageName(pkg.name);
32237
+ },
32238
+ children: pkg.displayName || pkg.name
32239
+ }, pkg.name);
32240
+ })
32241
+ });
32242
+ }
32243
+ return /*#__PURE__*/jsxs("div", {
32244
+ className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
32245
+ children: [/*#__PURE__*/jsx("div", {
32246
+ className: "flex-shrink-0 px-4 pt-4",
32247
+ children: /*#__PURE__*/jsxs("button", {
32248
+ type: "button",
32249
+ onClick: onBack,
32250
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
32251
+ children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
32252
+ icon: "arrow-left",
32253
+ className: "h-3 w-3"
32254
+ }), /*#__PURE__*/jsx("span", {
32255
+ children: "Back"
32256
+ })]
32257
+ })
32258
+ }), /*#__PURE__*/jsx("div", {
32259
+ className: "flex-shrink-0 px-4 py-3",
32260
+ children: /*#__PURE__*/jsx(SearchInput, {
32261
+ value: searchQuery,
32262
+ onChange: setSearchQuery,
32263
+ placeholder: "Search themes...",
32264
+ inputClassName: "py-1.5 text-xs"
32265
+ })
32266
+ }), /*#__PURE__*/jsx("div", {
32267
+ className: "flex-1 min-h-0 overflow-y-auto px-2",
32268
+ children: listBody
32269
+ }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxs("div", {
32270
+ className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
32271
+ children: [packages.length, " theme", packages.length !== 1 ? "s" : ""]
32272
+ })]
32273
+ });
32274
+ };
32275
+
32276
+ function ownKeys$b(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
32277
+ function _objectSpread$b(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$b(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$b(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
32278
+ var ThemeManagerModal = function ThemeManagerModal(_ref) {
32279
+ var open = _ref.open,
32280
+ setIsOpen = _ref.setIsOpen;
32281
+ var _useContext = useContext(ThemeContext),
32282
+ changeThemesForApplication = _useContext.changeThemesForApplication,
32283
+ rawThemes = _useContext.rawThemes,
32284
+ themes = _useContext.themes,
32285
+ changeCurrentTheme = _useContext.changeCurrentTheme,
32286
+ changeThemeVariant = _useContext.changeThemeVariant,
32287
+ currentTheme = _useContext.currentTheme;
32288
+ var _useContext2 = useContext(AppContext),
32289
+ dashApi = _useContext2.dashApi,
32290
+ credentials = _useContext2.credentials,
32291
+ settings = _useContext2.settings;
32292
+ var _useState = useState(null),
32293
+ _useState2 = _slicedToArray(_useState, 2),
32294
+ themeSelected = _useState2[0],
32295
+ setThemeSelected = _useState2[1];
32296
+ var _useState3 = useState(null),
32297
+ _useState4 = _slicedToArray(_useState3, 2),
32298
+ rawThemeSelected = _useState4[0],
32299
+ setRawThemeSelected = _useState4[1];
32300
+ var _useState5 = useState(null),
32301
+ _useState6 = _slicedToArray(_useState5, 2),
32302
+ themeKeySelected = _useState6[0],
32303
+ setThemeKeySelected = _useState6[1];
32304
+ var _useState7 = useState(false),
32305
+ _useState8 = _slicedToArray(_useState7, 2),
32306
+ isEditing = _useState8[0],
32307
+ setIsEditing = _useState8[1];
32308
+ var _useState9 = useState(false),
32309
+ _useState0 = _slicedToArray(_useState9, 2),
32310
+ isCreating = _useState0[0],
32311
+ setIsCreating = _useState0[1];
32312
+ var _useState1 = useState(false),
32313
+ _useState10 = _slicedToArray(_useState1, 2),
32314
+ isChoosingMode = _useState10[0],
32315
+ setIsChoosingMode = _useState10[1];
32316
+ var _useState11 = useState(false),
32317
+ _useState12 = _slicedToArray(_useState11, 2),
32318
+ isSearching = _useState12[0],
32319
+ setIsSearching = _useState12[1];
32320
+ var _useState13 = useState(""),
32321
+ _useState14 = _slicedToArray(_useState13, 2),
32322
+ wizardName = _useState14[0],
32323
+ setWizardName = _useState14[1];
32324
+ var _useState15 = useState(null),
32325
+ _useState16 = _slicedToArray(_useState15, 2),
32326
+ wizardMethod = _useState16[0],
32327
+ setWizardMethod = _useState16[1];
32328
+ var _useState17 = useState(null),
32329
+ _useState18 = _slicedToArray(_useState17, 2),
32330
+ wizardTheme = _useState18[0],
32331
+ setWizardTheme = _useState18[1];
32332
+ var _React$useState = React__default.useState(),
32333
+ _React$useState2 = _slicedToArray(_React$useState, 2),
32334
+ updateState = _React$useState2[1];
32335
+ var forceUpdate = React__default.useCallback(function () {
32336
+ return updateState({});
32337
+ }, []);
32338
+ var footerStyles = getStylesForItem(themeObjects.PANEL_FOOTER, currentTheme, {});
32339
+ useEffect(function () {
32340
+ if (open === false) {
32341
+ setThemeSelected(null);
32342
+ setRawThemeSelected(null);
32343
+ setThemeKeySelected(null);
32344
+ setIsCreating(false);
32345
+ setIsChoosingMode(false);
32346
+ setIsSearching(false);
32347
+ } else {
32348
+ if (themeKeySelected === null && themes) {
32349
+ var themeKeyTemp = settings && "theme" in settings ? settings["theme"] in themes ? settings["theme"] : Object.keys(themes)[0] : Object.keys(themes)[0];
32350
+ var themeModel = ThemeModel(rawThemes[themeKeyTemp]);
32351
+ setThemeKeySelected(function () {
32352
+ return themeKeyTemp;
32353
+ });
32354
+ setThemeSelected(function () {
32355
+ return themeModel;
32356
+ });
32357
+ setRawThemeSelected(function () {
32358
+ return rawThemes[themeKeyTemp];
32359
+ });
32360
+ }
32361
+ }
32362
+ }, [open, themes, rawThemes, settings, themeKeySelected]);
32363
+ function handleThemeSelected(themeUpdated, themeKey) {
32364
+ var newRawThemeSelected = deepCopy(rawThemeSelected);
32365
+ if (newRawThemeSelected !== null) {
32366
+ Object.keys(themeUpdated).forEach(function (k) {
32367
+ newRawThemeSelected[k] = themeUpdated[k];
32368
+ });
32369
+ } else {
32370
+ newRawThemeSelected = deepCopy(themeUpdated);
32371
+ }
32372
+ setRawThemeSelected(function () {
32373
+ return newRawThemeSelected;
32374
+ });
32375
+ var newTheme = ThemeModel(deepCopy(newRawThemeSelected));
32376
+ setThemeKeySelected(function () {
32377
+ return themeKey;
32378
+ });
32379
+ setThemeSelected(function () {
32380
+ return newTheme;
32381
+ });
32382
+ forceUpdate();
32383
+ }
32384
+ function handleStartCreateTheme() {
32385
+ setIsChoosingMode(true);
32386
+ setIsCreating(false);
32387
+ setIsSearching(false);
32388
+ setIsEditing(false);
32389
+ }
32390
+ function handleChooseCreate() {
32391
+ setIsChoosingMode(false);
32392
+ setIsCreating(true);
32393
+ setWizardName("");
32394
+ setWizardMethod(null);
32395
+ setWizardTheme(null);
32396
+ }
32397
+ function handleChooseSearch() {
32398
+ setIsChoosingMode(false);
32399
+ setIsSearching(true);
32400
+ }
32401
+ function handleBackFromSearch() {
32402
+ setIsSearching(false);
32403
+ setIsChoosingMode(true);
32404
+ }
32405
+ function handleWizardComplete() {
32406
+ if (!wizardTheme || !wizardName.trim()) return;
32407
+ var key = wizardTheme.id || "theme-".concat(Date.now());
32408
+ var finalTheme = _objectSpread$b(_objectSpread$b({}, wizardTheme), {}, {
32409
+ id: key,
32410
+ name: wizardName.trim()
32411
+ });
32412
+ if (dashApi) {
32413
+ dashApi.saveTheme(credentials.appId, key, finalTheme, function (e, message) {
32414
+ changeThemesForApplication(message["themes"]);
32415
+ setIsCreating(false);
32416
+ setIsEditing(false);
32417
+ var newThemes = message["themes"];
32418
+ if (newThemes && newThemes[key]) {
32419
+ setThemeKeySelected(key);
31709
32420
  setThemeSelected(newThemes[key]);
31710
32421
  setRawThemeSelected(finalTheme);
31711
32422
  }
@@ -31714,6 +32425,8 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
31714
32425
  }
31715
32426
  function handleCancelCreate() {
31716
32427
  setIsCreating(false);
32428
+ setIsChoosingMode(false);
32429
+ setIsSearching(false);
31717
32430
  }
31718
32431
  function handleSaveTheme() {
31719
32432
  if (themeKeySelected !== null && rawThemeSelected !== null) {
@@ -31790,7 +32503,22 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
31790
32503
  onChooseTheme: handleChooseTheme,
31791
32504
  onChangeVariant: changeThemeVariant,
31792
32505
  rawTheme: rawThemeSelected,
31793
- wizardContent: isCreating ? /*#__PURE__*/jsx(ThemeQuickCreate, {
32506
+ wizardContent: isChoosingMode ? /*#__PURE__*/jsx(ThemeNewChooser, {
32507
+ onSearchThemes: handleChooseSearch,
32508
+ onCreateNew: handleChooseCreate
32509
+ }) : isSearching ? /*#__PURE__*/jsx(DiscoverThemesDetail, {
32510
+ onBack: handleBackFromSearch,
32511
+ appId: credentials === null || credentials === void 0 ? void 0 : credentials.appId,
32512
+ onInstallComplete: function onInstallComplete() {
32513
+ if (dashApi && credentials !== null && credentials !== void 0 && credentials.appId) {
32514
+ dashApi.listThemes(credentials.appId, function (e, message) {
32515
+ if (message && message.themes) {
32516
+ changeThemesForApplication(message.themes);
32517
+ }
32518
+ });
32519
+ }
32520
+ }
32521
+ }) : isCreating ? /*#__PURE__*/jsx(ThemeQuickCreate, {
31794
32522
  wizardName: wizardName,
31795
32523
  setWizardName: setWizardName,
31796
32524
  wizardMethod: wizardMethod,
@@ -31818,13 +32546,13 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
31818
32546
  children: themeKeySelected
31819
32547
  })]
31820
32548
  })
31821
- }), isCreating && /*#__PURE__*/jsx("div", {
32549
+ }), (isCreating || isChoosingMode || isSearching) && /*#__PURE__*/jsx("div", {
31822
32550
  className: "flex flex-row space-x-2",
31823
32551
  children: /*#__PURE__*/jsx(Button, {
31824
32552
  onClick: handleCancelCreate,
31825
32553
  title: "Cancel"
31826
32554
  })
31827
- }), !isCreating && isEditing === false && /*#__PURE__*/jsxs("div", {
32555
+ }), !isCreating && !isChoosingMode && !isSearching && isEditing === false && /*#__PURE__*/jsxs("div", {
31828
32556
  className: "flex flex-row space-x-2",
31829
32557
  children: [/*#__PURE__*/jsx(Button, {
31830
32558
  onClick: function onClick() {
@@ -31843,7 +32571,7 @@ var ThemeManagerModal = function ThemeManagerModal(_ref) {
31843
32571
  onClick: handleActivateTheme,
31844
32572
  title: "Activate"
31845
32573
  })]
31846
- }), !isCreating && isEditing === true && /*#__PURE__*/jsxs("div", {
32574
+ }), !isCreating && !isChoosingMode && !isSearching && isEditing === true && /*#__PURE__*/jsxs("div", {
31847
32575
  className: "flex flex-row space-x-2",
31848
32576
  children: [/*#__PURE__*/jsx(Button, {
31849
32577
  onClick: function onClick() {
@@ -32790,7 +33518,11 @@ var DashboardDetail = function DashboardDetail(_ref2) {
32790
33518
  t = _ref8[1];
32791
33519
  return {
32792
33520
  label: t.name || key,
32793
- value: key
33521
+ value: key,
33522
+ icon: "palette",
33523
+ badge: /*#__PURE__*/jsx(ThemeColorDots, {
33524
+ theme: t
33525
+ })
32794
33526
  };
32795
33527
  }));
32796
33528
  function handleChangeFolder(val) {
@@ -37037,545 +37769,146 @@ var ComponentStyleRow = function ComponentStyleRow(_ref3) {
37037
37769
  title: "".concat(key, ": ").concat(value)
37038
37770
  }, key);
37039
37771
  }
37040
- return /*#__PURE__*/jsx("div", {
37041
- className: "h-5 w-5 rounded-sm ".concat(value),
37042
- title: "".concat(key, ": ").concat(value)
37043
- }, key);
37044
- })
37045
- }), /*#__PURE__*/jsx("div", {
37046
- className: "flex flex-row items-center gap-2 flex-1 overflow-hidden",
37047
- children: nonColorEntries.map(function (_ref5) {
37048
- var key = _ref5.key,
37049
- value = _ref5.value;
37050
- return /*#__PURE__*/jsx("span", {
37051
- className: "text-[10px] opacity-40 whitespace-nowrap",
37052
- title: key,
37053
- children: value
37054
- }, key);
37055
- })
37056
- })]
37057
- });
37058
- };
37059
-
37060
- // --- Main Component ---
37061
-
37062
- var ThemeDetail = function ThemeDetail(_ref6) {
37063
- var themeKey = _ref6.themeKey,
37064
- themes = _ref6.themes,
37065
- currentThemeKey = _ref6.currentThemeKey,
37066
- themeVariant = _ref6.themeVariant,
37067
- onActivate = _ref6.onActivate,
37068
- onOpenThemeEditor = _ref6.onOpenThemeEditor,
37069
- _ref6$onDelete = _ref6.onDelete,
37070
- onDelete = _ref6$onDelete === void 0 ? null : _ref6$onDelete,
37071
- _ref6$appId = _ref6.appId,
37072
- appId = _ref6$appId === void 0 ? null : _ref6$appId;
37073
- var theme = themeKey && themes ? themes[themeKey] : null;
37074
- var _useState = useState(false),
37075
- _useState2 = _slicedToArray(_useState, 2),
37076
- publishOpen = _useState2[0],
37077
- setPublishOpen = _useState2[1];
37078
- var canPublish = theme && !theme._registryMeta;
37079
- var displayTheme = useMemo(function () {
37080
- return theme ? theme[themeVariant] || {} : {};
37081
- }, [theme, themeVariant]);
37082
- var isActive = themeKey === currentThemeKey;
37083
-
37084
- // Memoize all component styles
37085
- var allStyles = useMemo(function () {
37086
- var result = {};
37087
- Object.values(themeObjects).forEach(function (key) {
37088
- result[key] = getStylesForItem(key, displayTheme, {});
37089
- });
37090
- return result;
37091
- }, [displayTheme]);
37092
- if (!theme) return null;
37093
- return /*#__PURE__*/jsxs("div", {
37094
- className: "flex flex-col flex-1 min-h-0",
37095
- children: [/*#__PURE__*/jsxs("div", {
37096
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6",
37097
- children: [/*#__PURE__*/jsxs("div", {
37098
- className: "flex flex-row items-center gap-3",
37099
- children: [/*#__PURE__*/jsx(SubHeading, {
37100
- title: theme.name || themeKey,
37101
- padding: false
37102
- }), isActive && /*#__PURE__*/jsx("span", {
37103
- className: "text-xs opacity-40",
37104
- children: "active"
37105
- })]
37106
- }), /*#__PURE__*/jsx(ColorSwatchGrid, {
37107
- displayTheme: displayTheme
37108
- }), /*#__PURE__*/jsxs("div", {
37109
- className: "flex flex-col space-y-2",
37110
- children: [/*#__PURE__*/jsx("span", {
37111
- className: "text-xs font-semibold opacity-50",
37112
- children: "Component Styles"
37113
- }), /*#__PURE__*/jsx(Accordion2, {
37114
- type: "multiple",
37115
- children: COMPONENT_GROUPS.map(function (group) {
37116
- // Only show groups that have valid theme objects
37117
- var validKeys = group.keys.filter(function (k) {
37118
- return themeObjects[k];
37119
- });
37120
- if (validKeys.length === 0) return null;
37121
- return /*#__PURE__*/jsxs(Accordion2.Item, {
37122
- value: group.label,
37123
- children: [/*#__PURE__*/jsxs(Accordion2.Trigger, {
37124
- value: group.label,
37125
- children: [group.label, " (", validKeys.length, ")"]
37126
- }), /*#__PURE__*/jsx(Accordion2.Content, {
37127
- value: group.label,
37128
- children: /*#__PURE__*/jsx("div", {
37129
- className: "flex flex-col",
37130
- children: validKeys.map(function (k) {
37131
- var objectValue = themeObjects[k];
37132
- return /*#__PURE__*/jsx(ComponentStyleRow, {
37133
- objectKey: objectValue,
37134
- styles: allStyles[objectValue]
37135
- }, k);
37136
- })
37137
- })
37138
- })]
37139
- }, group.label);
37140
- })
37141
- })]
37142
- })]
37143
- }), /*#__PURE__*/jsxs("div", {
37144
- className: "flex-shrink-0 flex flex-row justify-between px-6 py-4 border-t border-white/10",
37145
- children: [/*#__PURE__*/jsxs("div", {
37146
- className: "flex flex-row gap-2",
37147
- children: [!isActive && onDelete && /*#__PURE__*/jsx(Button, {
37148
- title: "Delete",
37149
- onClick: function onClick() {
37150
- return onDelete(themeKey);
37151
- },
37152
- size: "sm"
37153
- }), canPublish && /*#__PURE__*/jsx(Button, {
37154
- title: "Publish",
37155
- onClick: function onClick() {
37156
- return setPublishOpen(true);
37157
- },
37158
- size: "sm"
37159
- })]
37160
- }), /*#__PURE__*/jsxs("div", {
37161
- className: "flex flex-row gap-2",
37162
- children: [!isActive && /*#__PURE__*/jsx(Button, {
37163
- title: "Activate",
37164
- onClick: function onClick() {
37165
- return onActivate(themeKey);
37166
- },
37167
- size: "sm"
37168
- }), /*#__PURE__*/jsx(Button, {
37169
- title: "Edit",
37170
- onClick: onOpenThemeEditor,
37171
- size: "sm"
37172
- })]
37173
- })]
37174
- }), canPublish && /*#__PURE__*/jsx(PublishThemeModal, {
37175
- isOpen: publishOpen,
37176
- setIsOpen: setPublishOpen,
37177
- appId: appId,
37178
- themeKey: themeKey,
37179
- themeName: theme.name || themeKey
37180
- })]
37181
- });
37182
- };
37183
-
37184
- var RegistryThemeDetail = function RegistryThemeDetail(_ref) {
37185
- var themePackage = _ref.themePackage,
37186
- appId = _ref.appId,
37187
- onInstallComplete = _ref.onInstallComplete;
37188
- var _useContext = useContext(ThemeContext),
37189
- currentTheme = _useContext.currentTheme,
37190
- changeThemesForApplication = _useContext.changeThemesForApplication;
37191
- var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
37192
- grow: false
37193
- });
37194
- var _useState = useState(false),
37195
- _useState2 = _slicedToArray(_useState, 2),
37196
- isInstalling = _useState2[0],
37197
- setIsInstalling = _useState2[1];
37198
- var _useState3 = useState(null),
37199
- _useState4 = _slicedToArray(_useState3, 2),
37200
- installResult = _useState4[0],
37201
- setInstallResult = _useState4[1];
37202
- var pkg = themePackage;
37203
- if (!pkg) return null;
37204
- var colors = pkg.colors || {};
37205
- function handleInstall() {
37206
- return _handleInstall.apply(this, arguments);
37207
- }
37208
- function _handleInstall() {
37209
- _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
37210
- var result, _t;
37211
- return _regeneratorRuntime.wrap(function (_context) {
37212
- while (1) switch (_context.prev = _context.next) {
37213
- case 0:
37214
- if (!(!appId || !pkg.name)) {
37215
- _context.next = 1;
37216
- break;
37217
- }
37218
- return _context.abrupt("return");
37219
- case 1:
37220
- setIsInstalling(true);
37221
- setInstallResult(null);
37222
- _context.prev = 2;
37223
- _context.next = 3;
37224
- return window.mainApi.themes.installThemeFromRegistry(appId, pkg.name);
37225
- case 3:
37226
- result = _context.sent;
37227
- setInstallResult({
37228
- status: result !== null && result !== void 0 && result.success ? "success" : "error",
37229
- message: result !== null && result !== void 0 && result.success ? "Theme \"".concat(result.themeKey || pkg.displayName || pkg.name, "\" installed successfully.") : (result === null || result === void 0 ? void 0 : result.error) || "Installation failed."
37230
- });
37231
- if (result !== null && result !== void 0 && result.success) {
37232
- // Refresh ThemeContext with updated themes
37233
- if (result.themes) {
37234
- changeThemesForApplication(result.themes);
37235
- }
37236
- if (onInstallComplete) {
37237
- onInstallComplete(result);
37238
- }
37239
- }
37240
- _context.next = 5;
37241
- break;
37242
- case 4:
37243
- _context.prev = 4;
37244
- _t = _context["catch"](2);
37245
- setInstallResult({
37246
- status: "error",
37247
- message: _t.message || "Failed to install theme."
37248
- });
37249
- case 5:
37250
- _context.prev = 5;
37251
- setIsInstalling(false);
37252
- return _context.finish(5);
37253
- case 6:
37254
- case "end":
37255
- return _context.stop();
37256
- }
37257
- }, _callee, null, [[2, 4, 5, 6]]);
37258
- }));
37259
- return _handleInstall.apply(this, arguments);
37260
- }
37261
- var colorEntries = [{
37262
- label: "Primary",
37263
- value: colors.primary
37264
- }, {
37265
- label: "Secondary",
37266
- value: colors.secondary
37267
- }, {
37268
- label: "Tertiary",
37269
- value: colors.tertiary
37270
- }, {
37271
- label: "Neutral",
37272
- value: colors.neutral
37273
- }].filter(function (c) {
37274
- return c.value;
37772
+ return /*#__PURE__*/jsx("div", {
37773
+ className: "h-5 w-5 rounded-sm ".concat(value),
37774
+ title: "".concat(key, ": ").concat(value)
37775
+ }, key);
37776
+ })
37777
+ }), /*#__PURE__*/jsx("div", {
37778
+ className: "flex flex-row items-center gap-2 flex-1 overflow-hidden",
37779
+ children: nonColorEntries.map(function (_ref5) {
37780
+ var key = _ref5.key,
37781
+ value = _ref5.value;
37782
+ return /*#__PURE__*/jsx("span", {
37783
+ className: "text-[10px] opacity-40 whitespace-nowrap",
37784
+ title: key,
37785
+ children: value
37786
+ }, key);
37787
+ })
37788
+ })]
37275
37789
  });
37790
+ };
37791
+
37792
+ // --- Main Component ---
37793
+
37794
+ var ThemeDetail = function ThemeDetail(_ref6) {
37795
+ var themeKey = _ref6.themeKey,
37796
+ themes = _ref6.themes,
37797
+ currentThemeKey = _ref6.currentThemeKey,
37798
+ themeVariant = _ref6.themeVariant,
37799
+ onActivate = _ref6.onActivate,
37800
+ onOpenThemeEditor = _ref6.onOpenThemeEditor,
37801
+ _ref6$onDelete = _ref6.onDelete,
37802
+ onDelete = _ref6$onDelete === void 0 ? null : _ref6$onDelete,
37803
+ _ref6$appId = _ref6.appId,
37804
+ appId = _ref6$appId === void 0 ? null : _ref6$appId;
37805
+ var theme = themeKey && themes ? themes[themeKey] : null;
37806
+ var _useState = useState(false),
37807
+ _useState2 = _slicedToArray(_useState, 2),
37808
+ publishOpen = _useState2[0],
37809
+ setPublishOpen = _useState2[1];
37810
+ var canPublish = theme && !theme._registryMeta;
37811
+ var displayTheme = useMemo(function () {
37812
+ return theme ? theme[themeVariant] || {} : {};
37813
+ }, [theme, themeVariant]);
37814
+ var isActive = themeKey === currentThemeKey;
37815
+
37816
+ // Memoize all component styles
37817
+ var allStyles = useMemo(function () {
37818
+ var result = {};
37819
+ Object.values(themeObjects).forEach(function (key) {
37820
+ result[key] = getStylesForItem(key, displayTheme, {});
37821
+ });
37822
+ return result;
37823
+ }, [displayTheme]);
37824
+ if (!theme) return null;
37276
37825
  return /*#__PURE__*/jsxs("div", {
37277
37826
  className: "flex flex-col flex-1 min-h-0",
37278
37827
  children: [/*#__PURE__*/jsxs("div", {
37279
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
37828
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6",
37280
37829
  children: [/*#__PURE__*/jsxs("div", {
37281
37830
  className: "flex flex-row items-center gap-3",
37282
- children: [/*#__PURE__*/jsx("div", {
37283
- className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
37284
- children: /*#__PURE__*/jsx(FontAwesomeIcon, {
37285
- icon: "palette",
37286
- className: "h-5 w-5"
37287
- })
37288
- }), /*#__PURE__*/jsxs("div", {
37289
- children: [/*#__PURE__*/jsx(SubHeading3, {
37290
- title: pkg.displayName || pkg.name,
37291
- padding: false
37292
- }), /*#__PURE__*/jsxs("div", {
37293
- className: "flex items-center gap-2 mt-0.5",
37294
- children: [/*#__PURE__*/jsxs("span", {
37295
- className: "text-sm opacity-60",
37296
- children: ["by ", pkg.author || "Unknown"]
37297
- }), pkg.version && /*#__PURE__*/jsxs("span", {
37298
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
37299
- children: ["v", pkg.version]
37300
- })]
37301
- })]
37831
+ children: [/*#__PURE__*/jsx(SubHeading, {
37832
+ title: theme.name || themeKey,
37833
+ padding: false
37834
+ }), isActive && /*#__PURE__*/jsx("span", {
37835
+ className: "text-xs opacity-40",
37836
+ children: "active"
37302
37837
  })]
37303
- }), /*#__PURE__*/jsx("hr", {
37304
- className: currentTheme["border-primary-medium"]
37305
- }), colorEntries.length > 0 && /*#__PURE__*/jsxs("div", {
37838
+ }), /*#__PURE__*/jsx(ColorSwatchGrid, {
37839
+ displayTheme: displayTheme
37840
+ }), /*#__PURE__*/jsxs("div", {
37841
+ className: "flex flex-col space-y-2",
37306
37842
  children: [/*#__PURE__*/jsx("span", {
37307
- className: "text-xs font-semibold opacity-50 mb-2 block",
37308
- children: "COLORS"
37309
- }), /*#__PURE__*/jsx("div", {
37310
- className: "flex flex-row gap-3",
37311
- children: colorEntries.map(function (_ref2) {
37312
- var label = _ref2.label,
37313
- value = _ref2.value;
37314
- return /*#__PURE__*/jsxs("div", {
37315
- className: "flex flex-col items-center gap-1",
37316
- children: [/*#__PURE__*/jsx("div", {
37317
- className: "h-10 w-10 rounded-full border-2 border-white/20",
37318
- style: {
37319
- backgroundColor: value
37320
- }
37321
- }), /*#__PURE__*/jsx("span", {
37322
- className: "text-[10px] opacity-50",
37323
- children: label
37324
- }), /*#__PURE__*/jsx("span", {
37325
- className: "text-[10px] opacity-30 font-mono",
37326
- children: value
37327
- })]
37328
- }, label);
37329
- })
37330
- })]
37331
- }), pkg.description && /*#__PURE__*/jsx("p", {
37332
- className: "text-sm",
37333
- children: pkg.description
37334
- }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsx("div", {
37335
- className: "flex flex-wrap gap-1",
37336
- children: pkg.tags.map(function (tag) {
37337
- return /*#__PURE__*/jsx("span", {
37338
- className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
37339
- children: tag
37340
- }, tag);
37341
- })
37342
- }), installResult && /*#__PURE__*/jsx("div", {
37343
- className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
37344
- children: /*#__PURE__*/jsxs("div", {
37345
- className: "flex items-center gap-2",
37346
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
37347
- icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
37348
- className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
37349
- }), /*#__PURE__*/jsx("span", {
37350
- className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
37351
- children: installResult.message
37352
- })]
37353
- })
37354
- })]
37355
- }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsx("div", {
37356
- className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
37357
- children: /*#__PURE__*/jsx(Button, {
37358
- title: isInstalling ? "Installing..." : "Install Theme",
37359
- bgColor: "bg-blue-600",
37360
- hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
37361
- textSize: "text-sm",
37362
- padding: "py-1.5 px-4",
37363
- onClick: handleInstall,
37364
- disabled: isInstalling
37365
- })
37366
- })]
37367
- });
37368
- };
37369
-
37370
- var DiscoverThemesDetail = function DiscoverThemesDetail(_ref) {
37371
- var onBack = _ref.onBack,
37372
- appId = _ref.appId,
37373
- onInstallComplete = _ref.onInstallComplete;
37374
- var _useContext = useContext(ThemeContext),
37375
- currentTheme = _useContext.currentTheme;
37376
- var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
37377
- grow: false
37378
- });
37379
- var _useState = useState([]),
37380
- _useState2 = _slicedToArray(_useState, 2),
37381
- packages = _useState2[0],
37382
- setPackages = _useState2[1];
37383
- var _useState3 = useState(false),
37384
- _useState4 = _slicedToArray(_useState3, 2),
37385
- isLoading = _useState4[0],
37386
- setIsLoading = _useState4[1];
37387
- var _useState5 = useState(null),
37388
- _useState6 = _slicedToArray(_useState5, 2),
37389
- error = _useState6[0],
37390
- setError = _useState6[1];
37391
- var _useState7 = useState(""),
37392
- _useState8 = _slicedToArray(_useState7, 2),
37393
- searchQuery = _useState8[0],
37394
- setSearchQuery = _useState8[1];
37395
- var _useState9 = useState(null),
37396
- _useState0 = _slicedToArray(_useState9, 2),
37397
- selectedPackageName = _useState0[0],
37398
- setSelectedPackageName = _useState0[1];
37399
- var search = useCallback(/*#__PURE__*/function () {
37400
- var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
37401
- var _window$mainApi;
37402
- var result, _t;
37403
- return _regeneratorRuntime.wrap(function (_context) {
37404
- while (1) switch (_context.prev = _context.next) {
37405
- case 0:
37406
- if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchThemes) {
37407
- _context.next = 1;
37408
- break;
37409
- }
37410
- setPackages([]);
37411
- return _context.abrupt("return");
37412
- case 1:
37413
- setIsLoading(true);
37414
- setError(null);
37415
- _context.prev = 2;
37416
- _context.next = 3;
37417
- return window.mainApi.registry.searchThemes(query || "", {});
37418
- case 3:
37419
- result = _context.sent;
37420
- setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
37421
- _context.next = 5;
37422
- break;
37423
- case 4:
37424
- _context.prev = 4;
37425
- _t = _context["catch"](2);
37426
- setError(_t.message || "Failed to search theme registry");
37427
- setPackages([]);
37428
- case 5:
37429
- _context.prev = 5;
37430
- setIsLoading(false);
37431
- return _context.finish(5);
37432
- case 6:
37433
- case "end":
37434
- return _context.stop();
37435
- }
37436
- }, _callee, null, [[2, 4, 5, 6]]);
37437
- }));
37438
- return function (_x) {
37439
- return _ref2.apply(this, arguments);
37440
- };
37441
- }(), []);
37442
-
37443
- // Debounce search on query changes
37444
- useEffect(function () {
37445
- var timer = setTimeout(function () {
37446
- search(searchQuery);
37447
- }, 300);
37448
- return function () {
37449
- return clearTimeout(timer);
37450
- };
37451
- // eslint-disable-next-line react-hooks/exhaustive-deps
37452
- }, [searchQuery]);
37453
- var retry = function retry() {
37454
- return search(searchQuery);
37455
- };
37456
- var selectedPackage = selectedPackageName ? packages.find(function (p) {
37457
- return p.name === selectedPackageName;
37458
- }) : null;
37459
-
37460
- // If a package is selected, show its detail inline
37461
- if (selectedPackage) {
37462
- return /*#__PURE__*/jsxs("div", {
37463
- className: "flex flex-col flex-1 min-h-0",
37464
- children: [/*#__PURE__*/jsx("div", {
37465
- className: "flex-shrink-0 px-4 pt-4",
37466
- children: /*#__PURE__*/jsxs("button", {
37467
- type: "button",
37843
+ className: "text-xs font-semibold opacity-50",
37844
+ children: "Component Styles"
37845
+ }), /*#__PURE__*/jsx(Accordion2, {
37846
+ type: "multiple",
37847
+ children: COMPONENT_GROUPS.map(function (group) {
37848
+ // Only show groups that have valid theme objects
37849
+ var validKeys = group.keys.filter(function (k) {
37850
+ return themeObjects[k];
37851
+ });
37852
+ if (validKeys.length === 0) return null;
37853
+ return /*#__PURE__*/jsxs(Accordion2.Item, {
37854
+ value: group.label,
37855
+ children: [/*#__PURE__*/jsxs(Accordion2.Trigger, {
37856
+ value: group.label,
37857
+ children: [group.label, " (", validKeys.length, ")"]
37858
+ }), /*#__PURE__*/jsx(Accordion2.Content, {
37859
+ value: group.label,
37860
+ children: /*#__PURE__*/jsx("div", {
37861
+ className: "flex flex-col",
37862
+ children: validKeys.map(function (k) {
37863
+ var objectValue = themeObjects[k];
37864
+ return /*#__PURE__*/jsx(ComponentStyleRow, {
37865
+ objectKey: objectValue,
37866
+ styles: allStyles[objectValue]
37867
+ }, k);
37868
+ })
37869
+ })
37870
+ })]
37871
+ }, group.label);
37872
+ })
37873
+ })]
37874
+ })]
37875
+ }), /*#__PURE__*/jsxs("div", {
37876
+ className: "flex-shrink-0 flex flex-row justify-between px-6 py-4 border-t border-white/10",
37877
+ children: [/*#__PURE__*/jsxs("div", {
37878
+ className: "flex flex-row gap-2",
37879
+ children: [!isActive && onDelete && /*#__PURE__*/jsx(Button, {
37880
+ title: "Delete",
37468
37881
  onClick: function onClick() {
37469
- return setSelectedPackageName(null);
37882
+ return onDelete(themeKey);
37470
37883
  },
37471
- className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
37472
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
37473
- icon: "arrow-left",
37474
- className: "h-3 w-3"
37475
- }), /*#__PURE__*/jsx("span", {
37476
- children: "Back"
37477
- })]
37478
- })
37479
- }), /*#__PURE__*/jsx(RegistryThemeDetail, {
37480
- themePackage: selectedPackage,
37481
- appId: appId,
37482
- onInstallComplete: onInstallComplete
37483
- })]
37484
- });
37485
- }
37486
-
37487
- // Package list view
37488
- var listBody;
37489
- if (isLoading) {
37490
- listBody = /*#__PURE__*/jsx("div", {
37491
- className: "flex items-center justify-center py-12",
37492
- children: /*#__PURE__*/jsxs("div", {
37493
- className: "text-center",
37494
- children: [/*#__PURE__*/jsx("div", {
37495
- className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
37496
- }), /*#__PURE__*/jsx(Paragraph, {
37497
- className: "text-sm opacity-50",
37498
- children: "Loading themes..."
37884
+ size: "sm"
37885
+ }), canPublish && /*#__PURE__*/jsx(Button, {
37886
+ title: "Publish",
37887
+ onClick: function onClick() {
37888
+ return setPublishOpen(true);
37889
+ },
37890
+ size: "sm"
37499
37891
  })]
37500
- })
37501
- });
37502
- } else if (error) {
37503
- listBody = /*#__PURE__*/jsxs("div", {
37504
- className: "px-4 py-8 text-center",
37505
- children: [/*#__PURE__*/jsx(Paragraph, {
37506
- className: "text-sm text-red-400 mb-3",
37507
- children: error
37508
- }), /*#__PURE__*/jsx(Button, {
37509
- title: "Retry",
37510
- bgColor: "bg-gray-700",
37511
- hoverBackgroundColor: "hover:bg-gray-600",
37512
- textSize: "text-sm",
37513
- padding: "py-1 px-3",
37514
- onClick: retry
37515
- })]
37516
- });
37517
- } else if (packages.length === 0) {
37518
- listBody = /*#__PURE__*/jsx("div", {
37519
- className: "px-4 py-8 text-center",
37520
- children: /*#__PURE__*/jsx(Paragraph, {
37521
- className: "text-sm opacity-50",
37522
- children: searchQuery ? "No themes match your search." : "No theme packages available."
37523
- })
37524
- });
37525
- } else {
37526
- listBody = /*#__PURE__*/jsx("div", {
37527
- className: "space-y-1",
37528
- children: packages.map(function (pkg) {
37529
- var colors = pkg.colors || {};
37530
- return /*#__PURE__*/jsx(Sidebar.Item, {
37531
- icon: /*#__PURE__*/jsx("div", {
37532
- className: "flex items-center gap-0.5",
37533
- children: [colors.primary, colors.secondary, colors.tertiary].filter(Boolean).map(function (color, i) {
37534
- return /*#__PURE__*/jsx("div", {
37535
- className: "h-3 w-3 rounded-full border border-white/20",
37536
- style: {
37537
- backgroundColor: color
37538
- }
37539
- }, i);
37540
- })
37541
- }),
37892
+ }), /*#__PURE__*/jsxs("div", {
37893
+ className: "flex flex-row gap-2",
37894
+ children: [!isActive && /*#__PURE__*/jsx(Button, {
37895
+ title: "Activate",
37542
37896
  onClick: function onClick() {
37543
- return setSelectedPackageName(pkg.name);
37897
+ return onActivate(themeKey);
37544
37898
  },
37545
- children: pkg.displayName || pkg.name
37546
- }, pkg.name);
37547
- })
37548
- });
37549
- }
37550
- return /*#__PURE__*/jsxs("div", {
37551
- className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
37552
- children: [/*#__PURE__*/jsx("div", {
37553
- className: "flex-shrink-0 px-4 pt-4",
37554
- children: /*#__PURE__*/jsxs("button", {
37555
- type: "button",
37556
- onClick: onBack,
37557
- className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
37558
- children: [/*#__PURE__*/jsx(FontAwesomeIcon, {
37559
- icon: "arrow-left",
37560
- className: "h-3 w-3"
37561
- }), /*#__PURE__*/jsx("span", {
37562
- children: "Back"
37899
+ size: "sm"
37900
+ }), /*#__PURE__*/jsx(Button, {
37901
+ title: "Edit",
37902
+ onClick: onOpenThemeEditor,
37903
+ size: "sm"
37563
37904
  })]
37564
- })
37565
- }), /*#__PURE__*/jsx("div", {
37566
- className: "flex-shrink-0 px-4 py-3",
37567
- children: /*#__PURE__*/jsx(SearchInput, {
37568
- value: searchQuery,
37569
- onChange: setSearchQuery,
37570
- placeholder: "Search themes...",
37571
- inputClassName: "py-1.5 text-xs"
37572
- })
37573
- }), /*#__PURE__*/jsx("div", {
37574
- className: "flex-1 min-h-0 overflow-y-auto px-2",
37575
- children: listBody
37576
- }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxs("div", {
37577
- className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
37578
- children: [packages.length, " theme", packages.length !== 1 ? "s" : ""]
37905
+ })]
37906
+ }), canPublish && /*#__PURE__*/jsx(PublishThemeModal, {
37907
+ isOpen: publishOpen,
37908
+ setIsOpen: setPublishOpen,
37909
+ appId: appId,
37910
+ themeKey: themeKey,
37911
+ themeName: theme.name || themeKey
37579
37912
  })]
37580
37913
  });
37581
37914
  };
@@ -37626,6 +37959,10 @@ var ThemesSection = function ThemesSection(_ref) {
37626
37959
  _useState10 = _slicedToArray(_useState1, 2),
37627
37960
  installMode = _useState10[0],
37628
37961
  setInstallMode = _useState10[1];
37962
+ var _useState11 = useState(false),
37963
+ _useState12 = _slicedToArray(_useState11, 2),
37964
+ enteredViaChooser = _useState12[0],
37965
+ setEnteredViaChooser = _useState12[1];
37629
37966
  var themeEntries = themes ? Object.entries(themes) : [];
37630
37967
  var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
37631
37968
  var rowStyles = getStylesForItem(themeObjects.PANEL_HEADER, currentTheme, {
@@ -37636,7 +37973,7 @@ var ThemesSection = function ThemesSection(_ref) {
37636
37973
  var prevCreateRequested = useRef(false);
37637
37974
  useEffect(function () {
37638
37975
  if (createRequested && !prevCreateRequested.current) {
37639
- setGenerateMode(GENERATE_MODES.WIZARD);
37976
+ setGenerateMode(GENERATE_MODES.CHOOSER);
37640
37977
  setWizardName("");
37641
37978
  setWizardMethod(null);
37642
37979
  setWizardTheme(null);
@@ -37718,9 +38055,9 @@ var ThemesSection = function ThemesSection(_ref) {
37718
38055
  }
37719
38056
  var listContent = /*#__PURE__*/jsxs("div", {
37720
38057
  className: "flex flex-col h-full",
37721
- children: [/*#__PURE__*/jsxs("div", {
38058
+ children: [/*#__PURE__*/jsx("div", {
37722
38059
  className: "flex-shrink-0 flex flex-col gap-2 px-3 py-2 ".concat(rowStyles.backgroundColor || ""),
37723
- children: [/*#__PURE__*/jsxs("div", {
38060
+ children: /*#__PURE__*/jsxs("div", {
37724
38061
  className: "flex flex-row items-center justify-between",
37725
38062
  children: [/*#__PURE__*/jsxs("div", {
37726
38063
  className: "flex flex-row items-center gap-2",
@@ -37738,32 +38075,7 @@ var ThemesSection = function ThemesSection(_ref) {
37738
38075
  className: "text-xs opacity-50",
37739
38076
  children: themeVariant === "dark" ? "Dark" : "Light"
37740
38077
  })]
37741
- }), /*#__PURE__*/jsx("div", {
37742
- className: "flex bg-white/5 rounded-md p-0.5",
37743
- children: [{
37744
- key: "themes",
37745
- label: "My Themes"
37746
- }, {
37747
- key: "marketplace",
37748
- label: "Marketplace"
37749
- }].map(function (tab) {
37750
- var currentTab = installMode === "marketplace" ? "marketplace" : "themes";
37751
- return /*#__PURE__*/jsx("button", {
37752
- type: "button",
37753
- onClick: function onClick() {
37754
- if (tab.key === "marketplace") {
37755
- setInstallMode("marketplace");
37756
- setSelectedThemeKey(null);
37757
- setGenerateMode(GENERATE_MODES.NONE);
37758
- } else {
37759
- setInstallMode(null);
37760
- }
37761
- },
37762
- className: "flex-1 px-2 py-0.5 rounded text-[11px] transition-colors ".concat(currentTab === tab.key ? "bg-white/10 font-medium opacity-90" : "opacity-50 hover:opacity-70"),
37763
- children: tab.label
37764
- }, tab.key);
37765
- })
37766
- })]
38078
+ })
37767
38079
  }), /*#__PURE__*/jsx("div", {
37768
38080
  className: "flex-1 overflow-y-auto min-h-0",
37769
38081
  children: /*#__PURE__*/jsxs(Sidebar.Content, {
@@ -37787,7 +38099,9 @@ var ThemesSection = function ThemesSection(_ref) {
37787
38099
  setGenerateMode(GENERATE_MODES.NONE);
37788
38100
  setInstallMode(null);
37789
38101
  },
37790
- badge: isActive ? "active" : null,
38102
+ badge: /*#__PURE__*/jsx(ThemeColorDots, {
38103
+ theme: theme
38104
+ }),
37791
38105
  className: isSelected ? "bg-white/10 opacity-100" : "",
37792
38106
  children: theme.name || key
37793
38107
  }, key);
@@ -37805,6 +38119,10 @@ var ThemesSection = function ThemesSection(_ref) {
37805
38119
  detailContent = /*#__PURE__*/jsx(DiscoverThemesDetail, {
37806
38120
  onBack: function onBack() {
37807
38121
  setInstallMode(null);
38122
+ if (enteredViaChooser) {
38123
+ setGenerateMode(GENERATE_MODES.CHOOSER);
38124
+ setEnteredViaChooser(false);
38125
+ }
37808
38126
  },
37809
38127
  appId: appId,
37810
38128
  onInstallComplete: function onInstallComplete() {
@@ -37818,6 +38136,17 @@ var ThemesSection = function ThemesSection(_ref) {
37818
38136
  }
37819
38137
  }
37820
38138
  });
38139
+ } else if (generateMode === GENERATE_MODES.CHOOSER) {
38140
+ detailContent = /*#__PURE__*/jsx(ThemeNewChooser, {
38141
+ onSearchThemes: function onSearchThemes() {
38142
+ setGenerateMode(GENERATE_MODES.NONE);
38143
+ setInstallMode("marketplace");
38144
+ setEnteredViaChooser(true);
38145
+ },
38146
+ onCreateNew: function onCreateNew() {
38147
+ setGenerateMode(GENERATE_MODES.WIZARD);
38148
+ }
38149
+ });
37821
38150
  } else if (generateMode === GENERATE_MODES.WIZARD) {
37822
38151
  detailContent = /*#__PURE__*/jsx(ThemeQuickCreate, {
37823
38152
  wizardName: wizardName,
@@ -38168,7 +38497,9 @@ var RegistryPackageDetail = function RegistryPackageDetail(_ref) {
38168
38497
  _ref$isInstalling = _ref.isInstalling,
38169
38498
  isInstalling = _ref$isInstalling === void 0 ? false : _ref$isInstalling,
38170
38499
  _ref$installError = _ref.installError,
38171
- installError = _ref$installError === void 0 ? null : _ref$installError;
38500
+ installError = _ref$installError === void 0 ? null : _ref$installError,
38501
+ _ref$isInstalled = _ref.isInstalled,
38502
+ isInstalled = _ref$isInstalled === void 0 ? false : _ref$isInstalled;
38172
38503
  var _useContext = useContext(ThemeContext),
38173
38504
  currentTheme = _useContext.currentTheme;
38174
38505
  var panelStyles = getStylesForItem(themeObjects.PANEL, currentTheme, {
@@ -38188,9 +38519,15 @@ var RegistryPackageDetail = function RegistryPackageDetail(_ref) {
38188
38519
  className: "h-5 w-5"
38189
38520
  })
38190
38521
  }), /*#__PURE__*/jsxs("div", {
38191
- children: [/*#__PURE__*/jsx(SubHeading3, {
38192
- title: widget.packageDisplayName,
38193
- padding: false
38522
+ children: [/*#__PURE__*/jsxs("div", {
38523
+ className: "flex items-center gap-2",
38524
+ children: [/*#__PURE__*/jsx(SubHeading3, {
38525
+ title: widget.packageDisplayName,
38526
+ padding: false
38527
+ }), isInstalled && /*#__PURE__*/jsx("span", {
38528
+ className: "text-[10px] px-1.5 py-0.5 rounded bg-emerald-500/20 text-emerald-400 flex-shrink-0",
38529
+ children: "Installed"
38530
+ })]
38194
38531
  }), /*#__PURE__*/jsxs("div", {
38195
38532
  className: "flex items-center gap-2 mt-0.5",
38196
38533
  children: [/*#__PURE__*/jsxs("span", {
@@ -38301,13 +38638,13 @@ var RegistryPackageDetail = function RegistryPackageDetail(_ref) {
38301
38638
  }), /*#__PURE__*/jsx("div", {
38302
38639
  className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
38303
38640
  children: /*#__PURE__*/jsx(Button, {
38304
- title: isInstalling ? "Installing..." : "Install Package",
38305
- bgColor: "bg-blue-600",
38306
- hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
38641
+ title: isInstalled ? "Installed" : isInstalling ? "Installing..." : "Install Package",
38642
+ bgColor: isInstalled ? "bg-emerald-600/50" : "bg-blue-600",
38643
+ hoverBackgroundColor: isInstalled || isInstalling ? "" : "hover:bg-blue-700",
38307
38644
  textSize: "text-sm",
38308
38645
  padding: "py-1.5 px-4",
38309
38646
  onClick: onInstall,
38310
- disabled: isInstalling
38647
+ disabled: isInstalling || isInstalled
38311
38648
  })
38312
38649
  })]
38313
38650
  });
@@ -38410,7 +38747,11 @@ var useRegistrySearch = function useRegistrySearch() {
38410
38747
  return window.mainApi.registry.search(query !== null && query !== void 0 ? query : searchQuery, filters);
38411
38748
  case 3:
38412
38749
  result = _context.sent;
38413
- pkgs = result.packages || [];
38750
+ // Only include packages that contain at least one widget
38751
+ // (filters out theme-only packages, etc.)
38752
+ pkgs = (result.packages || []).filter(function (pkg) {
38753
+ return pkg.widgets && pkg.widgets.length > 0;
38754
+ });
38414
38755
  setPackages(pkgs);
38415
38756
 
38416
38757
  // Flatten packages into widget entries
@@ -38629,6 +38970,83 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
38629
38970
  _useState4 = _slicedToArray(_useState3, 2),
38630
38971
  toolConflictWarning = _useState4[0],
38631
38972
  setToolConflictWarning = _useState4[1];
38973
+
38974
+ // Track installed package names (same pattern as WidgetSidebar)
38975
+ var _useState5 = useState(new Set()),
38976
+ _useState6 = _slicedToArray(_useState5, 2),
38977
+ installedPackageNames = _useState6[0],
38978
+ setInstalledPackageNames = _useState6[1];
38979
+ var loadInstalledPackages = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
38980
+ var widgets, names, _iterator, _step, w, folderName, _folderName;
38981
+ return _regeneratorRuntime.wrap(function (_context) {
38982
+ while (1) switch (_context.prev = _context.next) {
38983
+ case 0:
38984
+ _context.prev = 0;
38985
+ _context.next = 1;
38986
+ return window.mainApi.widgets.list();
38987
+ case 1:
38988
+ widgets = _context.sent;
38989
+ names = new Set();
38990
+ _iterator = _createForOfIteratorHelper$2(widgets);
38991
+ try {
38992
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
38993
+ w = _step.value;
38994
+ if (w.name) names.add(w.name);
38995
+ if (w.path) {
38996
+ folderName = w.path.split("/").pop();
38997
+ if (folderName) names.add(folderName);
38998
+ }
38999
+ if (w.author && w.name) {
39000
+ names.add("".concat(w.author, "/").concat(w.name));
39001
+ }
39002
+ if (w.author && w.path) {
39003
+ _folderName = w.path.split("/").pop();
39004
+ if (_folderName) names.add("".concat(w.author, "/").concat(_folderName));
39005
+ }
39006
+ }
39007
+ } catch (err) {
39008
+ _iterator.e(err);
39009
+ } finally {
39010
+ _iterator.f();
39011
+ }
39012
+ setInstalledPackageNames(names);
39013
+ _context.next = 3;
39014
+ break;
39015
+ case 2:
39016
+ _context.prev = 2;
39017
+ _context["catch"](0);
39018
+ case 3:
39019
+ case "end":
39020
+ return _context.stop();
39021
+ }
39022
+ }, _callee, null, [[0, 2]]);
39023
+ })), []);
39024
+ useEffect(function () {
39025
+ loadInstalledPackages();
39026
+ var handleWidgetsUpdated = function handleWidgetsUpdated() {
39027
+ return loadInstalledPackages();
39028
+ };
39029
+ window.addEventListener("dash:widgets-updated", handleWidgetsUpdated);
39030
+ return function () {
39031
+ return window.removeEventListener("dash:widgets-updated", handleWidgetsUpdated);
39032
+ };
39033
+ }, [loadInstalledPackages]);
39034
+ var isPackageInstalled = useCallback(function (pkg) {
39035
+ if (installedPackageNames.has(pkg.name) || pkg.scope && installedPackageNames.has("".concat(pkg.scope, "/").concat(pkg.name))) {
39036
+ return true;
39037
+ }
39038
+ var packageWidgets = pkg.widgets || [];
39039
+ if (packageWidgets.length > 0) {
39040
+ var cMap = ComponentManager.componentMap();
39041
+ var cMapKeys = Object.keys(cMap);
39042
+ return packageWidgets.some(function (w) {
39043
+ return w.name in cMap || cMapKeys.some(function (k) {
39044
+ return k === w.name || k.endsWith("_".concat(w.name));
39045
+ });
39046
+ });
39047
+ }
39048
+ return false;
39049
+ }, [installedPackageNames]);
38632
39050
  var selectedWidget = selectedPackageName ? flatWidgets.find(function (w) {
38633
39051
  return w.packageName === selectedPackageName;
38634
39052
  }) : null;
@@ -38637,31 +39055,31 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
38637
39055
  var checkToolConflicts = function checkToolConflicts(widget) {
38638
39056
  var conflicts = [];
38639
39057
  var packageWidgets = widget.packageWidgets || [];
38640
- var _iterator = _createForOfIteratorHelper$2(packageWidgets),
38641
- _step;
39058
+ var _iterator2 = _createForOfIteratorHelper$2(packageWidgets),
39059
+ _step2;
38642
39060
  try {
38643
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
38644
- var w = _step.value;
38645
- var _iterator2 = _createForOfIteratorHelper$2(w.providers || []),
38646
- _step2;
39061
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
39062
+ var w = _step2.value;
39063
+ var _iterator3 = _createForOfIteratorHelper$2(w.providers || []),
39064
+ _step3;
38647
39065
  try {
38648
39066
  var _loop = function _loop() {
38649
39067
  var _p$requiredTools;
38650
- var p = _step2.value;
39068
+ var p = _step3.value;
38651
39069
  if (!((_p$requiredTools = p.requiredTools) !== null && _p$requiredTools !== void 0 && _p$requiredTools.length) || p.providerClass !== "mcp") return 1; // continue
38652
39070
  // Find matching user provider
38653
- var matchingProviders = Object.entries(providers).filter(function (_ref2) {
38654
- var _ref3 = _slicedToArray(_ref2, 2),
38655
- prov = _ref3[1];
39071
+ var matchingProviders = Object.entries(providers).filter(function (_ref3) {
39072
+ var _ref4 = _slicedToArray(_ref3, 2),
39073
+ prov = _ref4[1];
38656
39074
  return prov.type === p.type && prov.providerClass === "mcp" && prov.allowedTools;
38657
39075
  });
38658
- var _iterator3 = _createForOfIteratorHelper$2(matchingProviders),
38659
- _step3;
39076
+ var _iterator4 = _createForOfIteratorHelper$2(matchingProviders),
39077
+ _step4;
38660
39078
  try {
38661
39079
  var _loop2 = function _loop2() {
38662
- var _step3$value = _slicedToArray(_step3.value, 2),
38663
- provName = _step3$value[0],
38664
- prov = _step3$value[1];
39080
+ var _step4$value = _slicedToArray(_step4.value, 2),
39081
+ provName = _step4$value[0],
39082
+ prov = _step4$value[1];
38665
39083
  var blocked = p.requiredTools.filter(function (t) {
38666
39084
  return !prov.allowedTools.includes(t);
38667
39085
  });
@@ -38673,28 +39091,28 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
38673
39091
  });
38674
39092
  }
38675
39093
  };
38676
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
39094
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
38677
39095
  _loop2();
38678
39096
  }
38679
39097
  } catch (err) {
38680
- _iterator3.e(err);
39098
+ _iterator4.e(err);
38681
39099
  } finally {
38682
- _iterator3.f();
39100
+ _iterator4.f();
38683
39101
  }
38684
39102
  };
38685
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
39103
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
38686
39104
  if (_loop()) continue;
38687
39105
  }
38688
39106
  } catch (err) {
38689
- _iterator2.e(err);
39107
+ _iterator3.e(err);
38690
39108
  } finally {
38691
- _iterator2.f();
39109
+ _iterator3.f();
38692
39110
  }
38693
39111
  }
38694
39112
  } catch (err) {
38695
- _iterator.e(err);
39113
+ _iterator2.e(err);
38696
39114
  } finally {
38697
- _iterator.f();
39115
+ _iterator2.f();
38698
39116
  }
38699
39117
  return conflicts;
38700
39118
  };
@@ -38737,7 +39155,10 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
38737
39155
  widget: selectedWidget,
38738
39156
  onInstall: handleInstall,
38739
39157
  isInstalling: isInstalling,
38740
- installError: installError
39158
+ installError: installError,
39159
+ isInstalled: selectedWidget ? isPackageInstalled(packages.find(function (p) {
39160
+ return p.name === selectedPackageName;
39161
+ }) || {}) : false
38741
39162
  })]
38742
39163
  });
38743
39164
  }
@@ -38790,6 +39211,7 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
38790
39211
  return w.packageName === pkg.name;
38791
39212
  });
38792
39213
  var hasIncompatible = (pkgWidget === null || pkgWidget === void 0 ? void 0 : pkgWidget.missingApis) && pkgWidget.missingApis.length > 0;
39214
+ var isInstalled = isPackageInstalled(pkg);
38793
39215
  return /*#__PURE__*/jsx(Sidebar.Item, {
38794
39216
  icon: /*#__PURE__*/jsx(FontAwesomeIcon, {
38795
39217
  icon: hasIncompatible ? "triangle-exclamation" : "cube",
@@ -38799,7 +39221,14 @@ var DiscoverWidgetsDetail = function DiscoverWidgetsDetail(_ref) {
38799
39221
  return setSelectedPackageName(pkg.name);
38800
39222
  },
38801
39223
  badge: "".concat(widgetCount),
38802
- children: pkg.displayName || pkg.name
39224
+ className: isInstalled ? "opacity-50" : "",
39225
+ children: /*#__PURE__*/jsxs("span", {
39226
+ className: "flex items-center gap-1.5",
39227
+ children: [pkg.displayName || pkg.name, isInstalled && /*#__PURE__*/jsx("span", {
39228
+ className: "text-[10px] text-emerald-400",
39229
+ children: "Installed"
39230
+ })]
39231
+ })
38803
39232
  }, pkg.name);
38804
39233
  })
38805
39234
  });
@@ -44716,5 +45145,5 @@ var WorkspaceMenu = function WorkspaceMenu(_ref) {
44716
45145
 
44717
45146
  ComponentManager.registerContainerTypes(LayoutContainer, LayoutGridContainer);
44718
45147
 
44719
- export { ALGOLIA_ANALYTICS_FOR_QUERY, ALGOLIA_ANALYTICS_FOR_QUERY_COMPLETE, ALGOLIA_ANALYTICS_FOR_QUERY_ERROR, ALGOLIA_LIST_INDICES, ALGOLIA_LIST_INDICES_COMPLETE, ALGOLIA_LIST_INDICES_ERROR, AVAILABLE_COLORS, AddMenuItemModal, AdvancedMcpConfig, AppContext, AppSettingsModal, AppThemeScope, AppWrapper, CHOOSE_FILE, CHOOSE_FILE_COMPLETE, CHOOSE_FILE_ERROR, ColorModel, ComponentConfigModel, ComponentManager, ContextModel, DATA_JSON_TO_CSV_FILE, DATA_JSON_TO_CSV_FILE_COMPLETE, DATA_JSON_TO_CSV_FILE_ERROR, DATA_JSON_TO_CSV_STRING, DATA_JSON_TO_CSV_STRING_COMPLETE, DATA_JSON_TO_CSV_STRING_ERROR, DATA_READ_FROM_FILE, DATA_READ_FROM_FILE_COMPLETE, DATA_READ_FROM_FILE_ERROR, DATA_SAVE_TO_FILE, DATA_SAVE_TO_FILE_COMPLETE, DATA_SAVE_TO_FILE_ERROR, DashCommandPalette, DashNavbar, DashSidebar, DashTabBar, DashboardStage as Dashboard, DashboardApi, DashboardContext, DashboardFooter, DashboardHeader, DashboardMenuItem, DashboardModel, DashboardMonitor, DashboardPublisher, DashboardStage, DashboardThemeProvider, DashboardWrapper, ElectronDashboardApi, ErrorBoundary, ExternalWidget, GRID_CELL_WIDGET_TYPE, HARMONY_STRATEGIES, LAYOUT_LIST, LAYOUT_LIST_COMPLETE, LAYOUT_LIST_ERROR, LAYOUT_SAVE, LAYOUT_SAVE_COMPLETE, LAYOUT_SAVE_ERROR, Layout, LayoutBuilder, LayoutBuilderAddItemModal, LayoutBuilderConfigContainerMenuItem, LayoutBuilderConfigMenuItem, LayoutBuilderConfigModal, LayoutBuilderEditItemModal, LayoutBuilderEventModal, LayoutBuilderGridItem, LayoutContainer, LayoutDragBuilder, LayoutDragBuilderEdit, LayoutGridContainer, LayoutManagerModal, LayoutModel, LayoutQuickAddMenu, MCP_CALL_TOOL_COMPLETE, MCP_CALL_TOOL_ERROR, MCP_GET_CATALOG_COMPLETE, MCP_GET_CATALOG_ERROR, MCP_LIST_RESOURCES_COMPLETE, MCP_LIST_RESOURCES_ERROR, MCP_LIST_TOOLS_COMPLETE, MCP_LIST_TOOLS_ERROR, MCP_READ_RESOURCE_COMPLETE, MCP_READ_RESOURCE_ERROR, MCP_RUN_AUTH_COMPLETE, MCP_RUN_AUTH_ERROR, MCP_SERVER_STATUS_COMPLETE, MCP_SERVER_STATUS_ERROR, MCP_START_SERVER_COMPLETE, MCP_START_SERVER_ERROR, MCP_STOP_SERVER_COMPLETE, MCP_STOP_SERVER_ERROR, MENU_ITEMS_DELETE, MENU_ITEMS_DELETE_COMPLETE, MENU_ITEMS_DELETE_ERROR, MENU_ITEMS_LIST, MENU_ITEMS_LIST_COMPLETE, MENU_ITEMS_LIST_ERROR, MENU_ITEMS_SAVE, MENU_ITEMS_SAVE_COMPLETE, MENU_ITEMS_SAVE_ERROR, MainMenu, MainMenuItem, MainMenuSection, McpServerPicker, MenuItemModel, MenuSlideOverlay, MergeCellsModal, MissingProviderPrompt, MockDashboardApi, PROVIDER_DELETE_COMPLETE, PROVIDER_DELETE_ERROR, PROVIDER_GET_COMPLETE, PROVIDER_GET_ERROR, PROVIDER_LIST_COMPLETE, PROVIDER_LIST_ERROR, PROVIDER_SAVE_COMPLETE, PROVIDER_SAVE_ERROR, PanelCode, PanelEditItem, PanelEditItemHandlers, PanelEditItemNotifications, ProviderContext, ProviderErrorBoundary, ProviderForm, ProviderSelector, SECURE_STORAGE_ENCRYPT_STRING, SECURE_STORAGE_ENCRYPT_STRING_COMPLETE, SECURE_STORAGE_ENCRYPT_STRING_ERROR, SECURE_STORE_ENCRYPTION_CHECK, SECURE_STORE_ENCRYPTION_CHECK_COMPLETE, SECURE_STORE_ENCRYPTION_CHECK_ERROR, SECURE_STORE_GET_DATA, SECURE_STORE_GET_DATA_COMPLETE, SECURE_STORE_GET_DATA_ERROR, SECURE_STORE_SET_DATA, SECURE_STORE_SET_DATA_COMPLETE, SECURE_STORE_SET_DATA_ERROR, SETTINGS_GET, SETTINGS_GET_COMPLETE, SETTINGS_GET_ERROR, SETTINGS_SAVE, SETTINGS_SAVE_COMPLETE, SETTINGS_SAVE_ERROR, SIDEBAR_WIDGET_TYPE, SettingsModel, SideMenu, SplitCellModal, THEME_DELETE, THEME_DELETE_COMPLETE, THEME_DELETE_ERROR, THEME_LIST, THEME_LIST_COMPLETE, THEME_LIST_ERROR, THEME_SAVE, THEME_SAVE_COMPLETE, THEME_SAVE_ERROR, ThemeApi, ThemeManagerModal, ThemeModel, ThemeWrapper, WORKSPACE_DELETE, WORKSPACE_DELETE_COMPLETE, WORKSPACE_DELETE_ERROR, WORKSPACE_LIST, WORKSPACE_LIST_COMPLETE, WORKSPACE_LIST_ERROR, WORKSPACE_SAVE, WORKSPACE_SAVE_COMPLETE, WORKSPACE_SAVE_ERROR, WebDashboardApi, Widget, WidgetApi, WidgetConfigPanel, WidgetContext, WidgetFactory, WidgetPopoutStage, WidgetProviderWrapper, WidgetSidebar, Workspace, WorkspaceContext, WorkspaceFooter, WorkspaceMenu, WorkspaceModel, addChildToLayoutItem, addItemToItemLayout, buildMcpConfigFromOverrides, canHaveChildren, changeDirectionForLayoutItem, createProviderRegistry, deriveFormFields, envMappingToRows, evaluateBundle, extractWidgetConfigs, formStateToMcpJson, formatFieldName, generateCustomTheme, generateHarmonyTheme, generateRandomTheme, generateThemeName, getBorderStyle, getChildrenForLayoutItem, getComponentInLayout, getContainerBorderColor, getContainerColor, getIndexOfLayoutChildrenForItem, getIndexOfLayoutItem, getLayoutItemById, getLayoutItemForWorkspace, getNearestParentWorkspace, getNextHighestId, getNextHighestItemInLayout, getNextHighestOrder, getNextHighestParentId, getNextLowestItemInLayout, getParentForLayoutItem, getParentWorkspaceForItem, getThemePresets, getUserConfigurableProviders, getWidgetsForWorkspace, getWorkspacesForWorkspace, headerTemplateToRows, isContainer, isLikelySecret, isMaxOrderForItem, isMinOrderForItem, isWidget, isWidgetResolvable, isWorkspace, layoutItemHasWorkspaceAsChild, loadWidgetBundle, mcpJsonToFormState, numChildrenForLayout, removeItemFromLayout, renderComponent, renderGridLayout, renderGridLayoutFlow, _renderLayout as renderLayout, renderLayoutMenu, replaceItemInLayout, resolveIcon, setHostModules, traverseParentTree, updateLayoutItem, updateParentForItem, useDashboard, useMcpProvider, useNotifications, useProvider, useProviderClient, useWidgetEvents, useWidgetProviders, validateCellMerge, validateGridCell, validateGridPlacement, validateWidgetPlacement, withProviderDetection };
45148
+ export { ALGOLIA_ANALYTICS_FOR_QUERY, ALGOLIA_ANALYTICS_FOR_QUERY_COMPLETE, ALGOLIA_ANALYTICS_FOR_QUERY_ERROR, ALGOLIA_LIST_INDICES, ALGOLIA_LIST_INDICES_COMPLETE, ALGOLIA_LIST_INDICES_ERROR, AVAILABLE_COLORS, AddMenuItemModal, AdvancedMcpConfig, AppContext, AppSettingsModal, AppThemeScope, AppWrapper, CHOOSE_FILE, CHOOSE_FILE_COMPLETE, CHOOSE_FILE_ERROR, ColorModel, ComponentConfigModel, ComponentManager, ContextModel, DATA_JSON_TO_CSV_FILE, DATA_JSON_TO_CSV_FILE_COMPLETE, DATA_JSON_TO_CSV_FILE_ERROR, DATA_JSON_TO_CSV_STRING, DATA_JSON_TO_CSV_STRING_COMPLETE, DATA_JSON_TO_CSV_STRING_ERROR, DATA_READ_FROM_FILE, DATA_READ_FROM_FILE_COMPLETE, DATA_READ_FROM_FILE_ERROR, DATA_SAVE_TO_FILE, DATA_SAVE_TO_FILE_COMPLETE, DATA_SAVE_TO_FILE_ERROR, DashCommandPalette, DashNavbar, DashSidebar, DashTabBar, DashboardStage as Dashboard, DashboardApi, DashboardContext, DashboardFooter, DashboardHeader, DashboardMenuItem, DashboardModel, DashboardMonitor, DashboardPublisher, DashboardStage, DashboardThemeProvider, DashboardWrapper, ElectronDashboardApi, ErrorBoundary, ExternalWidget, GRID_CELL_WIDGET_TYPE, HARMONY_STRATEGIES, LAYOUT_LIST, LAYOUT_LIST_COMPLETE, LAYOUT_LIST_ERROR, LAYOUT_SAVE, LAYOUT_SAVE_COMPLETE, LAYOUT_SAVE_ERROR, Layout, LayoutBuilder, LayoutBuilderAddItemModal, LayoutBuilderConfigContainerMenuItem, LayoutBuilderConfigMenuItem, LayoutBuilderConfigModal, LayoutBuilderEditItemModal, LayoutBuilderEventModal, LayoutBuilderGridItem, LayoutContainer, LayoutDragBuilder, LayoutDragBuilderEdit, LayoutGridContainer, LayoutManagerModal, LayoutModel, LayoutQuickAddMenu, MCP_CALL_TOOL_COMPLETE, MCP_CALL_TOOL_ERROR, MCP_GET_CATALOG_COMPLETE, MCP_GET_CATALOG_ERROR, MCP_LIST_RESOURCES_COMPLETE, MCP_LIST_RESOURCES_ERROR, MCP_LIST_TOOLS_COMPLETE, MCP_LIST_TOOLS_ERROR, MCP_READ_RESOURCE_COMPLETE, MCP_READ_RESOURCE_ERROR, MCP_RUN_AUTH_COMPLETE, MCP_RUN_AUTH_ERROR, MCP_SERVER_STATUS_COMPLETE, MCP_SERVER_STATUS_ERROR, MCP_START_SERVER_COMPLETE, MCP_START_SERVER_ERROR, MCP_STOP_SERVER_COMPLETE, MCP_STOP_SERVER_ERROR, MENU_ITEMS_DELETE, MENU_ITEMS_DELETE_COMPLETE, MENU_ITEMS_DELETE_ERROR, MENU_ITEMS_LIST, MENU_ITEMS_LIST_COMPLETE, MENU_ITEMS_LIST_ERROR, MENU_ITEMS_SAVE, MENU_ITEMS_SAVE_COMPLETE, MENU_ITEMS_SAVE_ERROR, MainMenu, MainMenuItem, MainMenuSection, McpServerPicker, MenuItemModel, MenuSlideOverlay, MergeCellsModal, MissingProviderPrompt, MockDashboardApi, PROVIDER_DELETE_COMPLETE, PROVIDER_DELETE_ERROR, PROVIDER_GET_COMPLETE, PROVIDER_GET_ERROR, PROVIDER_LIST_COMPLETE, PROVIDER_LIST_ERROR, PROVIDER_SAVE_COMPLETE, PROVIDER_SAVE_ERROR, PanelCode, PanelEditItem, PanelEditItemHandlers, PanelEditItemNotifications, ProviderContext, ProviderErrorBoundary, ProviderForm, ProviderSelector, SECURE_STORAGE_ENCRYPT_STRING, SECURE_STORAGE_ENCRYPT_STRING_COMPLETE, SECURE_STORAGE_ENCRYPT_STRING_ERROR, SECURE_STORE_ENCRYPTION_CHECK, SECURE_STORE_ENCRYPTION_CHECK_COMPLETE, SECURE_STORE_ENCRYPTION_CHECK_ERROR, SECURE_STORE_GET_DATA, SECURE_STORE_GET_DATA_COMPLETE, SECURE_STORE_GET_DATA_ERROR, SECURE_STORE_SET_DATA, SECURE_STORE_SET_DATA_COMPLETE, SECURE_STORE_SET_DATA_ERROR, SETTINGS_GET, SETTINGS_GET_COMPLETE, SETTINGS_GET_ERROR, SETTINGS_SAVE, SETTINGS_SAVE_COMPLETE, SETTINGS_SAVE_ERROR, SIDEBAR_WIDGET_TYPE, SettingsModel, SideMenu, SplitCellModal, THEME_DELETE, THEME_DELETE_COMPLETE, THEME_DELETE_ERROR, THEME_LIST, THEME_LIST_COMPLETE, THEME_LIST_ERROR, THEME_SAVE, THEME_SAVE_COMPLETE, THEME_SAVE_ERROR, ThemeApi, ThemeColorDots, ThemeManagerModal, ThemeModel, ThemeWrapper, WORKSPACE_DELETE, WORKSPACE_DELETE_COMPLETE, WORKSPACE_DELETE_ERROR, WORKSPACE_LIST, WORKSPACE_LIST_COMPLETE, WORKSPACE_LIST_ERROR, WORKSPACE_SAVE, WORKSPACE_SAVE_COMPLETE, WORKSPACE_SAVE_ERROR, WebDashboardApi, Widget, WidgetApi, WidgetConfigPanel, WidgetContext, WidgetFactory, WidgetPopoutStage, WidgetProviderWrapper, WidgetSidebar, Workspace, WorkspaceContext, WorkspaceFooter, WorkspaceMenu, WorkspaceModel, addChildToLayoutItem, addItemToItemLayout, buildMcpConfigFromOverrides, canHaveChildren, changeDirectionForLayoutItem, createProviderRegistry, deriveFormFields, envMappingToRows, evaluateBundle, extractWidgetConfigs, formStateToMcpJson, formatFieldName, generateCustomTheme, generateHarmonyTheme, generateRandomTheme, generateThemeName, getBorderStyle, getChildrenForLayoutItem, getComponentInLayout, getContainerBorderColor, getContainerColor, getIndexOfLayoutChildrenForItem, getIndexOfLayoutItem, getLayoutItemById, getLayoutItemForWorkspace, getNearestParentWorkspace, getNextHighestId, getNextHighestItemInLayout, getNextHighestOrder, getNextHighestParentId, getNextLowestItemInLayout, getParentForLayoutItem, getParentWorkspaceForItem, getThemePresets, getUserConfigurableProviders, getWidgetsForWorkspace, getWorkspacesForWorkspace, headerTemplateToRows, isContainer, isLikelySecret, isMaxOrderForItem, isMinOrderForItem, isWidget, isWidgetResolvable, isWorkspace, layoutItemHasWorkspaceAsChild, loadWidgetBundle, mcpJsonToFormState, numChildrenForLayout, removeItemFromLayout, renderComponent, renderGridLayout, renderGridLayoutFlow, _renderLayout as renderLayout, renderLayoutMenu, replaceItemInLayout, resolveIcon, setHostModules, traverseParentTree, updateLayoutItem, updateParentForItem, useDashboard, useMcpProvider, useNotifications, useProvider, useProviderClient, useWidgetEvents, useWidgetProviders, validateCellMerge, validateGridCell, validateGridPlacement, validateWidgetPlacement, withProviderDetection };
44720
45149
  //# sourceMappingURL=index.esm.js.map