@trops/dash-core 0.1.131 → 0.1.133

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.js CHANGED
@@ -3621,6 +3621,36 @@ var RegistryDashboardDetail = function RegistryDashboardDetail(_ref) {
3621
3621
  children: tag
3622
3622
  }, tag);
3623
3623
  })
3624
+ }), pkg.theme && /*#__PURE__*/jsxRuntime.jsxs("div", {
3625
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3626
+ className: "text-xs font-semibold opacity-50 mb-1 block",
3627
+ children: "INCLUDES THEME"
3628
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3629
+ className: "p-3 rounded ".concat(currentTheme["bg-primary-medium"], " flex items-center gap-3"),
3630
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
3631
+ icon: "palette",
3632
+ className: "h-4 w-4 opacity-60"
3633
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3634
+ className: "flex-1",
3635
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3636
+ className: "text-sm font-medium",
3637
+ children: pkg.theme.name || pkg.theme.key || "Bundled Theme"
3638
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
3639
+ className: "text-xs opacity-40 ml-2",
3640
+ children: "Will be auto-installed"
3641
+ })]
3642
+ }), pkg.theme.colors && /*#__PURE__*/jsxRuntime.jsx("div", {
3643
+ className: "flex items-center gap-1",
3644
+ children: [pkg.theme.colors.primary, pkg.theme.colors.secondary, pkg.theme.colors.tertiary].filter(Boolean).map(function (color, i) {
3645
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
3646
+ className: "h-4 w-4 rounded-full border border-white/20",
3647
+ style: {
3648
+ backgroundColor: color
3649
+ }
3650
+ }, i);
3651
+ })
3652
+ })]
3653
+ })]
3624
3654
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
3625
3655
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
3626
3656
  className: "text-xs font-semibold opacity-50 mb-1 block",
@@ -36166,368 +36196,1511 @@ var ProvidersSection = function ProvidersSection(_ref) {
36166
36196
  });
36167
36197
  };
36168
36198
 
36169
- var TOKEN_TYPES = ["bg", "text", "border"];
36170
-
36171
- // --- Color Swatch Grid ---
36172
-
36173
- var SwatchCell = function SwatchCell(_ref) {
36174
- var tokenKey = _ref.tokenKey,
36175
- resolvedClass = _ref.resolvedClass,
36176
- type = _ref.type;
36177
- var tooltip = "".concat(tokenKey, " \u2192 ").concat(resolvedClass || "(none)");
36178
- if (type === "bg") {
36179
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36180
- className: "h-8 flex-1 rounded ".concat(resolvedClass || ""),
36181
- title: tooltip
36182
- });
36183
- }
36184
- if (type === "text") {
36185
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36186
- className: "h-8 flex-1 rounded flex items-center justify-center bg-black/10",
36187
- title: tooltip,
36188
- children: /*#__PURE__*/jsxRuntime.jsx("span", {
36189
- className: "text-xs font-bold ".concat(resolvedClass || ""),
36190
- children: "Aa"
36191
- })
36192
- });
36193
- }
36194
-
36195
- // border
36196
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36197
- className: "h-8 flex-1 rounded border-2 ".concat(resolvedClass || ""),
36198
- title: tooltip
36199
- });
36200
- };
36201
- var ColorSwatchGrid = function ColorSwatchGrid(_ref2) {
36202
- var displayTheme = _ref2.displayTheme;
36203
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36204
- className: "flex flex-col space-y-5",
36205
- children: DashReact.colorTypes.map(function (family) {
36206
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
36207
- className: "flex flex-col space-y-2",
36208
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36209
- className: "text-xs font-semibold opacity-50 capitalize",
36210
- children: family
36211
- }), TOKEN_TYPES.map(function (type) {
36212
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
36213
- className: "flex flex-row items-center gap-2",
36214
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36215
- className: "text-[10px] opacity-40 w-10 text-right shrink-0",
36216
- children: type
36217
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
36218
- className: "flex flex-row gap-1.5 flex-1",
36219
- children: DashReact.themeVariants.map(function (shade) {
36220
- var tokenKey = "".concat(type, "-").concat(family, "-").concat(shade);
36221
- var resolvedClass = displayTheme[tokenKey] || "";
36222
- return /*#__PURE__*/jsxRuntime.jsx(SwatchCell, {
36223
- tokenKey: tokenKey,
36224
- resolvedClass: resolvedClass,
36225
- type: type
36226
- }, shade);
36227
- })
36228
- })]
36229
- }, type);
36230
- })]
36231
- }, family);
36232
- })
36233
- });
36234
- };
36235
-
36236
- // --- Component Style Accordion ---
36237
-
36238
- var COLOR_KEYS = ["backgroundColor", "textColor", "borderColor", "hoverBackgroundColor", "hoverTextColor", "hoverBorderColor", "activeBackgroundColor", "activeTextColor", "focusRingColor", "focusBorderColor"];
36239
- var NON_COLOR_KEYS = ["shadow", "borderRadius", "spacing", "textSize", "iconSize", "fontWeight", "transition", "cursor", "disabledOpacity", "letterSpacing", "lineHeight"];
36240
- var COMPONENT_GROUPS = [{
36241
- label: "Buttons",
36242
- keys: ["BUTTON", "BUTTON_2", "BUTTON_3", "BUTTON_ICON", "BUTTON_ICON_2", "BUTTON_ICON_3"]
36243
- }, {
36244
- label: "Panels",
36245
- keys: ["PANEL", "PANEL_2", "PANEL_3", "PANEL_HEADER", "PANEL_HEADER_2", "PANEL_HEADER_3", "PANEL_FOOTER", "PANEL_FOOTER_2", "PANEL_FOOTER_3", "DASH_PANEL", "DASH_PANEL_2", "DASH_PANEL_3", "DASH_PANEL_HEADER", "DASH_PANEL_HEADER_2", "DASH_PANEL_HEADER_3", "DASH_PANEL_FOOTER", "DASH_PANEL_FOOTER_2", "DASH_PANEL_FOOTER_3"]
36246
- }, {
36247
- label: "Cards",
36248
- keys: ["CARD", "CARD_2", "CARD_3", "STAT_CARD", "STAT_CARD_LABEL", "STAT_CARD_VALUE", "STAT_CARD_CHANGE"]
36249
- }, {
36250
- label: "Typography",
36251
- keys: ["HEADING", "HEADING_2", "HEADING_3", "SUBHEADING", "SUBHEADING_2", "SUBHEADING_3", "PARAGRAPH", "PARAGRAPH_2", "PARAGRAPH_3"]
36252
- }, {
36253
- label: "Navigation",
36254
- keys: ["MENU_ITEM", "MENU_ITEM_2", "MENU_ITEM_3", "TABS", "TABS_2", "TABS_3", "TABS_LIST", "TABS_LIST_2", "TABS_LIST_3", "TABS_TRIGGER", "TABS_TRIGGER_2", "TABS_TRIGGER_3", "TABS_CONTENT", "TABS_CONTENT_2", "TABS_CONTENT_3", "SIDEBAR", "SIDEBAR_ITEM", "NAVBAR", "TABBED_NAVBAR", "BREADCRUMBS", "BREADCRUMBS_2", "BREADCRUMBS_3"]
36255
- }, {
36256
- label: "Forms",
36257
- keys: ["INPUT_TEXT", "SELECT_MENU", "TEXTAREA", "CHECKBOX", "RADIO", "SWITCH", "SLIDER", "SEARCH_INPUT", "TOGGLE", "TOGGLE_2", "TOGGLE_3", "FORM_LABEL"]
36258
- }, {
36259
- label: "Feedback",
36260
- keys: ["ALERT", "ALERT_2", "ALERT_3", "ALERT_BANNER", "TOAST", "TOAST_2", "TOAST_3", "PROGRESS_BAR", "PROGRESS_BAR_2", "PROGRESS_BAR_3", "TAG", "TAG_2", "TAG_3", "TOOLTIP", "EMPTY_STATE"]
36261
- }, {
36262
- label: "Tables",
36263
- keys: ["TABLE", "TABLE_2", "TABLE_3", "DATA_LIST", "DATA_LIST_ITEM"]
36264
- }, {
36265
- label: "Advanced",
36266
- keys: ["ACCORDION", "ACCORDION_2", "ACCORDION_3", "ACCORDION_ITEM", "ACCORDION_ITEM_2", "ACCORDION_ITEM_3", "ACCORDION_TRIGGER", "ACCORDION_TRIGGER_2", "ACCORDION_TRIGGER_3", "ACCORDION_CONTENT", "ACCORDION_CONTENT_2", "ACCORDION_CONTENT_3", "COMMAND_PALETTE", "COMMAND_PALETTE_INPUT", "COMMAND_PALETTE_ITEM", "DRAWER", "DRAWER_HEADER", "DRAWER_FOOTER", "STEPPER", "STEPPER_STEP", "STEPPER_CONNECTOR", "SKELETON", "CODE_EDITOR"]
36267
- }, {
36268
- label: "Layout",
36269
- keys: ["WIDGET_CHROME", "WIDGET", "WORKSPACE", "LAYOUT_CONTAINER", "DASHBOARD_FOOTER", "DASHBOARD_FOOTER_2", "DASHBOARD_FOOTER_3", "SETTINGS_MODAL_SIDEBAR", "SETTINGS_MODAL_FOOTER"]
36270
- }];
36271
- var ComponentStyleRow = function ComponentStyleRow(_ref3) {
36272
- var objectKey = _ref3.objectKey,
36273
- styles = _ref3.styles;
36274
- if (!styles) return null;
36275
- var colorEntries = COLOR_KEYS.filter(function (k) {
36276
- return styles[k];
36277
- }).map(function (k) {
36278
- return {
36279
- key: k,
36280
- value: styles[k]
36281
- };
36282
- });
36283
- var nonColorEntries = NON_COLOR_KEYS.filter(function (k) {
36284
- return styles[k];
36285
- }).map(function (k) {
36286
- return {
36287
- key: k,
36288
- value: styles[k]
36289
- };
36290
- });
36291
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
36292
- className: "flex flex-row items-center gap-3 py-1.5",
36293
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36294
- className: "text-[11px] font-mono opacity-70 w-40 shrink-0 truncate",
36295
- children: objectKey
36296
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
36297
- className: "flex flex-row items-center gap-1",
36298
- children: colorEntries.map(function (_ref4) {
36299
- var key = _ref4.key,
36300
- value = _ref4.value;
36301
- if (key.toLowerCase().includes("text")) {
36302
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36303
- className: "h-5 w-5 rounded-sm flex items-center justify-center bg-black/10",
36304
- title: "".concat(key, ": ").concat(value),
36305
- children: /*#__PURE__*/jsxRuntime.jsx("span", {
36306
- className: "text-[8px] font-bold ".concat(value),
36307
- children: "Aa"
36308
- })
36309
- }, key);
36310
- }
36311
- if (key.toLowerCase().includes("border")) {
36312
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36313
- className: "h-5 w-5 rounded-sm border-2 ".concat(value),
36314
- title: "".concat(key, ": ").concat(value)
36315
- }, key);
36316
- }
36317
- return /*#__PURE__*/jsxRuntime.jsx("div", {
36318
- className: "h-5 w-5 rounded-sm ".concat(value),
36319
- title: "".concat(key, ": ").concat(value)
36320
- }, key);
36321
- })
36322
- }), /*#__PURE__*/jsxRuntime.jsx("div", {
36323
- className: "flex flex-row items-center gap-2 flex-1 overflow-hidden",
36324
- children: nonColorEntries.map(function (_ref5) {
36325
- var key = _ref5.key,
36326
- value = _ref5.value;
36327
- return /*#__PURE__*/jsxRuntime.jsx("span", {
36328
- className: "text-[10px] opacity-40 whitespace-nowrap",
36329
- title: key,
36330
- children: value
36331
- }, key);
36332
- })
36333
- })]
36334
- });
36335
- };
36336
-
36337
- // --- Main Component ---
36338
-
36339
- var ThemeDetail = function ThemeDetail(_ref6) {
36340
- var themeKey = _ref6.themeKey,
36341
- themes = _ref6.themes,
36342
- currentThemeKey = _ref6.currentThemeKey,
36343
- themeVariant = _ref6.themeVariant,
36344
- onActivate = _ref6.onActivate,
36345
- onOpenThemeEditor = _ref6.onOpenThemeEditor,
36346
- _ref6$onDelete = _ref6.onDelete,
36347
- onDelete = _ref6$onDelete === void 0 ? null : _ref6$onDelete;
36348
- var theme = themeKey && themes ? themes[themeKey] : null;
36349
- var displayTheme = React.useMemo(function () {
36350
- return theme ? theme[themeVariant] || {} : {};
36351
- }, [theme, themeVariant]);
36352
- var isActive = themeKey === currentThemeKey;
36353
-
36354
- // Memoize all component styles
36355
- var allStyles = React.useMemo(function () {
36356
- var result = {};
36357
- Object.values(DashReact.themeObjects).forEach(function (key) {
36358
- result[key] = DashReact.getStylesForItem(key, displayTheme, {});
36359
- });
36360
- return result;
36361
- }, [displayTheme]);
36362
- if (!theme) return null;
36363
- return /*#__PURE__*/jsxRuntime.jsxs("div", {
36364
- className: "flex flex-col flex-1 min-h-0",
36365
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36366
- className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6",
36367
- children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36368
- className: "flex flex-row items-center gap-3",
36369
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading, {
36370
- title: theme.name || themeKey,
36371
- padding: false
36372
- }), isActive && /*#__PURE__*/jsxRuntime.jsx("span", {
36373
- className: "text-xs opacity-40",
36374
- children: "active"
36375
- })]
36376
- }), /*#__PURE__*/jsxRuntime.jsx(ColorSwatchGrid, {
36377
- displayTheme: displayTheme
36378
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36379
- className: "flex flex-col space-y-2",
36380
- children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36381
- className: "text-xs font-semibold opacity-50",
36382
- children: "Component Styles"
36383
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Accordion2, {
36384
- type: "multiple",
36385
- children: COMPONENT_GROUPS.map(function (group) {
36386
- // Only show groups that have valid theme objects
36387
- var validKeys = group.keys.filter(function (k) {
36388
- return DashReact.themeObjects[k];
36389
- });
36390
- if (validKeys.length === 0) return null;
36391
- return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Accordion2.Item, {
36392
- value: group.label,
36393
- children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.Accordion2.Trigger, {
36394
- value: group.label,
36395
- children: [group.label, " (", validKeys.length, ")"]
36396
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Accordion2.Content, {
36397
- value: group.label,
36398
- children: /*#__PURE__*/jsxRuntime.jsx("div", {
36399
- className: "flex flex-col",
36400
- children: validKeys.map(function (k) {
36401
- var objectValue = DashReact.themeObjects[k];
36402
- return /*#__PURE__*/jsxRuntime.jsx(ComponentStyleRow, {
36403
- objectKey: objectValue,
36404
- styles: allStyles[objectValue]
36405
- }, k);
36406
- })
36407
- })
36408
- })]
36409
- }, group.label);
36410
- })
36411
- })]
36412
- })]
36413
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36414
- className: "flex-shrink-0 flex flex-row justify-between px-6 py-4 border-t border-white/10",
36415
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
36416
- children: !isActive && onDelete && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
36417
- title: "Delete",
36418
- onClick: function onClick() {
36419
- return onDelete(themeKey);
36420
- },
36421
- size: "sm"
36422
- })
36423
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36424
- className: "flex flex-row gap-2",
36425
- children: [!isActive && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
36426
- title: "Activate",
36427
- onClick: function onClick() {
36428
- return onActivate(themeKey);
36429
- },
36430
- size: "sm"
36431
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
36432
- title: "Edit",
36433
- onClick: onOpenThemeEditor,
36434
- size: "sm"
36435
- })]
36436
- })]
36437
- })]
36438
- });
36439
- };
36199
+ var THEME_TAGS = ["dark", "light", "colorful", "minimal", "professional", "vibrant", "pastel", "high-contrast", "warm", "cool"];
36440
36200
 
