@trops/dash-core 0.1.604 → 0.1.606
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 +271 -39
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +271 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -2549,6 +2549,27 @@ var ThemeWrapper = function ThemeWrapper(_ref) {
|
|
|
2549
2549
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2550
2550
|
}, [chosenTheme, themeVariant, themeName, themesForApplication, rawThemes]);
|
|
2551
2551
|
|
|
2552
|
+
// Broadcast the app-level theme to a SEPARATE global so
|
|
2553
|
+
// components rendered OUTSIDE the React theme tree
|
|
2554
|
+
// (WidgetBuilderModal, AppUpdatesModal — they live as siblings
|
|
2555
|
+
// of DashboardStage in dash-electron's Dash.js render) can fall
|
|
2556
|
+
// back to it when no dashboard-specific override is in play.
|
|
2557
|
+
//
|
|
2558
|
+
// We can't share the same global with DashboardThemeProvider's
|
|
2559
|
+
// per-workspace broadcast because React commits child effects
|
|
2560
|
+
// BEFORE parent effects — ThemeWrapper would always run last
|
|
2561
|
+
// and silently overwrite the workspace theme. Two separate
|
|
2562
|
+
// globals avoid the race: consumers read
|
|
2563
|
+
// `__dashThemeContext` (workspace) first, fall back to
|
|
2564
|
+
// `__dashAppThemeContext` (app-level) when no workspace is open.
|
|
2565
|
+
useEffect(function () {
|
|
2566
|
+
if (typeof window === "undefined") return undefined;
|
|
2567
|
+
if (contextValue !== null && contextValue !== void 0 && contextValue.currentTheme) {
|
|
2568
|
+
window.__dashAppThemeContext = contextValue;
|
|
2569
|
+
window.dispatchEvent(new Event("dash:theme-changed"));
|
|
2570
|
+
}
|
|
2571
|
+
}, [contextValue]);
|
|
2572
|
+
|
|
2552
2573
|
// Write the active theme's CSS custom properties to :root so any
|
|
2553
2574
|
// hex-channel tokens (`bg-[var(--primary-700)]` etc. emitted by
|
|
2554
2575
|
// ThemeModel) resolve app-wide. Without this, saving a hex theme
|
|
@@ -2786,13 +2807,42 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2786
2807
|
error = _useState6[0],
|
|
2787
2808
|
setError = _useState6[1];
|
|
2788
2809
|
var refresh = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
2789
|
-
var _window$mainApi, cMap, builtinWidgets, registryByName, list, installedFromCM, cmSourcePackages, fallbackInstalled, _t;
|
|
2810
|
+
var _window$mainApi, _window$mainApi2, classifyWidget, cMap, builtinWidgets, draftsByPackageDir, draftShortIdToId, allDrafts, _iterator4, _step4, d, shortId, registryByName, list, installedFromCM, cmSourcePackages, fallbackInstalled, _t, _t3;
|
|
2790
2811
|
return _regeneratorRuntime.wrap(function (_context) {
|
|
2791
2812
|
while (1) switch (_context.prev = _context.next) {
|
|
2792
2813
|
case 0:
|
|
2793
2814
|
setIsLoading(true);
|
|
2794
2815
|
setError(null);
|
|
2795
2816
|
_context.prev = 1;
|
|
2817
|
+
classifyWidget = function classifyWidget(reg, fallbackName) {
|
|
2818
|
+
var name = (reg === null || reg === void 0 ? void 0 : reg.name) || fallbackName || "";
|
|
2819
|
+
var path = (reg === null || reg === void 0 ? void 0 : reg.path) || "";
|
|
2820
|
+
// 1. Match against drafts metadata by packageDir (canonical).
|
|
2821
|
+
if (path && draftsByPackageDir.has(path)) {
|
|
2822
|
+
return {
|
|
2823
|
+
kind: "draft",
|
|
2824
|
+
draftId: draftsByPackageDir.get(path).id
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
// 2. Fallback: the dir name follows `<base>-draft-<shortId>`;
|
|
2828
|
+
// pluck the shortId and look it up in the drafts list.
|
|
2829
|
+
var m = String(name).match(/-draft-([A-Za-z0-9]+)$/);
|
|
2830
|
+
if (m) {
|
|
2831
|
+
var _shortId = m[1].slice(0, 8);
|
|
2832
|
+
var draftId = draftShortIdToId.get(_shortId) || null;
|
|
2833
|
+
return {
|
|
2834
|
+
kind: "draft",
|
|
2835
|
+
draftId: draftId
|
|
2836
|
+
};
|
|
2837
|
+
}
|
|
2838
|
+
return {
|
|
2839
|
+
kind: "installed",
|
|
2840
|
+
draftId: null
|
|
2841
|
+
};
|
|
2842
|
+
}; // ── Installed widgets from ComponentManager + Registry ───
|
|
2843
|
+
// CM entries with _sourcePackage are registry-installed widgets.
|
|
2844
|
+
// Show each as an individual "installed" entry, enriched with
|
|
2845
|
+
// registry-level metadata (version, path, packageId).
|
|
2796
2846
|
// ── Built-in widgets from ComponentManager ──────────────
|
|
2797
2847
|
cMap = ComponentManager.componentMap() || {};
|
|
2798
2848
|
builtinWidgets = Object.keys(cMap).filter(function (key) {
|
|
@@ -2811,33 +2861,80 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2811
2861
|
version: null,
|
|
2812
2862
|
path: null,
|
|
2813
2863
|
source: "builtin",
|
|
2864
|
+
kind: "installed",
|
|
2865
|
+
draftId: null,
|
|
2814
2866
|
providers: config.providers || [],
|
|
2815
2867
|
workspace: config.workspace || null,
|
|
2816
2868
|
componentNames: [key],
|
|
2817
2869
|
scopedId: key
|
|
2818
2870
|
};
|
|
2819
|
-
}); // ──
|
|
2820
|
-
//
|
|
2821
|
-
//
|
|
2822
|
-
//
|
|
2871
|
+
}); // ── Drafts (in-progress widgets from the AI Builder) ─────
|
|
2872
|
+
// Drafts on disk look like installed packages — their dirs
|
|
2873
|
+
// sit under @ai-built/<name>-draft-<shortId>/ alongside real
|
|
2874
|
+
// installs. We surface them as `kind: "draft"` so consumers
|
|
2875
|
+
// (dashboard picker, Settings → Widgets) can render them
|
|
2876
|
+
// distinctly (Resume/Delete affordances) or filter them out.
|
|
2877
|
+
// The match is `packageDir`-based when available (canonical)
|
|
2878
|
+
// and falls back to a `-draft-` name-pattern check so legacy
|
|
2879
|
+
// drafts without the on-disk metadata still get classified.
|
|
2880
|
+
draftsByPackageDir = new Map();
|
|
2881
|
+
draftShortIdToId = new Map();
|
|
2882
|
+
if (!((_window$mainApi = window.mainApi) !== null && _window$mainApi !== void 0 && (_window$mainApi = _window$mainApi.drafts) !== null && _window$mainApi !== void 0 && _window$mainApi.list)) {
|
|
2883
|
+
_context.next = 6;
|
|
2884
|
+
break;
|
|
2885
|
+
}
|
|
2886
|
+
_context.prev = 2;
|
|
2887
|
+
_context.next = 3;
|
|
2888
|
+
return window.mainApi.drafts.list();
|
|
2889
|
+
case 3:
|
|
2890
|
+
_t = _context.sent;
|
|
2891
|
+
if (_t) {
|
|
2892
|
+
_context.next = 4;
|
|
2893
|
+
break;
|
|
2894
|
+
}
|
|
2895
|
+
_t = [];
|
|
2896
|
+
case 4:
|
|
2897
|
+
allDrafts = _t;
|
|
2898
|
+
_iterator4 = _createForOfIteratorHelper$M(allDrafts);
|
|
2899
|
+
try {
|
|
2900
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
2901
|
+
d = _step4.value;
|
|
2902
|
+
if (d !== null && d !== void 0 && d.packageDir) draftsByPackageDir.set(d.packageDir, d);
|
|
2903
|
+
if (d !== null && d !== void 0 && d.id) {
|
|
2904
|
+
shortId = String(d.id).replace(/^draft-/, "").slice(0, 8);
|
|
2905
|
+
if (shortId) draftShortIdToId.set(shortId, d.id);
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
} catch (err) {
|
|
2909
|
+
_iterator4.e(err);
|
|
2910
|
+
} finally {
|
|
2911
|
+
_iterator4.f();
|
|
2912
|
+
}
|
|
2913
|
+
_context.next = 6;
|
|
2914
|
+
break;
|
|
2915
|
+
case 5:
|
|
2916
|
+
_context.prev = 5;
|
|
2917
|
+
_context["catch"](2);
|
|
2918
|
+
case 6:
|
|
2823
2919
|
registryByName = {};
|
|
2824
|
-
if (!((_window$
|
|
2825
|
-
_context.next =
|
|
2920
|
+
if (!((_window$mainApi2 = window.mainApi) !== null && _window$mainApi2 !== void 0 && _window$mainApi2.widgets)) {
|
|
2921
|
+
_context.next = 8;
|
|
2826
2922
|
break;
|
|
2827
2923
|
}
|
|
2828
|
-
_context.next =
|
|
2924
|
+
_context.next = 7;
|
|
2829
2925
|
return window.mainApi.widgets.list();
|
|
2830
|
-
case
|
|
2926
|
+
case 7:
|
|
2831
2927
|
list = _context.sent;
|
|
2832
2928
|
(list || []).forEach(function (w) {
|
|
2833
2929
|
registryByName[w.packageId || w.name] = w;
|
|
2834
2930
|
});
|
|
2835
|
-
case
|
|
2931
|
+
case 8:
|
|
2836
2932
|
installedFromCM = Object.keys(cMap).filter(function (key) {
|
|
2837
2933
|
return cMap[key].type === "widget" && !!cMap[key]._sourcePackage;
|
|
2838
2934
|
}).map(function (key) {
|
|
2839
2935
|
var config = cMap[key];
|
|
2840
2936
|
var reg = registryByName[config._sourcePackage] || {};
|
|
2937
|
+
var classification = classifyWidget(reg, config._sourcePackage);
|
|
2841
2938
|
return {
|
|
2842
2939
|
name: key,
|
|
2843
2940
|
displayName: config.name || key,
|
|
@@ -2848,6 +2945,8 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2848
2945
|
version: reg.version || null,
|
|
2849
2946
|
path: reg.path || null,
|
|
2850
2947
|
source: "installed",
|
|
2948
|
+
kind: classification.kind,
|
|
2949
|
+
draftId: classification.draftId,
|
|
2851
2950
|
providers: config.providers || [],
|
|
2852
2951
|
workspace: config.workspace || null,
|
|
2853
2952
|
componentNames: [key],
|
|
@@ -2864,6 +2963,7 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2864
2963
|
fallbackInstalled = Object.values(registryByName).filter(function (w) {
|
|
2865
2964
|
return !cmSourcePackages.has(w.name);
|
|
2866
2965
|
}).map(function (w) {
|
|
2966
|
+
var classification = classifyWidget(w, w.name);
|
|
2867
2967
|
return {
|
|
2868
2968
|
name: w.name,
|
|
2869
2969
|
displayName: w.displayName || w.name,
|
|
@@ -2874,6 +2974,8 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2874
2974
|
version: w.version || null,
|
|
2875
2975
|
path: w.path || null,
|
|
2876
2976
|
source: "installed",
|
|
2977
|
+
kind: classification.kind,
|
|
2978
|
+
draftId: classification.draftId,
|
|
2877
2979
|
providers: w.providers || [],
|
|
2878
2980
|
workspace: w.workspace || null,
|
|
2879
2981
|
componentNames: w.componentNames || [],
|
|
@@ -2882,31 +2984,31 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2882
2984
|
};
|
|
2883
2985
|
});
|
|
2884
2986
|
setWidgets([].concat(_toConsumableArray(builtinWidgets), _toConsumableArray(installedFromCM), _toConsumableArray(fallbackInstalled)));
|
|
2885
|
-
_context.next =
|
|
2987
|
+
_context.next = 10;
|
|
2886
2988
|
break;
|
|
2887
|
-
case
|
|
2888
|
-
_context.prev =
|
|
2889
|
-
|
|
2890
|
-
setError(
|
|
2989
|
+
case 9:
|
|
2990
|
+
_context.prev = 9;
|
|
2991
|
+
_t3 = _context["catch"](1);
|
|
2992
|
+
setError(_t3.message || "Failed to load widgets");
|
|
2891
2993
|
setWidgets([]);
|
|
2892
|
-
case
|
|
2893
|
-
_context.prev =
|
|
2994
|
+
case 10:
|
|
2995
|
+
_context.prev = 10;
|
|
2894
2996
|
setIsLoading(false);
|
|
2895
|
-
return _context.finish(
|
|
2896
|
-
case
|
|
2997
|
+
return _context.finish(10);
|
|
2998
|
+
case 11:
|
|
2897
2999
|
case "end":
|
|
2898
3000
|
return _context.stop();
|
|
2899
3001
|
}
|
|
2900
|
-
}, _callee, null, [[1,
|
|
3002
|
+
}, _callee, null, [[1, 9, 10, 11], [2, 5]]);
|
|
2901
3003
|
})), []);
|
|
2902
3004
|
var uninstallWidget = useCallback(/*#__PURE__*/function () {
|
|
2903
3005
|
var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(widgetName) {
|
|
2904
|
-
var _window$
|
|
2905
|
-
var widget, packageId, cMap, keysToRemove,
|
|
3006
|
+
var _window$mainApi3;
|
|
3007
|
+
var widget, packageId, cMap, keysToRemove, _t4;
|
|
2906
3008
|
return _regeneratorRuntime.wrap(function (_context2) {
|
|
2907
3009
|
while (1) switch (_context2.prev = _context2.next) {
|
|
2908
3010
|
case 0:
|
|
2909
|
-
if ((_window$
|
|
3011
|
+
if ((_window$mainApi3 = window.mainApi) !== null && _window$mainApi3 !== void 0 && _window$mainApi3.widgets) {
|
|
2910
3012
|
_context2.next = 1;
|
|
2911
3013
|
break;
|
|
2912
3014
|
}
|
|
@@ -2937,8 +3039,8 @@ var useInstalledWidgets = function useInstalledWidgets() {
|
|
|
2937
3039
|
break;
|
|
2938
3040
|
case 4:
|
|
2939
3041
|
_context2.prev = 4;
|
|
2940
|
-
|
|
2941
|
-
throw
|
|
3042
|
+
_t4 = _context2["catch"](1);
|
|
3043
|
+
throw _t4;
|
|
2942
3044
|
case 5:
|
|
2943
3045
|
case "end":
|
|
2944
3046
|
return _context2.stop();
|
|
@@ -5725,6 +5827,45 @@ function ThemeBroadcast(_ref) {
|
|
|
5725
5827
|
return null;
|
|
5726
5828
|
}
|
|
5727
5829
|
|
|
5830
|
+
/**
|
|
5831
|
+
* Writes the dashboard theme's cssVars to `:root` while mounted, and
|
|
5832
|
+
* restores the previous values on unmount / theme switch.
|
|
5833
|
+
*
|
|
5834
|
+
* ThemeWrapper writes the APP theme's cssVars at the top of the tree.
|
|
5835
|
+
* Without this helper, a dashboard that overrides the app theme with a
|
|
5836
|
+
* hex-channel theme (like "Slack Generic") would carry the right class
|
|
5837
|
+
* names (`bg-[var(--primary-900)]`) but the `--primary-900` variable
|
|
5838
|
+
* on :root would still be the APP theme's value — or undefined if the
|
|
5839
|
+
* app theme is named-family. Hex-themed surfaces then render with no
|
|
5840
|
+
* background. This effect closes that gap by promoting the dashboard
|
|
5841
|
+
* theme's cssVars to :root for the duration of its mount.
|
|
5842
|
+
*/
|
|
5843
|
+
function DashboardCssVarsBridge(_ref2) {
|
|
5844
|
+
var cssVars = _ref2.cssVars;
|
|
5845
|
+
useEffect(function () {
|
|
5846
|
+
if (!cssVars || typeof document === "undefined") return undefined;
|
|
5847
|
+
var root = document.documentElement;
|
|
5848
|
+
var previous = {};
|
|
5849
|
+
var keys = Object.keys(cssVars);
|
|
5850
|
+
for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
|
|
5851
|
+
var key = _keys[_i];
|
|
5852
|
+
previous[key] = root.style.getPropertyValue(key);
|
|
5853
|
+
root.style.setProperty(key, cssVars[key]);
|
|
5854
|
+
}
|
|
5855
|
+
return function () {
|
|
5856
|
+
for (var _i2 = 0, _keys2 = keys; _i2 < _keys2.length; _i2++) {
|
|
5857
|
+
var _key = _keys2[_i2];
|
|
5858
|
+
if (previous[_key]) {
|
|
5859
|
+
root.style.setProperty(_key, previous[_key]);
|
|
5860
|
+
} else {
|
|
5861
|
+
root.style.removeProperty(_key);
|
|
5862
|
+
}
|
|
5863
|
+
}
|
|
5864
|
+
};
|
|
5865
|
+
}, [cssVars]);
|
|
5866
|
+
return null;
|
|
5867
|
+
}
|
|
5868
|
+
|
|
5728
5869
|
/**
|
|
5729
5870
|
* DashboardThemeProvider
|
|
5730
5871
|
*
|
|
@@ -5735,9 +5876,10 @@ function ThemeBroadcast(_ref) {
|
|
|
5735
5876
|
* App chrome (navbar, tab bar, sidebar) stays OUTSIDE this wrapper
|
|
5736
5877
|
* and keeps the app theme.
|
|
5737
5878
|
*/
|
|
5738
|
-
var DashboardThemeProvider = function DashboardThemeProvider(
|
|
5739
|
-
var
|
|
5740
|
-
|
|
5879
|
+
var DashboardThemeProvider = function DashboardThemeProvider(_ref3) {
|
|
5880
|
+
var _contextValue$current;
|
|
5881
|
+
var themeKey = _ref3.themeKey,
|
|
5882
|
+
children = _ref3.children;
|
|
5741
5883
|
var parentContext = useContext(ThemeContext);
|
|
5742
5884
|
var themes = parentContext.themes,
|
|
5743
5885
|
themeVariant = parentContext.themeVariant;
|
|
@@ -5769,6 +5911,8 @@ var DashboardThemeProvider = function DashboardThemeProvider(_ref2) {
|
|
|
5769
5911
|
value: contextValue,
|
|
5770
5912
|
children: [/*#__PURE__*/jsx(ThemeBroadcast, {
|
|
5771
5913
|
ctx: contextValue
|
|
5914
|
+
}), /*#__PURE__*/jsx(DashboardCssVarsBridge, {
|
|
5915
|
+
cssVars: contextValue === null || contextValue === void 0 || (_contextValue$current = contextValue.currentTheme) === null || _contextValue$current === void 0 ? void 0 : _contextValue$current.cssVars
|
|
5772
5916
|
}), children]
|
|
5773
5917
|
});
|
|
5774
5918
|
};
|
|
@@ -17604,6 +17748,12 @@ var EnhancedWidgetDropdown = function EnhancedWidgetDropdown(_ref) {
|
|
|
17604
17748
|
// Filter widgets based on search, author, and provider
|
|
17605
17749
|
var getFilteredWidgets = function getFilteredWidgets() {
|
|
17606
17750
|
var filtered = widgets.filter(function (widget) {
|
|
17751
|
+
// Drafts are in-progress widgets — they appear in
|
|
17752
|
+
// Settings → Widgets (as a Draft chip with Resume/Delete
|
|
17753
|
+
// affordances) but never in the dashboard placement picker
|
|
17754
|
+
// since they're not finished products.
|
|
17755
|
+
if (widget.kind === "draft") return false;
|
|
17756
|
+
|
|
17607
17757
|
// Search filter
|
|
17608
17758
|
var searchLower = searchQuery.toLowerCase();
|
|
17609
17759
|
var matchesSearch = !searchQuery || (widget.name || "").toLowerCase().includes(searchLower) || (widget.description || "").toLowerCase().includes(searchLower) || (widget.key || "").toLowerCase().includes(searchLower) || (widget.packageName || "").toLowerCase().includes(searchLower) || (widget.packageTags || []).some(function (t) {
|
|
@@ -28958,6 +29108,36 @@ var WorkspaceModel = function WorkspaceModel(workspaceItem) {
|
|
|
28958
29108
|
function ownKeys$H(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; }
|
|
28959
29109
|
function _objectSpread$H(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$H(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$H(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
28960
29110
|
|
|
29111
|
+
/**
|
|
29112
|
+
* Last-resort family for ANY channel whose value can't be resolved
|
|
29113
|
+
* (unknown name, missing palette entry, missing shade, …). Picked
|
|
29114
|
+
* because it's universally safelist-covered, has every shade from
|
|
29115
|
+
* 50..950, and is visually neutral — so a misconfigured theme
|
|
29116
|
+
* renders "muted" rather than blank/transparent.
|
|
29117
|
+
*
|
|
29118
|
+
* Slack Generic etc. exposed this: when a channel value was missing
|
|
29119
|
+
* or unrecognized, ThemeModel silently emitted `bg-undefined-700`
|
|
29120
|
+
* (not in any safelist) → Tailwind dropped the class → the
|
|
29121
|
+
* dropdown popover rendered transparent. Falling back here means
|
|
29122
|
+
* no token can be "missing" by the time `getStylesForItem` reads it.
|
|
29123
|
+
*/
|
|
29124
|
+
var FALLBACK_FAMILY = "gray";
|
|
29125
|
+
|
|
29126
|
+
/**
|
|
29127
|
+
* Resolve a channel value to a safelist-covered Tailwind family
|
|
29128
|
+
* name. Returns the original value when it's a hex (the caller
|
|
29129
|
+
* handles those via CSS variables) or a recognized palette family;
|
|
29130
|
+
* otherwise returns FALLBACK_FAMILY so the resulting class always
|
|
29131
|
+
* renders.
|
|
29132
|
+
*/
|
|
29133
|
+
function resolveChannelFamily(channelValue) {
|
|
29134
|
+
if (isHexColor$1(channelValue)) return channelValue;
|
|
29135
|
+
if (typeof channelValue === "string" && channelValue.length > 0 && TAILWIND_PALETTE && TAILWIND_PALETTE[channelValue]) {
|
|
29136
|
+
return channelValue;
|
|
29137
|
+
}
|
|
29138
|
+
return FALLBACK_FAMILY;
|
|
29139
|
+
}
|
|
29140
|
+
|
|
28961
29141
|
/**
|
|
28962
29142
|
* getNextLevel
|
|
28963
29143
|
* Need to generate the levels for tailwind
|
|
@@ -28976,6 +29156,11 @@ function invert(shade) {
|
|
|
28976
29156
|
* shade. Routes to the arbitrary-value syntax (`bg-[var(--type-shade)]`)
|
|
28977
29157
|
* when the channel's value is a hex.
|
|
28978
29158
|
*
|
|
29159
|
+
* Layer 1 fallback (audit follow-up to the Slack Generic bug): if
|
|
29160
|
+
* `channelValue` isn't a hex AND isn't a recognized Tailwind palette
|
|
29161
|
+
* family, fall back to FALLBACK_FAMILY so the emitted class is
|
|
29162
|
+
* always safelist-covered and never resolves to `bg-undefined-700`.
|
|
29163
|
+
*
|
|
28979
29164
|
* @param {"bg"|"text"|"border"} prefix
|
|
28980
29165
|
* @param {string} type channel name (primary | secondary | …)
|
|
28981
29166
|
* @param {number} shade tailwind shade (100..950)
|
|
@@ -28985,10 +29170,11 @@ function invert(shade) {
|
|
|
28985
29170
|
function classFor(prefix, type, shade, channelValue) {
|
|
28986
29171
|
var hover = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
|
|
28987
29172
|
var h = hover ? "hover:" : "";
|
|
28988
|
-
|
|
29173
|
+
var resolved = resolveChannelFamily(channelValue);
|
|
29174
|
+
if (isHexColor$1(resolved)) {
|
|
28989
29175
|
return "".concat(h).concat(prefix, "-[var(--").concat(type, "-").concat(shade, ")]");
|
|
28990
29176
|
}
|
|
28991
|
-
return "".concat(h).concat(prefix, "-").concat(
|
|
29177
|
+
return "".concat(h).concat(prefix, "-").concat(resolved, "-").concat(shade);
|
|
28992
29178
|
}
|
|
28993
29179
|
|
|
28994
29180
|
/**
|
|
@@ -29001,8 +29187,10 @@ function classFor(prefix, type, shade, channelValue) {
|
|
|
29001
29187
|
* produce a `var(--{type}-{shade})` reference that resolves against
|
|
29002
29188
|
* the CSS custom properties ThemePreviewProvider writes to :root.
|
|
29003
29189
|
*
|
|
29004
|
-
*
|
|
29005
|
-
*
|
|
29190
|
+
* Layer 1 fallback: when the channel value or shade can't be
|
|
29191
|
+
* resolved, fall back to FALLBACK_FAMILY's shade so cssValue is
|
|
29192
|
+
* never null. Pairs with classFor's same fallback to guarantee
|
|
29193
|
+
* every (type, shade) tuple yields a renderable token.
|
|
29006
29194
|
*/
|
|
29007
29195
|
function cssValueFor(type, shade, channelValue) {
|
|
29008
29196
|
if (isHexColor$1(channelValue)) {
|
|
@@ -29015,12 +29203,17 @@ function cssValueFor(type, shade, channelValue) {
|
|
|
29015
29203
|
var _hex = shades[shade] || shades[String(shade)];
|
|
29016
29204
|
if (_hex) return _hex;
|
|
29017
29205
|
}
|
|
29018
|
-
return
|
|
29206
|
+
return fallbackCssValue(shade);
|
|
29019
29207
|
}
|
|
29020
29208
|
var family = TAILWIND_PALETTE && TAILWIND_PALETTE[channelValue];
|
|
29021
|
-
if (!family) return
|
|
29209
|
+
if (!family) return fallbackCssValue(shade);
|
|
29022
29210
|
var hex = family[shade] || family[String(shade)];
|
|
29023
|
-
return hex ||
|
|
29211
|
+
return hex || fallbackCssValue(shade);
|
|
29212
|
+
}
|
|
29213
|
+
function fallbackCssValue(shade) {
|
|
29214
|
+
var fallback = TAILWIND_PALETTE && TAILWIND_PALETTE[FALLBACK_FAMILY];
|
|
29215
|
+
if (!fallback) return null;
|
|
29216
|
+
return fallback[shade] || fallback[String(shade)] || null;
|
|
29024
29217
|
}
|
|
29025
29218
|
function gradientFor(direction, type, fromShade, viaShade, toShade, channelValue) {
|
|
29026
29219
|
if (isHexColor$1(channelValue)) {
|
|
@@ -35205,11 +35398,25 @@ var ChannelEditorModal = function ChannelEditorModal(_ref) {
|
|
|
35205
35398
|
var nearest = useMemo(function () {
|
|
35206
35399
|
return nearestSwatch(selectedHex, families);
|
|
35207
35400
|
}, [selectedHex, families]);
|
|
35401
|
+
|
|
35402
|
+
// Auto-switch the family tab when the underlying selected color
|
|
35403
|
+
// changes (user picked a different channel/shade or the theme
|
|
35404
|
+
// mutated). Track the last hex we synced for so we don't fight
|
|
35405
|
+
// the user's manual tab clicks — without this guard, every
|
|
35406
|
+
// re-render rebuilds `nearest` as a new object reference and the
|
|
35407
|
+
// effect snaps activeFamily back to the family containing the
|
|
35408
|
+
// current color, making it impossible to browse other families.
|
|
35409
|
+
var lastSyncedHexRef = useRef(null);
|
|
35208
35410
|
useEffect(function () {
|
|
35209
|
-
if (!isOpen)
|
|
35411
|
+
if (!isOpen) {
|
|
35412
|
+
lastSyncedHexRef.current = null;
|
|
35413
|
+
return;
|
|
35414
|
+
}
|
|
35415
|
+
if (lastSyncedHexRef.current === selectedHex) return;
|
|
35416
|
+
lastSyncedHexRef.current = selectedHex;
|
|
35210
35417
|
if (nearest) setActiveFamily(nearest.family);
|
|
35211
35418
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
35212
|
-
}, [isOpen, nearest]);
|
|
35419
|
+
}, [isOpen, selectedHex, nearest]);
|
|
35213
35420
|
function expandChannel(channelKey) {
|
|
35214
35421
|
setActiveChannel(channelKey);
|
|
35215
35422
|
setActiveSlot("base");
|
|
@@ -48540,7 +48747,27 @@ var InstalledWidgetDetail = function InstalledWidgetDetail(_ref) {
|
|
|
48540
48747
|
className: "p-2 rounded bg-red-900/30 border border-red-700 text-xs text-red-400",
|
|
48541
48748
|
children: updateError
|
|
48542
48749
|
})
|
|
48543
|
-
}), widget.source !== "builtin" && /*#__PURE__*/jsxs("div", {
|
|
48750
|
+
}), widget.source !== "builtin" && widget.kind === "draft" && /*#__PURE__*/jsxs("div", {
|
|
48751
|
+
className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t ".concat(currentTheme["border-primary-medium"] || "border-white/10"),
|
|
48752
|
+
children: [/*#__PURE__*/jsx(Button, {
|
|
48753
|
+
title: "Resume",
|
|
48754
|
+
onClick: function onClick() {
|
|
48755
|
+
window.dispatchEvent(new CustomEvent("dash:open-widget-builder", {
|
|
48756
|
+
detail: {
|
|
48757
|
+
resumeDraftId: widget.draftId || null
|
|
48758
|
+
}
|
|
48759
|
+
}));
|
|
48760
|
+
},
|
|
48761
|
+
disabled: !widget.draftId,
|
|
48762
|
+
size: "sm"
|
|
48763
|
+
}), /*#__PURE__*/jsx(Button, {
|
|
48764
|
+
title: "Delete",
|
|
48765
|
+
onClick: function onClick() {
|
|
48766
|
+
return onDelete(widget);
|
|
48767
|
+
},
|
|
48768
|
+
size: "sm"
|
|
48769
|
+
})]
|
|
48770
|
+
}), widget.source !== "builtin" && widget.kind !== "draft" && /*#__PURE__*/jsxs("div", {
|
|
48544
48771
|
className: "flex-shrink-0 flex flex-row justify-end gap-2 px-6 py-4 border-t ".concat(currentTheme["border-primary-medium"] || "border-white/10"),
|
|
48545
48772
|
children: [updateInfo && /*#__PURE__*/jsx(Button, {
|
|
48546
48773
|
title: isUpdating ? "Updating..." : "Update Package to v".concat(updateInfo.latestVersion),
|
|
@@ -50007,7 +50234,12 @@ var WidgetsSection = function WidgetsSection(_ref) {
|
|
|
50007
50234
|
className: "flex items-center gap-2",
|
|
50008
50235
|
children: [widget.displayName || widget.name, widget.source === "builtin" && /*#__PURE__*/jsx(Tag3, {
|
|
50009
50236
|
text: "Built-in"
|
|
50010
|
-
}),
|
|
50237
|
+
}), widget.kind === "draft" && /*#__PURE__*/jsx("span", {
|
|
50238
|
+
className: "px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-amber-900/40 text-amber-200 border border-amber-700/30",
|
|
50239
|
+
"data-testid": "widget-draft-chip-".concat(widget.name),
|
|
50240
|
+
title: "In-progress widget \u2014 open to Resume or Delete from the action menu",
|
|
50241
|
+
children: "Draft"
|
|
50242
|
+
}), widget.kind !== "draft" && updates.has(widget.name) && /*#__PURE__*/jsx("span", {
|
|
50011
50243
|
className: "text-[10px] text-blue-400 font-medium",
|
|
50012
50244
|
"data-testid": "widget-update-badge-".concat(widget.name),
|
|
50013
50245
|
children: "Update"
|