36441
- function ownKeys$5(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; }
36442
- function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
36443
- var ThemesSection = function ThemesSection(_ref) {
36444
- var _ref$onOpenThemeEdito = _ref.onOpenThemeEditor,
36445
- onOpenThemeEditor = _ref$onOpenThemeEdito === void 0 ? null : _ref$onOpenThemeEdito,
36446
- _ref$dashApi = _ref.dashApi,
36447
- dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
36448
- _ref$credentials = _ref.credentials,
36449
- credentials = _ref$credentials === void 0 ? null : _ref$credentials,
36450
- _ref$createRequested = _ref.createRequested,
36451
- createRequested = _ref$createRequested === void 0 ? false : _ref$createRequested,
36452
- _ref$onCreateAcknowle = _ref.onCreateAcknowledged,
36453
- onCreateAcknowledged = _ref$onCreateAcknowle === void 0 ? null : _ref$onCreateAcknowle;
36201
+ /**
36202
+ * PublishThemeModal multi-step stepper for publishing a theme
36203
+ * to the Dash Registry.
36204
+ *
36205
+ * Steps:
36206
+ * 0. Account — Auth check, sign-in prompt, profile display
36207
+ * 1. Details Author name (pre-filled from profile) + description
36208
+ * 2. Tags — Predefined theme tag selection
36209
+ * 3. Publish Review summary with color swatches, publish action
36210
+ */
36211
+ var PublishThemeModal = function PublishThemeModal(_ref) {
36212
+ var _result$registryResul, _result$registryResul2;
36213
+ var isOpen = _ref.isOpen,
36214
+ setIsOpen = _ref.setIsOpen,
36215
+ appId = _ref.appId,
36216
+ themeKey = _ref.themeKey,
36217
+ themeName = _ref.themeName;
36454
36218
  var _useContext = React.useContext(DashReact.ThemeContext),
36455
- themes = _useContext.themes,
36456
- currentThemeKey = _useContext.themeKey,
36457
- themeVariant = _useContext.themeVariant,
36458
- changeCurrentTheme = _useContext.changeCurrentTheme,
36459
- changeThemeVariant = _useContext.changeThemeVariant,
36460
- changeThemesForApplication = _useContext.changeThemesForApplication,
36461
36219
  currentTheme = _useContext.currentTheme;
36462
- var _useState = React.useState(currentThemeKey),
36220
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
36221
+ grow: false
36222
+ });
36223
+
36224
+ // Stepper state
36225
+ var _useState = React.useState(0),
36463
36226
  _useState2 = _slicedToArray(_useState, 2),
36464
- selectedThemeKey = _useState2[0],
36465
- setSelectedThemeKey = _useState2[1];
36466
- var _useState3 = React.useState(GENERATE_MODES.NONE),
36227
+ step = _useState2[0],
36228
+ setStep = _useState2[1];
36229
+
36230
+ // Step 0: Account / Auth
36231
+ var _useState3 = React.useState("loading"),
36467
36232
  _useState4 = _slicedToArray(_useState3, 2),
36468
- generateMode = _useState4[0],
36469
- setGenerateMode = _useState4[1];
36470
- var _useState5 = React.useState(""),
36233
+ authStatus = _useState4[0],
36234
+ setAuthStatus = _useState4[1];
36235
+ var _useState5 = React.useState(null),
36471
36236
  _useState6 = _slicedToArray(_useState5, 2),
36472
- wizardName = _useState6[0],
36473
- setWizardName = _useState6[1];
36237
+ profile = _useState6[0],
36238
+ setProfile = _useState6[1];
36474
36239
  var _useState7 = React.useState(null),
36475
36240
  _useState8 = _slicedToArray(_useState7, 2),
36476
- wizardMethod = _useState8[0],
36477
- setWizardMethod = _useState8[1];
36478
- var _useState9 = React.useState(null),
36241
+ authFlow = _useState8[0],
36242
+ setAuthFlow = _useState8[1];
36243
+ var _useState9 = React.useState(false),
36479
36244
  _useState0 = _slicedToArray(_useState9, 2),
36480
- wizardTheme = _useState0[0],
36481
- setWizardTheme = _useState0[1];
36482
- var themeEntries = themes ? Object.entries(themes) : [];
36483
- var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
36245
+ isPolling = _useState0[0],
36246
+ setIsPolling = _useState0[1];
36247
+ var _useState1 = React.useState(null),
36248
+ _useState10 = _slicedToArray(_useState1, 2),
36249
+ authError = _useState10[0],
36250
+ setAuthError = _useState10[1];
36484
36251
 
36485
- // Handle create request from parent — enter wizard mode
36252
+ // Step 1: Details
36253
+ var _useState11 = React.useState(""),
36254
+ _useState12 = _slicedToArray(_useState11, 2),
36255
+ authorName = _useState12[0],
36256
+ setAuthorName = _useState12[1];
36257
+ var _useState13 = React.useState(""),
36258
+ _useState14 = _slicedToArray(_useState13, 2),
36259
+ description = _useState14[0],
36260
+ setDescription = _useState14[1];
36261
+
36262
+ // Step 2: Tags
36263
+ var _useState15 = React.useState([]),
36264
+ _useState16 = _slicedToArray(_useState15, 2),
36265
+ selectedTags = _useState16[0],
36266
+ setSelectedTags = _useState16[1];
36267
+
36268
+ // Publish preview (colors)
36269
+ var _useState17 = React.useState(null),
36270
+ _useState18 = _slicedToArray(_useState17, 2),
36271
+ preview = _useState18[0],
36272
+ setPreview = _useState18[1];
36273
+
36274
+ // Step 3: Publish
36275
+ var _useState19 = React.useState(false),
36276
+ _useState20 = _slicedToArray(_useState19, 2),
36277
+ isPublishing = _useState20[0],
36278
+ setIsPublishing = _useState20[1];
36279
+ var _useState21 = React.useState(null),
36280
+ _useState22 = _slicedToArray(_useState21, 2),
36281
+ result = _useState22[0],
36282
+ setResult = _useState22[1];
36283
+
36284
+ // Fetch publish preview on open
36486
36285
  React.useEffect(function () {
36487
- if (createRequested) {
36488
- setGenerateMode(GENERATE_MODES.WIZARD);
36489
- setWizardName("");
36490
- setWizardMethod(null);
36491
- setWizardTheme(null);
36492
- setSelectedThemeKey(null);
36493
- onCreateAcknowledged && onCreateAcknowledged();
36286
+ if (!isOpen || !appId || !themeKey) return;
36287
+ window.mainApi.themes.getThemePublishPreview(appId, themeKey).then(function (res) {
36288
+ if (res.success) setPreview(res);
36289
+ })["catch"](console.error);
36290
+ }, [isOpen, appId, themeKey]);
36291
+
36292
+ // Check auth status on mount
36293
+ React.useEffect(function () {
36294
+ if (!isOpen) return;
36295
+ var cancelled = false;
36296
+ function checkAuth() {
36297
+ return _checkAuth.apply(this, arguments);
36494
36298
  }
36495
- // eslint-disable-next-line react-hooks/exhaustive-deps
36496
- }, [createRequested]);
36497
- function handleCreateFromPreset(preset) {
36498
- if (!dashApi || !appId) return;
36499
- var key = preset.id || "theme-".concat(Date.now());
36500
- preset.id = key;
36501
- saveAndSelectTheme(key, preset);
36502
- setGenerateMode(GENERATE_MODES.NONE);
36299
+ function _checkAuth() {
36300
+ _checkAuth = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
36301
+ var status, userProfile;
36302
+ return _regeneratorRuntime.wrap(function (_context) {
36303
+ while (1) switch (_context.prev = _context.next) {
36304
+ case 0:
36305
+ _context.prev = 0;
36306
+ _context.next = 1;
36307
+ return window.mainApi.registryAuth.getStatus();
36308
+ case 1:
36309
+ status = _context.sent;
36310
+ if (!cancelled) {
36311
+ _context.next = 2;
36312
+ break;
36313
+ }
36314
+ return _context.abrupt("return");
36315
+ case 2:
36316
+ if (!status.authenticated) {
36317
+ _context.next = 5;
36318
+ break;
36319
+ }
36320
+ _context.next = 3;
36321
+ return window.mainApi.registryAuth.getProfile();
36322
+ case 3:
36323
+ userProfile = _context.sent;
36324
+ if (!cancelled) {
36325
+ _context.next = 4;
36326
+ break;
36327
+ }
36328
+ return _context.abrupt("return");
36329
+ case 4:
36330
+ if (userProfile) {
36331
+ setProfile(userProfile);
36332
+ setAuthStatus("authenticated");
36333
+ setAuthorName(userProfile.displayName || userProfile.username || "");
36334
+ } else {
36335
+ setAuthStatus("unauthenticated");
36336
+ }
36337
+ _context.next = 6;
36338
+ break;
36339
+ case 5:
36340
+ setAuthStatus("unauthenticated");
36341
+ case 6:
36342
+ _context.next = 8;
36343
+ break;
36344
+ case 7:
36345
+ _context.prev = 7;
36346
+ _context["catch"](0);
36347
+ if (!cancelled) setAuthStatus("unauthenticated");
36348
+ case 8:
36349
+ case "end":
36350
+ return _context.stop();
36351
+ }
36352
+ }, _callee, null, [[0, 7]]);
36353
+ }));
36354
+ return _checkAuth.apply(this, arguments);
36355
+ }
36356
+ checkAuth();
36357
+ return function () {
36358
+ cancelled = true;
36359
+ };
36360
+ }, [isOpen]);
36361
+ function resetState() {
36362
+ setStep(0);
36363
+ setAuthStatus("loading");
36364
+ setProfile(null);
36365
+ setAuthFlow(null);
36366
+ setIsPolling(false);
36367
+ setAuthError(null);
36368
+ setAuthorName("");
36369
+ setDescription("");
36370
+ setSelectedTags([]);
36371
+ setPreview(null);
36372
+ setIsPublishing(false);
36373
+ setResult(null);
36503
36374
  }
36504
- function handleCreateFromHarmony(theme) {
36505
- if (!dashApi || !appId) return;
36506
- var key = theme.id;
36507
- saveAndSelectTheme(key, theme);
36508
- setGenerateMode(GENERATE_MODES.NONE);
36375
+ function handleClose() {
36376
+ setIsOpen(false);
36377
+ setTimeout(resetState, 200);
36509
36378
  }
36510
- function handleWizardComplete() {
36511
- if (!wizardTheme || !wizardName.trim()) return;
36512
- if (!dashApi || !appId) return;
36513
- var key = wizardTheme.id || "theme-".concat(Date.now());
36514
- var finalTheme = _objectSpread$5(_objectSpread$5({}, wizardTheme), {}, {
36515
- id: key,
36516
- name: wizardName.trim()
36517
- });
36518
- saveAndSelectTheme(key, finalTheme);
36379
+ function handleStepChange(nextStep) {
36380
+ if (step === 0 && nextStep > 0 && authStatus !== "authenticated") return;
36381
+ if (step === 1 && nextStep > 1 && !authorName.trim()) return;
36382
+ if (step === 2 && nextStep > 2 && selectedTags.length === 0) return;
36383
+ setStep(nextStep);
36519
36384
  }
36520
- function saveAndSelectTheme(key, rawTheme) {
36521
- dashApi.saveTheme(appId, key, rawTheme, function (e, message) {
36522
- if (message && message.themes) {
36523
- changeThemesForApplication(message.themes);
36524
- }
36525
- setSelectedThemeKey(key);
36526
- setGenerateMode(GENERATE_MODES.NONE);
36527
- }, function (e, err) {
36385
+ function toggleTag(tag) {
36386
+ setSelectedTags(function (prev) {
36387
+ return prev.includes(tag) ? prev.filter(function (t) {
36388
+ return t !== tag;
36389
+ }) : [].concat(_toConsumableArray(prev), [tag]);
36528
36390
  });
36529
36391
  }
36530
- function handleDeleteTheme(key) {
36392
+ function handlePublish() {
36393
+ return _handlePublish.apply(this, arguments);
36394
+ }
36395
+ function _handlePublish() {
36396
+ _handlePublish = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
36397
+ var options, res, _t2;
36398
+ return _regeneratorRuntime.wrap(function (_context2) {
36399
+ while (1) switch (_context2.prev = _context2.next) {
36400
+ case 0:
36401
+ if (!(!appId || !themeKey)) {
36402
+ _context2.next = 1;
36403
+ break;
36404
+ }
36405
+ return _context2.abrupt("return");
36406
+ case 1:
36407
+ setIsPublishing(true);
36408
+ setResult(null);
36409
+ _context2.prev = 2;
36410
+ options = {
36411
+ authorName: authorName.trim(),
36412
+ description: description.trim() || undefined,
36413
+ tags: selectedTags
36414
+ };
36415
+ _context2.next = 3;
36416
+ return window.mainApi.themes.publishTheme(appId, themeKey, options);
36417
+ case 3:
36418
+ res = _context2.sent;
36419
+ setResult(res);
36420
+ _context2.next = 5;
36421
+ break;
36422
+ case 4:
36423
+ _context2.prev = 4;
36424
+ _t2 = _context2["catch"](2);
36425
+ setResult({
36426
+ success: false,
36427
+ error: _t2.message || "Failed to prepare theme for publish."
36428
+ });
36429
+ case 5:
36430
+ _context2.prev = 5;
36431
+ setIsPublishing(false);
36432
+ return _context2.finish(5);
36433
+ case 6:
36434
+ case "end":
36435
+ return _context2.stop();
36436
+ }
36437
+ }, _callee2, null, [[2, 4, 5, 6]]);
36438
+ }));
36439
+ return _handlePublish.apply(this, arguments);
36440
+ }
36441
+ function handleSignIn() {
36442
+ return _handleSignIn.apply(this, arguments);
36443
+ }
36444
+ function _handleSignIn() {
36445
+ _handleSignIn = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
36446
+ var flow, interval, poll;
36447
+ return _regeneratorRuntime.wrap(function (_context4) {
36448
+ while (1) switch (_context4.prev = _context4.next) {
36449
+ case 0:
36450
+ setAuthError(null);
36451
+ _context4.prev = 1;
36452
+ _context4.next = 2;
36453
+ return window.mainApi.registryAuth.initiateLogin();
36454
+ case 2:
36455
+ flow = _context4.sent;
36456
+ setAuthFlow(flow);
36457
+ if (flow.verificationUrlComplete) {
36458
+ window.mainApi.shell.openExternal(flow.verificationUrlComplete);
36459
+ }
36460
+ setIsPolling(true);
36461
+ interval = (flow.interval || 5) * 1000;
36462
+ poll = setInterval(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
36463
+ var pollResult, userProfile;
36464
+ return _regeneratorRuntime.wrap(function (_context3) {
36465
+ while (1) switch (_context3.prev = _context3.next) {
36466
+ case 0:
36467
+ _context3.prev = 0;
36468
+ _context3.next = 1;
36469
+ return window.mainApi.registryAuth.pollToken(flow.deviceCode);
36470
+ case 1:
36471
+ pollResult = _context3.sent;
36472
+ if (!(pollResult.status === "authorized")) {
36473
+ _context3.next = 3;
36474
+ break;
36475
+ }
36476
+ clearInterval(poll);
36477
+ setIsPolling(false);
36478
+ setAuthFlow(null);
36479
+ _context3.next = 2;
36480
+ return window.mainApi.registryAuth.getProfile();
36481
+ case 2:
36482
+ userProfile = _context3.sent;
36483
+ setProfile(userProfile);
36484
+ setAuthStatus("authenticated");
36485
+ if (userProfile !== null && userProfile !== void 0 && userProfile.displayName && !authorName) {
36486
+ setAuthorName(userProfile.displayName);
36487
+ }
36488
+ _context3.next = 4;
36489
+ break;
36490
+ case 3:
36491
+ if (pollResult.status === "expired") {
36492
+ clearInterval(poll);
36493
+ setIsPolling(false);
36494
+ setAuthFlow(null);
36495
+ }
36496
+ case 4:
36497
+ _context3.next = 6;
36498
+ break;
36499
+ case 5:
36500
+ _context3.prev = 5;
36501
+ _context3["catch"](0);
36502
+ clearInterval(poll);
36503
+ setIsPolling(false);
36504
+ case 6:
36505
+ case "end":
36506
+ return _context3.stop();
36507
+ }
36508
+ }, _callee3, null, [[0, 5]]);
36509
+ })), interval);
36510
+ _context4.next = 4;
36511
+ break;
36512
+ case 3:
36513
+ _context4.prev = 3;
36514
+ _context4["catch"](1);
36515
+ setAuthError("Could not reach the registry. Check your connection and try again.");
36516
+ case 4:
36517
+ case "end":
36518
+ return _context4.stop();
36519
+ }
36520
+ }, _callee4, null, [[1, 3]]);
36521
+ }));
36522
+ return _handleSignIn.apply(this, arguments);
36523
+ }
36524
+ function handleSignOut() {
36525
+ return _handleSignOut.apply(this, arguments);
36526
+ }
36527
+ function _handleSignOut() {
36528
+ _handleSignOut = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
36529
+ return _regeneratorRuntime.wrap(function (_context5) {
36530
+ while (1) switch (_context5.prev = _context5.next) {
36531
+ case 0:
36532
+ _context5.prev = 0;
36533
+ _context5.next = 1;
36534
+ return window.mainApi.registryAuth.logout();
36535
+ case 1:
36536
+ setAuthStatus("unauthenticated");
36537
+ setProfile(null);
36538
+ _context5.next = 3;
36539
+ break;
36540
+ case 2:
36541
+ _context5.prev = 2;
36542
+ _context5["catch"](0);
36543
+ case 3:
36544
+ case "end":
36545
+ return _context5.stop();
36546
+ }
36547
+ }, _callee5, null, [[0, 2]]);
36548
+ }));
36549
+ return _handleSignOut.apply(this, arguments);
36550
+ }
36551
+ var isLastStep = step === 3;
36552
+ var canAdvance = step === 0 ? authStatus === "authenticated" : step === 1 ? !!authorName.trim() : step === 2 ? selectedTags.length > 0 : true;
36553
+ var previewColors = (preview === null || preview === void 0 ? void 0 : preview.colors) || {};
36554
+ var colorEntries = [{
36555
+ label: "Primary",
36556
+ value: previewColors.primary
36557
+ }, {
36558
+ label: "Secondary",
36559
+ value: previewColors.secondary
36560
+ }, {
36561
+ label: "Tertiary",
36562
+ value: previewColors.tertiary
36563
+ }, {
36564
+ label: "Neutral",
36565
+ value: previewColors.neutral
36566
+ }].filter(function (c) {
36567
+ return c.value;
36568
+ });
36569
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Modal, {
36570
+ isOpen: isOpen,
36571
+ setIsOpen: handleClose,
36572
+ width: "w-full max-w-2xl",
36573
+ height: "h-[70vh]",
36574
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36575
+ className: "flex flex-col h-full rounded-lg overflow-clip border ".concat(panelStyles.backgroundColor || "", " ").concat(panelStyles.borderColor || "", " ").concat(panelStyles.textColor || ""),
36576
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36577
+ className: "flex-shrink-0 flex flex-row items-center justify-between p-4 border-b border-white/10",
36578
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
36579
+ className: "text-lg font-semibold",
36580
+ children: ["Publish \"", themeName || themeKey || "Theme", "\""]
36581
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
36582
+ type: "button",
36583
+ onClick: handleClose,
36584
+ className: "opacity-50 hover:opacity-100 transition-opacity cursor-pointer",
36585
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36586
+ icon: "xmark",
36587
+ className: "h-5 w-5"
36588
+ })
36589
+ })]
36590
+ }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Stepper, {
36591
+ activeStep: step,
36592
+ onStepChange: handleStepChange,
36593
+ showNavigation: false,
36594
+ className: "flex-1 min-h-0 flex flex-col px-6 pt-2",
36595
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
36596
+ label: "Account",
36597
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36598
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
36599
+ children: [authStatus === "loading" && /*#__PURE__*/jsxRuntime.jsx("div", {
36600
+ className: "flex items-center justify-center py-12",
36601
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36602
+ className: "flex items-center gap-3 text-sm opacity-60",
36603
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36604
+ icon: "spinner",
36605
+ className: "h-4 w-4 animate-spin"
36606
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36607
+ children: "Checking account status..."
36608
+ })]
36609
+ })
36610
+ }), authStatus === "authenticated" && profile && /*#__PURE__*/jsxRuntime.jsxs("div", {
36611
+ className: "space-y-4",
36612
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
36613
+ className: "text-sm opacity-70",
36614
+ children: "You're signed in and ready to publish."
36615
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36616
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 flex items-center gap-4",
36617
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
36618
+ className: "flex items-center justify-center h-10 w-10 rounded-full bg-green-500/20 border border-green-500/30",
36619
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36620
+ icon: "circle-check",
36621
+ className: "h-5 w-5 text-green-400"
36622
+ })
36623
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36624
+ className: "flex-1 min-w-0",
36625
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
36626
+ className: "text-sm font-medium truncate",
36627
+ children: profile.displayName || profile.username
36628
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36629
+ className: "text-xs opacity-50 truncate",
36630
+ children: ["@", profile.username]
36631
+ })]
36632
+ })]
36633
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
36634
+ type: "button",
36635
+ onClick: handleSignOut,
36636
+ className: "text-xs opacity-40 hover:opacity-70 transition-opacity cursor-pointer",
36637
+ children: "Sign out"
36638
+ })]
36639
+ }), authStatus === "unauthenticated" && /*#__PURE__*/jsxRuntime.jsxs("div", {
36640
+ className: "space-y-4",
36641
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
36642
+ className: "text-sm opacity-70",
36643
+ children: "Sign in to the Dash Registry to publish your theme."
36644
+ }), !authFlow && !isPolling && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
36645
+ children: [/*#__PURE__*/jsxRuntime.jsx("button", {
36646
+ type: "button",
36647
+ onClick: handleSignIn,
36648
+ className: "px-4 py-2 rounded-lg text-sm bg-blue-500/20 border border-blue-500/30 text-blue-300 hover:bg-blue-500/30 transition-colors cursor-pointer",
36649
+ children: "Sign in to Registry"
36650
+ }), authError && /*#__PURE__*/jsxRuntime.jsx("div", {
36651
+ className: "bg-red-500/10 border border-red-500/20 rounded-lg p-3",
36652
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36653
+ className: "flex items-start gap-2",
36654
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36655
+ icon: "circle-xmark",
36656
+ className: "h-3.5 w-3.5 text-red-400 mt-0.5 flex-shrink-0"
36657
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36658
+ className: "text-xs text-red-300/90",
36659
+ children: authError
36660
+ })]
36661
+ })
36662
+ })]
36663
+ }), authFlow && isPolling && /*#__PURE__*/jsxRuntime.jsxs("div", {
36664
+ className: "bg-blue-500/10 border border-blue-500/20 rounded-lg p-4 space-y-3",
36665
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
36666
+ className: "text-xs text-blue-300/90",
36667
+ children: "Enter this code in your browser:"
36668
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36669
+ className: "text-center",
36670
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
36671
+ className: "text-2xl font-mono font-bold tracking-widest text-white",
36672
+ children: authFlow.userCode
36673
+ })
36674
+ }), /*#__PURE__*/jsxRuntime.jsx("p", {
36675
+ className: "text-xs text-blue-300/70 text-center",
36676
+ children: "Waiting for authorization..."
36677
+ })]
36678
+ })]
36679
+ })]
36680
+ })
36681
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
36682
+ label: "Details",
36683
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36684
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
36685
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
36686
+ className: "text-sm opacity-70",
36687
+ children: "Provide details about your theme for the registry listing."
36688
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36689
+ children: [/*#__PURE__*/jsxRuntime.jsx("label", {
36690
+ className: "block text-sm font-medium opacity-70 mb-1",
36691
+ children: "Author Name"
36692
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36693
+ className: "px-3 py-2 rounded-lg bg-white/5 border border-white/10 text-sm opacity-80",
36694
+ children: authorName || "\u2014"
36695
+ })]
36696
+ }), colorEntries.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
36697
+ children: [/*#__PURE__*/jsxRuntime.jsx("label", {
36698
+ className: "block text-sm font-medium opacity-70 mb-2",
36699
+ children: "Theme Colors"
36700
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36701
+ className: "flex flex-row gap-3",
36702
+ children: colorEntries.map(function (_ref2) {
36703
+ var label = _ref2.label,
36704
+ value = _ref2.value;
36705
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
36706
+ className: "flex flex-col items-center gap-1",
36707
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
36708
+ className: "h-8 w-8 rounded-full border-2 border-white/20",
36709
+ style: {
36710
+ backgroundColor: value
36711
+ }
36712
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36713
+ className: "text-[10px] opacity-50",
36714
+ children: label
36715
+ })]
36716
+ }, label);
36717
+ })
36718
+ })]
36719
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.TextArea, {
36720
+ label: "Description",
36721
+ value: description,
36722
+ onChange: setDescription,
36723
+ placeholder: "A brief description of this theme...",
36724
+ rows: 3
36725
+ })]
36726
+ })
36727
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
36728
+ label: "Tags",
36729
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36730
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-5",
36731
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
36732
+ className: "text-sm opacity-70",
36733
+ children: "Select at least one tag to categorize your theme."
36734
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36735
+ className: "grid grid-cols-3 gap-2",
36736
+ children: THEME_TAGS.map(function (tag) {
36737
+ var isSelected = selectedTags.includes(tag);
36738
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
36739
+ type: "button",
36740
+ onClick: function onClick() {
36741
+ return toggleTag(tag);
36742
+ },
36743
+ className: "px-3 py-1.5 rounded-full text-sm border transition-colors cursor-pointer ".concat(isSelected ? "bg-white/15 border-white/30 text-white" : "bg-transparent border-white/10 text-white/60 hover:border-white/20 hover:text-white/80"),
36744
+ children: tag
36745
+ }, tag);
36746
+ })
36747
+ })]
36748
+ })
36749
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Stepper.Step, {
36750
+ label: "Publish",
36751
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
36752
+ className: "flex-1 min-h-0 overflow-y-auto pb-4 space-y-4",
36753
+ children: !result ? /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
36754
+ children: [/*#__PURE__*/jsxRuntime.jsx("p", {
36755
+ className: "text-sm opacity-70",
36756
+ children: "Review your theme details before publishing."
36757
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36758
+ className: "bg-white/5 border border-white/10 rounded-lg p-4 space-y-2 text-sm",
36759
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36760
+ className: "flex gap-2",
36761
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36762
+ className: "opacity-50 w-20 flex-shrink-0",
36763
+ children: "Author"
36764
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36765
+ children: authorName
36766
+ })]
36767
+ }), description.trim() && /*#__PURE__*/jsxRuntime.jsxs("div", {
36768
+ className: "flex gap-2",
36769
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36770
+ className: "opacity-50 w-20 flex-shrink-0",
36771
+ children: "Description"
36772
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36773
+ children: description
36774
+ })]
36775
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36776
+ className: "flex gap-2",
36777
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36778
+ className: "opacity-50 w-20 flex-shrink-0",
36779
+ children: "Tags"
36780
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36781
+ children: selectedTags.length > 0 ? selectedTags.join(", ") : "None"
36782
+ })]
36783
+ }), colorEntries.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
36784
+ className: "flex gap-2 items-center",
36785
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36786
+ className: "opacity-50 w-20 flex-shrink-0",
36787
+ children: "Colors"
36788
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36789
+ className: "flex gap-1.5",
36790
+ children: colorEntries.map(function (_ref3) {
36791
+ var label = _ref3.label,
36792
+ value = _ref3.value;
36793
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
36794
+ className: "h-5 w-5 rounded-full border border-white/20",
36795
+ style: {
36796
+ backgroundColor: value
36797
+ },
36798
+ title: "".concat(label, ": ").concat(value)
36799
+ }, label);
36800
+ })
36801
+ })]
36802
+ })]
36803
+ })]
36804
+ }) : result.success ? /*#__PURE__*/jsxRuntime.jsxs("div", {
36805
+ className: "space-y-3",
36806
+ children: [(_result$registryResul = result.registryResult) !== null && _result$registryResul !== void 0 && _result$registryResul.success ? /*#__PURE__*/jsxRuntime.jsxs("div", {
36807
+ className: "space-y-3",
36808
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36809
+ className: "flex items-center gap-2",
36810
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36811
+ icon: "circle-check",
36812
+ className: "h-4 w-4 text-green-400"
36813
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36814
+ className: "text-sm",
36815
+ children: "Published to Dash Registry"
36816
+ })]
36817
+ }), result.registryResult.registryUrl && /*#__PURE__*/jsxRuntime.jsxs("div", {
36818
+ className: "bg-white/5 border border-white/10 rounded-lg p-3",
36819
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
36820
+ className: "text-xs opacity-50 mb-1",
36821
+ children: "Shareable Link"
36822
+ }), /*#__PURE__*/jsxRuntime.jsx("button", {
36823
+ type: "button",
36824
+ onClick: function onClick() {
36825
+ return window.mainApi.shell.openExternal(result.registryResult.registryUrl);
36826
+ },
36827
+ className: "text-sm text-blue-400 hover:underline cursor-pointer break-all text-left",
36828
+ children: result.registryResult.registryUrl
36829
+ })]
36830
+ })]
36831
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
36832
+ className: "space-y-3",
36833
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36834
+ className: "flex items-center gap-2",
36835
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36836
+ icon: "circle-check",
36837
+ className: "h-4 w-4 text-green-400"
36838
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36839
+ className: "text-sm",
36840
+ children: "Theme prepared for publishing."
36841
+ })]
36842
+ }), ((_result$registryResul2 = result.registryResult) === null || _result$registryResul2 === void 0 ? void 0 : _result$registryResul2.error) && /*#__PURE__*/jsxRuntime.jsx("div", {
36843
+ className: "bg-amber-500/10 border border-amber-500/20 rounded-lg p-3",
36844
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
36845
+ className: "flex items-start gap-2",
36846
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36847
+ icon: "triangle-exclamation",
36848
+ className: "h-3.5 w-3.5 text-amber-400 mt-0.5 flex-shrink-0"
36849
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
36850
+ className: "text-xs text-amber-300/90",
36851
+ children: ["Registry upload failed:", " ", result.registryResult.error, ". Your theme was saved locally."]
36852
+ })]
36853
+ })
36854
+ })]
36855
+ }), result.filePath && /*#__PURE__*/jsxRuntime.jsxs("div", {
36856
+ className: "text-xs opacity-50 break-all",
36857
+ children: ["Saved to: ", result.filePath]
36858
+ })]
36859
+ }) : /*#__PURE__*/jsxRuntime.jsxs("div", {
36860
+ className: "flex items-center gap-2",
36861
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36862
+ icon: "circle-xmark",
36863
+ className: "h-4 w-4 text-red-400"
36864
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
36865
+ className: "text-sm text-red-400",
36866
+ children: result.error || "Publish preparation failed."
36867
+ })]
36868
+ })
36869
+ })
36870
+ })]
36871
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
36872
+ className: "flex-shrink-0 flex flex-row items-center px-6 py-4 border-t border-white/10",
36873
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
36874
+ className: "flex flex-row gap-2",
36875
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button3, {
36876
+ title: step === 0 ? "Cancel" : "Back",
36877
+ onClick: step === 0 ? handleClose : function () {
36878
+ return setStep(step - 1);
36879
+ },
36880
+ disabled: isPublishing
36881
+ })
36882
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36883
+ className: "flex-1 text-center",
36884
+ children: /*#__PURE__*/jsxRuntime.jsxs("span", {
36885
+ className: "text-xs opacity-40",
36886
+ children: ["Step ", step + 1, " of 4"]
36887
+ })
36888
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36889
+ className: "flex flex-row gap-2",
36890
+ children: result !== null && result !== void 0 && result.success ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
36891
+ title: "Done",
36892
+ onClick: handleClose
36893
+ }) : isLastStep ? /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
36894
+ title: isPublishing ? "Publishing..." : "Publish",
36895
+ onClick: handlePublish,
36896
+ disabled: isPublishing
36897
+ }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.Button2, {
36898
+ title: "Next",
36899
+ onClick: function onClick() {
36900
+ return handleStepChange(step + 1);
36901
+ },
36902
+ disabled: !canAdvance
36903
+ })
36904
+ })]
36905
+ })]
36906
+ })
36907
+ });
36908
+ };
36909
+
36910
+ var TOKEN_TYPES = ["bg", "text", "border"];
36911
+
36912
+ // --- Color Swatch Grid ---
36913
+
36914
+ var SwatchCell = function SwatchCell(_ref) {
36915
+ var tokenKey = _ref.tokenKey,
36916
+ resolvedClass = _ref.resolvedClass,
36917
+ type = _ref.type;
36918
+ var tooltip = "".concat(tokenKey, " \u2192 ").concat(resolvedClass || "(none)");
36919
+ if (type === "bg") {
36920
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
36921
+ className: "h-8 flex-1 rounded ".concat(resolvedClass || ""),
36922
+ title: tooltip
36923
+ });
36924
+ }
36925
+ if (type === "text") {
36926
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
36927
+ className: "h-8 flex-1 rounded flex items-center justify-center bg-black/10",
36928
+ title: tooltip,
36929
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
36930
+ className: "text-xs font-bold ".concat(resolvedClass || ""),
36931
+ children: "Aa"
36932
+ })
36933
+ });
36934
+ }
36935
+
36936
+ // border
36937
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
36938
+ className: "h-8 flex-1 rounded border-2 ".concat(resolvedClass || ""),
36939
+ title: tooltip
36940
+ });
36941
+ };
36942
+ var ColorSwatchGrid = function ColorSwatchGrid(_ref2) {
36943
+ var displayTheme = _ref2.displayTheme;
36944
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
36945
+ className: "flex flex-col space-y-5",
36946
+ children: DashReact.colorTypes.map(function (family) {
36947
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
36948
+ className: "flex flex-col space-y-2",
36949
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36950
+ className: "text-xs font-semibold opacity-50 capitalize",
36951
+ children: family
36952
+ }), TOKEN_TYPES.map(function (type) {
36953
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
36954
+ className: "flex flex-row items-center gap-2",
36955
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
36956
+ className: "text-[10px] opacity-40 w-10 text-right shrink-0",
36957
+ children: type
36958
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
36959
+ className: "flex flex-row gap-1.5 flex-1",
36960
+ children: DashReact.themeVariants.map(function (shade) {
36961
+ var tokenKey = "".concat(type, "-").concat(family, "-").concat(shade);
36962
+ var resolvedClass = displayTheme[tokenKey] || "";
36963
+ return /*#__PURE__*/jsxRuntime.jsx(SwatchCell, {
36964
+ tokenKey: tokenKey,
36965
+ resolvedClass: resolvedClass,
36966
+ type: type
36967
+ }, shade);
36968
+ })
36969
+ })]
36970
+ }, type);
36971
+ })]
36972
+ }, family);
36973
+ })
36974
+ });
36975
+ };
36976
+
36977
+ // --- Component Style Accordion ---
36978
+
36979
+ var COLOR_KEYS = ["backgroundColor", "textColor", "borderColor", "hoverBackgroundColor", "hoverTextColor", "hoverBorderColor", "activeBackgroundColor", "activeTextColor", "focusRingColor", "focusBorderColor"];
36980
+ var NON_COLOR_KEYS = ["shadow", "borderRadius", "spacing", "textSize", "iconSize", "fontWeight", "transition", "cursor", "disabledOpacity", "letterSpacing", "lineHeight"];
36981
+ var COMPONENT_GROUPS = [{
36982
+ label: "Buttons",
36983
+ keys: ["BUTTON", "BUTTON_2", "BUTTON_3", "BUTTON_ICON", "BUTTON_ICON_2", "BUTTON_ICON_3"]
36984
+ }, {
36985
+ label: "Panels",
36986
+ keys: ["PANEL", "PANEL_2", "PANEL_3", "PANEL_HEADER", "PANEL_HEADER_2", "PANEL_HEADER_3", "PANEL_FOOTER", "PANEL_FOOTER_2", "PANEL_FOOTER_3", "DASH_PANEL", "DASH_PANEL_2", "DASH_PANEL_3", "DASH_PANEL_HEADER", "DASH_PANEL_HEADER_2", "DASH_PANEL_HEADER_3", "DASH_PANEL_FOOTER", "DASH_PANEL_FOOTER_2", "DASH_PANEL_FOOTER_3"]
36987
+ }, {
36988
+ label: "Cards",
36989
+ keys: ["CARD", "CARD_2", "CARD_3", "STAT_CARD", "STAT_CARD_LABEL", "STAT_CARD_VALUE", "STAT_CARD_CHANGE"]
36990
+ }, {
36991
+ label: "Typography",
36992
+ keys: ["HEADING", "HEADING_2", "HEADING_3", "SUBHEADING", "SUBHEADING_2", "SUBHEADING_3", "PARAGRAPH", "PARAGRAPH_2", "PARAGRAPH_3"]
36993
+ }, {
36994
+ label: "Navigation",
36995
+ keys: ["MENU_ITEM", "MENU_ITEM_2", "MENU_ITEM_3", "TABS", "TABS_2", "TABS_3", "TABS_LIST", "TABS_LIST_2", "TABS_LIST_3", "TABS_TRIGGER", "TABS_TRIGGER_2", "TABS_TRIGGER_3", "TABS_CONTENT", "TABS_CONTENT_2", "TABS_CONTENT_3", "SIDEBAR", "SIDEBAR_ITEM", "NAVBAR", "TABBED_NAVBAR", "BREADCRUMBS", "BREADCRUMBS_2", "BREADCRUMBS_3"]
36996
+ }, {
36997
+ label: "Forms",
36998
+ keys: ["INPUT_TEXT", "SELECT_MENU", "TEXTAREA", "CHECKBOX", "RADIO", "SWITCH", "SLIDER", "SEARCH_INPUT", "TOGGLE", "TOGGLE_2", "TOGGLE_3", "FORM_LABEL"]
36999
+ }, {
37000
+ label: "Feedback",
37001
+ keys: ["ALERT", "ALERT_2", "ALERT_3", "ALERT_BANNER", "TOAST", "TOAST_2", "TOAST_3", "PROGRESS_BAR", "PROGRESS_BAR_2", "PROGRESS_BAR_3", "TAG", "TAG_2", "TAG_3", "TOOLTIP", "EMPTY_STATE"]
37002
+ }, {
37003
+ label: "Tables",
37004
+ keys: ["TABLE", "TABLE_2", "TABLE_3", "DATA_LIST", "DATA_LIST_ITEM"]
37005
+ }, {
37006
+ label: "Advanced",
37007
+ keys: ["ACCORDION", "ACCORDION_2", "ACCORDION_3", "ACCORDION_ITEM", "ACCORDION_ITEM_2", "ACCORDION_ITEM_3", "ACCORDION_TRIGGER", "ACCORDION_TRIGGER_2", "ACCORDION_TRIGGER_3", "ACCORDION_CONTENT", "ACCORDION_CONTENT_2", "ACCORDION_CONTENT_3", "COMMAND_PALETTE", "COMMAND_PALETTE_INPUT", "COMMAND_PALETTE_ITEM", "DRAWER", "DRAWER_HEADER", "DRAWER_FOOTER", "STEPPER", "STEPPER_STEP", "STEPPER_CONNECTOR", "SKELETON", "CODE_EDITOR"]
37008
+ }, {
37009
+ label: "Layout",
37010
+ keys: ["WIDGET_CHROME", "WIDGET", "WORKSPACE", "LAYOUT_CONTAINER", "DASHBOARD_FOOTER", "DASHBOARD_FOOTER_2", "DASHBOARD_FOOTER_3", "SETTINGS_MODAL_SIDEBAR", "SETTINGS_MODAL_FOOTER"]
37011
+ }];
37012
+ var ComponentStyleRow = function ComponentStyleRow(_ref3) {
37013
+ var objectKey = _ref3.objectKey,
37014
+ styles = _ref3.styles;
37015
+ if (!styles) return null;
37016
+ var colorEntries = COLOR_KEYS.filter(function (k) {
37017
+ return styles[k];
37018
+ }).map(function (k) {
37019
+ return {
37020
+ key: k,
37021
+ value: styles[k]
37022
+ };
37023
+ });
37024
+ var nonColorEntries = NON_COLOR_KEYS.filter(function (k) {
37025
+ return styles[k];
37026
+ }).map(function (k) {
37027
+ return {
37028
+ key: k,
37029
+ value: styles[k]
37030
+ };
37031
+ });
37032
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
37033
+ className: "flex flex-row items-center gap-3 py-1.5",
37034
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
37035
+ className: "text-[11px] font-mono opacity-70 w-40 shrink-0 truncate",
37036
+ children: objectKey
37037
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37038
+ className: "flex flex-row items-center gap-1",
37039
+ children: colorEntries.map(function (_ref4) {
37040
+ var key = _ref4.key,
37041
+ value = _ref4.value;
37042
+ if (key.toLowerCase().includes("text")) {
37043
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
37044
+ className: "h-5 w-5 rounded-sm flex items-center justify-center bg-black/10",
37045
+ title: "".concat(key, ": ").concat(value),
37046
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
37047
+ className: "text-[8px] font-bold ".concat(value),
37048
+ children: "Aa"
37049
+ })
37050
+ }, key);
37051
+ }
37052
+ if (key.toLowerCase().includes("border")) {
37053
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
37054
+ className: "h-5 w-5 rounded-sm border-2 ".concat(value),
37055
+ title: "".concat(key, ": ").concat(value)
37056
+ }, key);
37057
+ }
37058
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
37059
+ className: "h-5 w-5 rounded-sm ".concat(value),
37060
+ title: "".concat(key, ": ").concat(value)
37061
+ }, key);
37062
+ })
37063
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37064
+ className: "flex flex-row items-center gap-2 flex-1 overflow-hidden",
37065
+ children: nonColorEntries.map(function (_ref5) {
37066
+ var key = _ref5.key,
37067
+ value = _ref5.value;
37068
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
37069
+ className: "text-[10px] opacity-40 whitespace-nowrap",
37070
+ title: key,
37071
+ children: value
37072
+ }, key);
37073
+ })
37074
+ })]
37075
+ });
37076
+ };
37077
+
37078
+ // --- Main Component ---
37079
+
37080
+ var ThemeDetail = function ThemeDetail(_ref6) {
37081
+ var themeKey = _ref6.themeKey,
37082
+ themes = _ref6.themes,
37083
+ currentThemeKey = _ref6.currentThemeKey,
37084
+ themeVariant = _ref6.themeVariant,
37085
+ onActivate = _ref6.onActivate,
37086
+ onOpenThemeEditor = _ref6.onOpenThemeEditor,
37087
+ _ref6$onDelete = _ref6.onDelete,
37088
+ onDelete = _ref6$onDelete === void 0 ? null : _ref6$onDelete,
37089
+ _ref6$appId = _ref6.appId,
37090
+ appId = _ref6$appId === void 0 ? null : _ref6$appId;
37091
+ var theme = themeKey && themes ? themes[themeKey] : null;
37092
+ var _useState = React.useState(false),
37093
+ _useState2 = _slicedToArray(_useState, 2),
37094
+ publishOpen = _useState2[0],
37095
+ setPublishOpen = _useState2[1];
37096
+ var canPublish = theme && !theme._registryMeta;
37097
+ var displayTheme = React.useMemo(function () {
37098
+ return theme ? theme[themeVariant] || {} : {};
37099
+ }, [theme, themeVariant]);
37100
+ var isActive = themeKey === currentThemeKey;
37101
+
37102
+ // Memoize all component styles
37103
+ var allStyles = React.useMemo(function () {
37104
+ var result = {};
37105
+ Object.values(DashReact.themeObjects).forEach(function (key) {
37106
+ result[key] = DashReact.getStylesForItem(key, displayTheme, {});
37107
+ });
37108
+ return result;
37109
+ }, [displayTheme]);
37110
+ if (!theme) return null;
37111
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
37112
+ className: "flex flex-col flex-1 min-h-0",
37113
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
37114
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6",
37115
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
37116
+ className: "flex flex-row items-center gap-3",
37117
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading, {
37118
+ title: theme.name || themeKey,
37119
+ padding: false
37120
+ }), isActive && /*#__PURE__*/jsxRuntime.jsx("span", {
37121
+ className: "text-xs opacity-40",
37122
+ children: "active"
37123
+ })]
37124
+ }), /*#__PURE__*/jsxRuntime.jsx(ColorSwatchGrid, {
37125
+ displayTheme: displayTheme
37126
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
37127
+ className: "flex flex-col space-y-2",
37128
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
37129
+ className: "text-xs font-semibold opacity-50",
37130
+ children: "Component Styles"
37131
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Accordion2, {
37132
+ type: "multiple",
37133
+ children: COMPONENT_GROUPS.map(function (group) {
37134
+ // Only show groups that have valid theme objects
37135
+ var validKeys = group.keys.filter(function (k) {
37136
+ return DashReact.themeObjects[k];
37137
+ });
37138
+ if (validKeys.length === 0) return null;
37139
+ return /*#__PURE__*/jsxRuntime.jsxs(DashReact.Accordion2.Item, {
37140
+ value: group.label,
37141
+ children: [/*#__PURE__*/jsxRuntime.jsxs(DashReact.Accordion2.Trigger, {
37142
+ value: group.label,
37143
+ children: [group.label, " (", validKeys.length, ")"]
37144
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Accordion2.Content, {
37145
+ value: group.label,
37146
+ children: /*#__PURE__*/jsxRuntime.jsx("div", {
37147
+ className: "flex flex-col",
37148
+ children: validKeys.map(function (k) {
37149
+ var objectValue = DashReact.themeObjects[k];
37150
+ return /*#__PURE__*/jsxRuntime.jsx(ComponentStyleRow, {
37151
+ objectKey: objectValue,
37152
+ styles: allStyles[objectValue]
37153
+ }, k);
37154
+ })
37155
+ })
37156
+ })]
37157
+ }, group.label);
37158
+ })
37159
+ })]
37160
+ })]
37161
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
37162
+ className: "flex-shrink-0 flex flex-row justify-between px-6 py-4 border-t border-white/10",
37163
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
37164
+ className: "flex flex-row gap-2",
37165
+ children: [!isActive && onDelete && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
37166
+ title: "Delete",
37167
+ onClick: function onClick() {
37168
+ return onDelete(themeKey);
37169
+ },
37170
+ size: "sm"
37171
+ }), canPublish && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
37172
+ title: "Publish",
37173
+ onClick: function onClick() {
37174
+ return setPublishOpen(true);
37175
+ },
37176
+ size: "sm"
37177
+ })]
37178
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
37179
+ className: "flex flex-row gap-2",
37180
+ children: [!isActive && /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
37181
+ title: "Activate",
37182
+ onClick: function onClick() {
37183
+ return onActivate(themeKey);
37184
+ },
37185
+ size: "sm"
37186
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
37187
+ title: "Edit",
37188
+ onClick: onOpenThemeEditor,
37189
+ size: "sm"
37190
+ })]
37191
+ })]
37192
+ }), canPublish && /*#__PURE__*/jsxRuntime.jsx(PublishThemeModal, {
37193
+ isOpen: publishOpen,
37194
+ setIsOpen: setPublishOpen,
37195
+ appId: appId,
37196
+ themeKey: themeKey,
37197
+ themeName: theme.name || themeKey
37198
+ })]
37199
+ });
37200
+ };
37201
+
37202
+ var RegistryThemeDetail = function RegistryThemeDetail(_ref) {
37203
+ var themePackage = _ref.themePackage,
37204
+ appId = _ref.appId,
37205
+ onInstallComplete = _ref.onInstallComplete;
37206
+ var _useContext = React.useContext(DashReact.ThemeContext),
37207
+ currentTheme = _useContext.currentTheme,
37208
+ changeThemesForApplication = _useContext.changeThemesForApplication;
37209
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
37210
+ grow: false
37211
+ });
37212
+ var _useState = React.useState(false),
37213
+ _useState2 = _slicedToArray(_useState, 2),
37214
+ isInstalling = _useState2[0],
37215
+ setIsInstalling = _useState2[1];
37216
+ var _useState3 = React.useState(null),
37217
+ _useState4 = _slicedToArray(_useState3, 2),
37218
+ installResult = _useState4[0],
37219
+ setInstallResult = _useState4[1];
37220
+ var pkg = themePackage;
37221
+ if (!pkg) return null;
37222
+ var colors = pkg.colors || {};
37223
+ function handleInstall() {
37224
+ return _handleInstall.apply(this, arguments);
37225
+ }
37226
+ function _handleInstall() {
37227
+ _handleInstall = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
37228
+ var result, _t;
37229
+ return _regeneratorRuntime.wrap(function (_context) {
37230
+ while (1) switch (_context.prev = _context.next) {
37231
+ case 0:
37232
+ if (!(!appId || !pkg.name)) {
37233
+ _context.next = 1;
37234
+ break;
37235
+ }
37236
+ return _context.abrupt("return");
37237
+ case 1:
37238
+ setIsInstalling(true);
37239
+ setInstallResult(null);
37240
+ _context.prev = 2;
37241
+ _context.next = 3;
37242
+ return window.mainApi.themes.installThemeFromRegistry(appId, pkg.name);
37243
+ case 3:
37244
+ result = _context.sent;
37245
+ setInstallResult({
37246
+ status: result !== null && result !== void 0 && result.success ? "success" : "error",
37247
+ 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."
37248
+ });
37249
+ if (result !== null && result !== void 0 && result.success) {
37250
+ // Refresh ThemeContext with updated themes
37251
+ if (result.themes) {
37252
+ changeThemesForApplication(result.themes);
37253
+ }
37254
+ if (onInstallComplete) {
37255
+ onInstallComplete(result);
37256
+ }
37257
+ }
37258
+ _context.next = 5;
37259
+ break;
37260
+ case 4:
37261
+ _context.prev = 4;
37262
+ _t = _context["catch"](2);
37263
+ setInstallResult({
37264
+ status: "error",
37265
+ message: _t.message || "Failed to install theme."
37266
+ });
37267
+ case 5:
37268
+ _context.prev = 5;
37269
+ setIsInstalling(false);
37270
+ return _context.finish(5);
37271
+ case 6:
37272
+ case "end":
37273
+ return _context.stop();
37274
+ }
37275
+ }, _callee, null, [[2, 4, 5, 6]]);
37276
+ }));
37277
+ return _handleInstall.apply(this, arguments);
37278
+ }
37279
+ var colorEntries = [{
37280
+ label: "Primary",
37281
+ value: colors.primary
37282
+ }, {
37283
+ label: "Secondary",
37284
+ value: colors.secondary
37285
+ }, {
37286
+ label: "Tertiary",
37287
+ value: colors.tertiary
37288
+ }, {
37289
+ label: "Neutral",
37290
+ value: colors.neutral
37291
+ }].filter(function (c) {
37292
+ return c.value;
37293
+ });
37294
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
37295
+ className: "flex flex-col flex-1 min-h-0",
37296
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
37297
+ className: "flex-1 min-h-0 overflow-y-auto p-6 space-y-6 ".concat(panelStyles.textColor || "text-gray-200"),
37298
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
37299
+ className: "flex flex-row items-center gap-3",
37300
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
37301
+ className: "h-5 w-5 flex-shrink-0 flex items-center justify-center",
37302
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37303
+ icon: "palette",
37304
+ className: "h-5 w-5"
37305
+ })
37306
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
37307
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.SubHeading3, {
37308
+ title: pkg.displayName || pkg.name,
37309
+ padding: false
37310
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
37311
+ className: "flex items-center gap-2 mt-0.5",
37312
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
37313
+ className: "text-sm opacity-60",
37314
+ children: ["by ", pkg.author || "Unknown"]
37315
+ }), pkg.version && /*#__PURE__*/jsxRuntime.jsxs("span", {
37316
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-70"),
37317
+ children: ["v", pkg.version]
37318
+ })]
37319
+ })]
37320
+ })]
37321
+ }), /*#__PURE__*/jsxRuntime.jsx("hr", {
37322
+ className: currentTheme["border-primary-medium"]
37323
+ }), colorEntries.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
37324
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
37325
+ className: "text-xs font-semibold opacity-50 mb-2 block",
37326
+ children: "COLORS"
37327
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37328
+ className: "flex flex-row gap-3",
37329
+ children: colorEntries.map(function (_ref2) {
37330
+ var label = _ref2.label,
37331
+ value = _ref2.value;
37332
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
37333
+ className: "flex flex-col items-center gap-1",
37334
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
37335
+ className: "h-10 w-10 rounded-full border-2 border-white/20",
37336
+ style: {
37337
+ backgroundColor: value
37338
+ }
37339
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
37340
+ className: "text-[10px] opacity-50",
37341
+ children: label
37342
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
37343
+ className: "text-[10px] opacity-30 font-mono",
37344
+ children: value
37345
+ })]
37346
+ }, label);
37347
+ })
37348
+ })]
37349
+ }), pkg.description && /*#__PURE__*/jsxRuntime.jsx("p", {
37350
+ className: "text-sm",
37351
+ children: pkg.description
37352
+ }), pkg.tags && pkg.tags.length > 0 && /*#__PURE__*/jsxRuntime.jsx("div", {
37353
+ className: "flex flex-wrap gap-1",
37354
+ children: pkg.tags.map(function (tag) {
37355
+ return /*#__PURE__*/jsxRuntime.jsx("span", {
37356
+ className: "text-xs px-2 py-0.5 rounded ".concat(currentTheme["bg-primary-medium"], " opacity-60"),
37357
+ children: tag
37358
+ }, tag);
37359
+ })
37360
+ }), installResult && /*#__PURE__*/jsxRuntime.jsx("div", {
37361
+ className: "p-2 rounded border ".concat(installResult.status === "success" ? "bg-green-900/20 border-green-700" : "bg-red-900/30 border-red-700"),
37362
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
37363
+ className: "flex items-center gap-2",
37364
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37365
+ icon: installResult.status === "success" ? "circle-check" : "circle-xmark",
37366
+ className: "h-4 w-4 ".concat(installResult.status === "success" ? "text-green-400" : "text-red-400")
37367
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
37368
+ className: "text-sm ".concat(installResult.status === "error" ? "text-red-400" : ""),
37369
+ children: installResult.message
37370
+ })]
37371
+ })
37372
+ })]
37373
+ }), (installResult === null || installResult === void 0 ? void 0 : installResult.status) !== "success" && /*#__PURE__*/jsxRuntime.jsx("div", {
37374
+ className: "flex items-center justify-end px-6 py-3 border-t ".concat(currentTheme["border-primary-medium"]),
37375
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
37376
+ title: isInstalling ? "Installing..." : "Install Theme",
37377
+ bgColor: "bg-blue-600",
37378
+ hoverBackgroundColor: isInstalling ? "" : "hover:bg-blue-700",
37379
+ textSize: "text-sm",
37380
+ padding: "py-1.5 px-4",
37381
+ onClick: handleInstall,
37382
+ disabled: isInstalling
37383
+ })
37384
+ })]
37385
+ });
37386
+ };
37387
+
37388
+ var DiscoverThemesDetail = function DiscoverThemesDetail(_ref) {
37389
+ var onBack = _ref.onBack,
37390
+ appId = _ref.appId,
37391
+ onInstallComplete = _ref.onInstallComplete;
37392
+ var _useContext = React.useContext(DashReact.ThemeContext),
37393
+ currentTheme = _useContext.currentTheme;
37394
+ var panelStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL, currentTheme, {
37395
+ grow: false
37396
+ });
37397
+ var _useState = React.useState([]),
37398
+ _useState2 = _slicedToArray(_useState, 2),
37399
+ packages = _useState2[0],
37400
+ setPackages = _useState2[1];
37401
+ var _useState3 = React.useState(false),
37402
+ _useState4 = _slicedToArray(_useState3, 2),
37403
+ isLoading = _useState4[0],
37404
+ setIsLoading = _useState4[1];
37405
+ var _useState5 = React.useState(null),
37406
+ _useState6 = _slicedToArray(_useState5, 2),
37407
+ error = _useState6[0],
37408
+ setError = _useState6[1];
37409
+ var _useState7 = React.useState(""),
37410
+ _useState8 = _slicedToArray(_useState7, 2),
37411
+ searchQuery = _useState8[0],
37412
+ setSearchQuery = _useState8[1];
37413
+ var _useState9 = React.useState(null),
37414
+ _useState0 = _slicedToArray(_useState9, 2),
37415
+ selectedPackageName = _useState0[0],
37416
+ setSelectedPackageName = _useState0[1];
37417
+ var search = React.useCallback(/*#__PURE__*/function () {
37418
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(query) {
37419
+ var _window$mainApi;
37420
+ var result, _t;
37421
+ return _regeneratorRuntime.wrap(function (_context) {
37422
+ while (1) switch (_context.prev = _context.next) {
37423
+ case 0:
37424
+ if ((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.registry) !== null && _window$mainApi !== void 0 && _window$mainApi.searchThemes) {
37425
+ _context.next = 1;
37426
+ break;
37427
+ }
37428
+ setPackages([]);
37429
+ return _context.abrupt("return");
37430
+ case 1:
37431
+ setIsLoading(true);
37432
+ setError(null);
37433
+ _context.prev = 2;
37434
+ _context.next = 3;
37435
+ return window.mainApi.registry.searchThemes(query || "", {});
37436
+ case 3:
37437
+ result = _context.sent;
37438
+ setPackages((result === null || result === void 0 ? void 0 : result.packages) || []);
37439
+ _context.next = 5;
37440
+ break;
37441
+ case 4:
37442
+ _context.prev = 4;
37443
+ _t = _context["catch"](2);
37444
+ setError(_t.message || "Failed to search theme registry");
37445
+ setPackages([]);
37446
+ case 5:
37447
+ _context.prev = 5;
37448
+ setIsLoading(false);
37449
+ return _context.finish(5);
37450
+ case 6:
37451
+ case "end":
37452
+ return _context.stop();
37453
+ }
37454
+ }, _callee, null, [[2, 4, 5, 6]]);
37455
+ }));
37456
+ return function (_x) {
37457
+ return _ref2.apply(this, arguments);
37458
+ };
37459
+ }(), []);
37460
+
37461
+ // Debounce search on query changes
37462
+ React.useEffect(function () {
37463
+ var timer = setTimeout(function () {
37464
+ search(searchQuery);
37465
+ }, 300);
37466
+ return function () {
37467
+ return clearTimeout(timer);
37468
+ };
37469
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37470
+ }, [searchQuery]);
37471
+ var retry = function retry() {
37472
+ return search(searchQuery);
37473
+ };
37474
+ var selectedPackage = selectedPackageName ? packages.find(function (p) {
37475
+ return p.name === selectedPackageName;
37476
+ }) : null;
37477
+
37478
+ // If a package is selected, show its detail inline
37479
+ if (selectedPackage) {
37480
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
37481
+ className: "flex flex-col flex-1 min-h-0",
37482
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
37483
+ className: "flex-shrink-0 px-4 pt-4",
37484
+ children: /*#__PURE__*/jsxRuntime.jsxs("button", {
37485
+ type: "button",
37486
+ onClick: function onClick() {
37487
+ return setSelectedPackageName(null);
37488
+ },
37489
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
37490
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37491
+ icon: "arrow-left",
37492
+ className: "h-3 w-3"
37493
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
37494
+ children: "Back"
37495
+ })]
37496
+ })
37497
+ }), /*#__PURE__*/jsxRuntime.jsx(RegistryThemeDetail, {
37498
+ themePackage: selectedPackage,
37499
+ appId: appId,
37500
+ onInstallComplete: onInstallComplete
37501
+ })]
37502
+ });
37503
+ }
37504
+
37505
+ // Package list view
37506
+ var listBody;
37507
+ if (isLoading) {
37508
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
37509
+ className: "flex items-center justify-center py-12",
37510
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
37511
+ className: "text-center",
37512
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
37513
+ className: "animate-spin rounded-full h-6 w-6 border-b-2 border-blue-500 mx-auto mb-3"
37514
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
37515
+ className: "text-sm opacity-50",
37516
+ children: "Loading themes..."
37517
+ })]
37518
+ })
37519
+ });
37520
+ } else if (error) {
37521
+ listBody = /*#__PURE__*/jsxRuntime.jsxs("div", {
37522
+ className: "px-4 py-8 text-center",
37523
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
37524
+ className: "text-sm text-red-400 mb-3",
37525
+ children: error
37526
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Button, {
37527
+ title: "Retry",
37528
+ bgColor: "bg-gray-700",
37529
+ hoverBackgroundColor: "hover:bg-gray-600",
37530
+ textSize: "text-sm",
37531
+ padding: "py-1 px-3",
37532
+ onClick: retry
37533
+ })]
37534
+ });
37535
+ } else if (packages.length === 0) {
37536
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
37537
+ className: "px-4 py-8 text-center",
37538
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.Paragraph, {
37539
+ className: "text-sm opacity-50",
37540
+ children: searchQuery ? "No themes match your search." : "No theme packages available."
37541
+ })
37542
+ });
37543
+ } else {
37544
+ listBody = /*#__PURE__*/jsxRuntime.jsx("div", {
37545
+ className: "space-y-1",
37546
+ children: packages.map(function (pkg) {
37547
+ var colors = pkg.colors || {};
37548
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
37549
+ icon: /*#__PURE__*/jsxRuntime.jsx("div", {
37550
+ className: "flex items-center gap-0.5",
37551
+ children: [colors.primary, colors.secondary, colors.tertiary].filter(Boolean).map(function (color, i) {
37552
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
37553
+ className: "h-3 w-3 rounded-full border border-white/20",
37554
+ style: {
37555
+ backgroundColor: color
37556
+ }
37557
+ }, i);
37558
+ })
37559
+ }),
37560
+ onClick: function onClick() {
37561
+ return setSelectedPackageName(pkg.name);
37562
+ },
37563
+ children: pkg.displayName || pkg.name
37564
+ }, pkg.name);
37565
+ })
37566
+ });
37567
+ }
37568
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
37569
+ className: "flex flex-col flex-1 min-h-0 ".concat(panelStyles.textColor || "text-gray-200"),
37570
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
37571
+ className: "flex-shrink-0 px-4 pt-4",
37572
+ children: /*#__PURE__*/jsxRuntime.jsxs("button", {
37573
+ type: "button",
37574
+ onClick: onBack,
37575
+ className: "flex items-center gap-1.5 text-sm opacity-60 hover:opacity-100 transition-opacity",
37576
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37577
+ icon: "arrow-left",
37578
+ className: "h-3 w-3"
37579
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
37580
+ children: "Back"
37581
+ })]
37582
+ })
37583
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37584
+ className: "flex-shrink-0 px-4 py-3",
37585
+ children: /*#__PURE__*/jsxRuntime.jsx(DashReact.SearchInput, {
37586
+ value: searchQuery,
37587
+ onChange: setSearchQuery,
37588
+ placeholder: "Search themes...",
37589
+ inputClassName: "py-1.5 text-xs"
37590
+ })
37591
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37592
+ className: "flex-1 min-h-0 overflow-y-auto px-2",
37593
+ children: listBody
37594
+ }), !isLoading && !error && packages.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
37595
+ className: "flex-shrink-0 px-4 py-2 text-[10px] opacity-40 border-t border-white/10",
37596
+ children: [packages.length, " theme", packages.length !== 1 ? "s" : ""]
37597
+ })]
37598
+ });
37599
+ };
37600
+
37601
+ function ownKeys$5(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; }
37602
+ function _objectSpread$5(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$5(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$5(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
37603
+ var ThemesSection = function ThemesSection(_ref) {
37604
+ var _ref$onOpenThemeEdito = _ref.onOpenThemeEditor,
37605
+ onOpenThemeEditor = _ref$onOpenThemeEdito === void 0 ? null : _ref$onOpenThemeEdito,
37606
+ _ref$dashApi = _ref.dashApi,
37607
+ dashApi = _ref$dashApi === void 0 ? null : _ref$dashApi,
37608
+ _ref$credentials = _ref.credentials,
37609
+ credentials = _ref$credentials === void 0 ? null : _ref$credentials,
37610
+ _ref$createRequested = _ref.createRequested,
37611
+ createRequested = _ref$createRequested === void 0 ? false : _ref$createRequested,
37612
+ _ref$onCreateAcknowle = _ref.onCreateAcknowledged,
37613
+ onCreateAcknowledged = _ref$onCreateAcknowle === void 0 ? null : _ref$onCreateAcknowle;
37614
+ var _useContext = React.useContext(DashReact.ThemeContext),
37615
+ themes = _useContext.themes,
37616
+ currentThemeKey = _useContext.themeKey,
37617
+ themeVariant = _useContext.themeVariant,
37618
+ changeCurrentTheme = _useContext.changeCurrentTheme,
37619
+ changeThemeVariant = _useContext.changeThemeVariant,
37620
+ changeThemesForApplication = _useContext.changeThemesForApplication,
37621
+ currentTheme = _useContext.currentTheme;
37622
+ var _useState = React.useState(currentThemeKey),
37623
+ _useState2 = _slicedToArray(_useState, 2),
37624
+ selectedThemeKey = _useState2[0],
37625
+ setSelectedThemeKey = _useState2[1];
37626
+ var _useState3 = React.useState(GENERATE_MODES.NONE),
37627
+ _useState4 = _slicedToArray(_useState3, 2),
37628
+ generateMode = _useState4[0],
37629
+ setGenerateMode = _useState4[1];
37630
+ var _useState5 = React.useState(""),
37631
+ _useState6 = _slicedToArray(_useState5, 2),
37632
+ wizardName = _useState6[0],
37633
+ setWizardName = _useState6[1];
37634
+ var _useState7 = React.useState(null),
37635
+ _useState8 = _slicedToArray(_useState7, 2),
37636
+ wizardMethod = _useState8[0],
37637
+ setWizardMethod = _useState8[1];
37638
+ var _useState9 = React.useState(null),
37639
+ _useState0 = _slicedToArray(_useState9, 2),
37640
+ wizardTheme = _useState0[0],
37641
+ setWizardTheme = _useState0[1];
37642
+ // null | "marketplace"
37643
+ var _useState1 = React.useState(null),
37644
+ _useState10 = _slicedToArray(_useState1, 2),
37645
+ installMode = _useState10[0],
37646
+ setInstallMode = _useState10[1];
37647
+ var themeEntries = themes ? Object.entries(themes) : [];
37648
+ var appId = credentials === null || credentials === void 0 ? void 0 : credentials.appId;
37649
+ var rowStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL_HEADER, currentTheme, {
37650
+ grow: false
37651
+ });
37652
+
37653
+ // Handle create request from parent — enter wizard mode
37654
+ var prevCreateRequested = React.useRef(false);
37655
+ React.useEffect(function () {
37656
+ if (createRequested && !prevCreateRequested.current) {
37657
+ setGenerateMode(GENERATE_MODES.WIZARD);
37658
+ setWizardName("");
37659
+ setWizardMethod(null);
37660
+ setWizardTheme(null);
37661
+ setSelectedThemeKey(null);
37662
+ setInstallMode(null);
37663
+ }
37664
+ prevCreateRequested.current = createRequested;
37665
+ if (createRequested && onCreateAcknowledged) {
37666
+ onCreateAcknowledged();
37667
+ }
37668
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37669
+ }, [createRequested]);
37670
+ function handleCreateFromPreset(preset) {
37671
+ if (!dashApi || !appId) return;
37672
+ var key = preset.id || "theme-".concat(Date.now());
37673
+ preset.id = key;
37674
+ saveAndSelectTheme(key, preset);
37675
+ setGenerateMode(GENERATE_MODES.NONE);
37676
+ }
37677
+ function handleCreateFromHarmony(theme) {
37678
+ if (!dashApi || !appId) return;
37679
+ var key = theme.id;
37680
+ saveAndSelectTheme(key, theme);
37681
+ setGenerateMode(GENERATE_MODES.NONE);
37682
+ }
37683
+ function handleWizardComplete() {
37684
+ if (!wizardTheme || !wizardName.trim()) return;
37685
+ if (!dashApi || !appId) return;
37686
+ var key = wizardTheme.id || "theme-".concat(Date.now());
37687
+ var finalTheme = _objectSpread$5(_objectSpread$5({}, wizardTheme), {}, {
37688
+ id: key,
37689
+ name: wizardName.trim()
37690
+ });
37691
+ saveAndSelectTheme(key, finalTheme);
37692
+ }
37693
+ function saveAndSelectTheme(key, rawTheme) {
37694
+ dashApi.saveTheme(appId, key, rawTheme, function (e, message) {
37695
+ if (message && message.themes) {
37696
+ changeThemesForApplication(message.themes);
37697
+ }
37698
+ setSelectedThemeKey(key);
37699
+ setGenerateMode(GENERATE_MODES.NONE);
37700
+ }, function (e, err) {
37701
+ });
37702
+ }
37703
+ function handleDeleteTheme(key) {
36531
37704
  if (!dashApi || !appId) return;
36532
37705
  if (key === currentThemeKey) {
36533
37706
  var _themeEntries$find;
@@ -36561,63 +37734,109 @@ var ThemesSection = function ThemesSection(_ref) {
36561
37734
  function handleEdit() {
36562
37735
  if (onOpenThemeEditor) onOpenThemeEditor();
36563
37736
  }
36564
- var rowStyles = DashReact.getStylesForItem(DashReact.themeObjects.PANEL_HEADER, currentTheme, {
36565
- grow: false
36566
- });
36567
37737
  var listContent = /*#__PURE__*/jsxRuntime.jsxs("div", {
36568
- className: "flex flex-col",
37738
+ className: "flex flex-col h-full",
36569
37739
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36570
- className: "flex flex-row items-center justify-between px-3 py-3 border-b ".concat(rowStyles.borderColor || ""),
37740
+ className: "flex-shrink-0 flex flex-col gap-2 px-3 py-2 ".concat(rowStyles.backgroundColor || ""),
36571
37741
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
36572
- className: "flex flex-row items-center gap-2",
36573
- children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36574
- icon: "sun",
36575
- className: "h-3 w-3 opacity-50"
36576
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
36577
- checked: themeVariant === "dark",
36578
- onChange: handleToggleVariant
36579
- }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36580
- icon: "moon",
36581
- className: "h-3 w-3 opacity-50"
37742
+ className: "flex flex-row items-center justify-between",
37743
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
37744
+ className: "flex flex-row items-center gap-2",
37745
+ children: [/*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37746
+ icon: "sun",
37747
+ className: "h-3 w-3 opacity-50"
37748
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.Switch, {
37749
+ checked: themeVariant === "dark",
37750
+ onChange: handleToggleVariant
37751
+ }), /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37752
+ icon: "moon",
37753
+ className: "h-3 w-3 opacity-50"
37754
+ })]
37755
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
37756
+ className: "text-xs opacity-50",
37757
+ children: themeVariant === "dark" ? "Dark" : "Light"
36582
37758
  })]
36583
- }), /*#__PURE__*/jsxRuntime.jsx("span", {
36584
- className: "text-xs opacity-50",
36585
- children: themeVariant === "dark" ? "Dark" : "Light"
36586
- })]
36587
- }), /*#__PURE__*/jsxRuntime.jsxs(DashReact.Sidebar.Content, {
36588
- children: [themeEntries.map(function (_ref4) {
36589
- var _ref5 = _slicedToArray(_ref4, 2),
36590
- key = _ref5[0],
36591
- theme = _ref5[1];
36592
- var isActive = key === currentThemeKey;
36593
- var isSelected = selectedThemeKey === key && generateMode === GENERATE_MODES.NONE;
36594
- return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
36595
- icon: isActive ? /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36596
- icon: "check",
36597
- className: "h-3 w-3 text-green-500"
36598
- }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
36599
- icon: "palette",
36600
- className: "h-3.5 w-3.5"
36601
- }),
36602
- active: isSelected,
36603
- onClick: function onClick() {
36604
- setSelectedThemeKey(key);
36605
- setGenerateMode(GENERATE_MODES.NONE);
36606
- },
36607
- badge: isActive ? "active" : null,
36608
- className: isSelected ? "bg-white/10 opacity-100" : "",
36609
- children: theme.name || key
36610
- }, key);
36611
- }), themeEntries.length === 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
36612
- className: "text-sm opacity-40 py-8 text-center",
36613
- children: "No themes available"
37759
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37760
+ className: "flex bg-white/5 rounded-md p-0.5",
37761
+ children: [{
37762
+ key: "themes",
37763
+ label: "My Themes"
37764
+ }, {
37765
+ key: "marketplace",
37766
+ label: "Marketplace"
37767
+ }].map(function (tab) {
37768
+ var currentTab = installMode === "marketplace" ? "marketplace" : "themes";
37769
+ return /*#__PURE__*/jsxRuntime.jsx("button", {
37770
+ type: "button",
37771
+ onClick: function onClick() {
37772
+ if (tab.key === "marketplace") {
37773
+ setInstallMode("marketplace");
37774
+ setSelectedThemeKey(null);
37775
+ setGenerateMode(GENERATE_MODES.NONE);
37776
+ } else {
37777
+ setInstallMode(null);
37778
+ }
37779
+ },
37780
+ 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"),
37781
+ children: tab.label
37782
+ }, tab.key);
37783
+ })
36614
37784
  })]
37785
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
37786
+ className: "flex-1 overflow-y-auto min-h-0",
37787
+ children: /*#__PURE__*/jsxRuntime.jsxs(DashReact.Sidebar.Content, {
37788
+ children: [themeEntries.map(function (_ref4) {
37789
+ var _ref5 = _slicedToArray(_ref4, 2),
37790
+ key = _ref5[0],
37791
+ theme = _ref5[1];
37792
+ var isActive = key === currentThemeKey;
37793
+ var isSelected = selectedThemeKey === key && generateMode === GENERATE_MODES.NONE && installMode !== "marketplace";
37794
+ return /*#__PURE__*/jsxRuntime.jsx(DashReact.Sidebar.Item, {
37795
+ icon: isActive ? /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37796
+ icon: "check",
37797
+ className: "h-3 w-3 text-green-500"
37798
+ }) : /*#__PURE__*/jsxRuntime.jsx(DashReact.FontAwesomeIcon, {
37799
+ icon: "palette",
37800
+ className: "h-3.5 w-3.5"
37801
+ }),
37802
+ active: isSelected,
37803
+ onClick: function onClick() {
37804
+ setSelectedThemeKey(key);
37805
+ setGenerateMode(GENERATE_MODES.NONE);
37806
+ setInstallMode(null);
37807
+ },
37808
+ badge: isActive ? "active" : null,
37809
+ className: isSelected ? "bg-white/10 opacity-100" : "",
37810
+ children: theme.name || key
37811
+ }, key);
37812
+ }), themeEntries.length === 0 && /*#__PURE__*/jsxRuntime.jsx("span", {
37813
+ className: "text-sm opacity-40 py-8 text-center",
37814
+ children: "No themes available"
37815
+ })]
37816
+ })
36615
37817
  })]
36616
37818
  });
36617
37819
 
36618
37820
  // Determine detail content based on mode
36619
37821
  var detailContent = null;
36620
- if (generateMode === GENERATE_MODES.WIZARD) {
37822
+ if (installMode === "marketplace") {
37823
+ detailContent = /*#__PURE__*/jsxRuntime.jsx(DiscoverThemesDetail, {
37824
+ onBack: function onBack() {
37825
+ setInstallMode(null);
37826
+ },
37827
+ appId: appId,
37828
+ onInstallComplete: function onInstallComplete() {
37829
+ // Refresh themes after install
37830
+ if (dashApi && appId) {
37831
+ dashApi.listThemes(appId, function (e, message) {
37832
+ if (message && message.themes) {
37833
+ changeThemesForApplication(message.themes);
37834
+ }
37835
+ });
37836
+ }
37837
+ }
37838
+ });
37839
+ } else if (generateMode === GENERATE_MODES.WIZARD) {
36621
37840
  detailContent = /*#__PURE__*/jsxRuntime.jsx(ThemeQuickCreate, {
36622
37841
  wizardName: wizardName,
36623
37842
  setWizardName: setWizardName,
@@ -36643,7 +37862,8 @@ var ThemesSection = function ThemesSection(_ref) {
36643
37862
  themeVariant: themeVariant,
36644
37863
  onActivate: handleActivate,
36645
37864
  onOpenThemeEditor: handleEdit,
36646
- onDelete: handleDeleteTheme
37865
+ onDelete: handleDeleteTheme,
37866
+ appId: appId
36647
37867
  });
36648
37868
  }
36649
37869
  return /*#__PURE__*/jsxRuntime.jsx(SectionLayout, {