@omerdlw/base-framework 1.0.4 → 1.0.6

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
@@ -7733,13 +7733,18 @@ init_theme();
7733
7733
  // src/modules/ambient/color.ts
7734
7734
  var COLOR_EXTRACT_CONFIG = Object.freeze({
7735
7735
  blackChromaFactor: 0.35,
7736
- primaryLightness: 0.74,
7737
- maxBlackChroma: 0.055,
7738
7736
  blackLightness: 0.15,
7739
7737
  cacheLimit: 100,
7738
+ chromaGain: 9.4,
7739
+ hueBins: 36,
7740
+ maxBlackChroma: 0.055,
7740
7741
  maxChroma: 0.28,
7741
- minChroma: 0.03,
7742
- sampleSize: 32
7742
+ maxPrimaryChroma: 0.24,
7743
+ minPixelChroma: 0.03,
7744
+ minPresence: 0.04,
7745
+ neutralChroma: 0.012,
7746
+ primaryLightness: 0.74,
7747
+ sampleSize: 64
7743
7748
  });
7744
7749
  function srgbToLinear(c) {
7745
7750
  const v = c / 255;
@@ -7776,100 +7781,104 @@ function oklchToString(l, c, h, alpha = 1) {
7776
7781
  }
7777
7782
  return `oklch(${safeL} ${safeC} ${safeH})`;
7778
7783
  }
7784
+ function clamp2(value, min, max) {
7785
+ return Math.max(min, Math.min(max, value));
7786
+ }
7779
7787
  function derivePalette(sampled) {
7780
7788
  const {
7781
7789
  blackChromaFactor,
7782
7790
  blackLightness,
7791
+ chromaGain,
7783
7792
  maxBlackChroma,
7784
7793
  maxChroma,
7785
- minChroma,
7794
+ maxPrimaryChroma,
7795
+ neutralChroma,
7786
7796
  primaryLightness
7787
7797
  } = COLOR_EXTRACT_CONFIG;
7788
- const chroma = Math.max(minChroma, Math.min(maxChroma, sampled.c));
7789
- const blackChroma = Math.min(
7790
- maxBlackChroma,
7791
- Math.max(0.025, chroma * blackChromaFactor)
7792
- );
7793
- const primaryChroma = Math.max(
7794
- 0.15,
7795
- Math.min(0.24, Math.max(chroma * 1.15, 0.18))
7796
- );
7798
+ const chroma = sampled.c < neutralChroma ? 0 : clamp2(sampled.c, 0, maxChroma);
7799
+ const hue = chroma === 0 ? 0 : sampled.h;
7800
+ const primaryChroma = maxPrimaryChroma * (1 - Math.exp(-chroma * chromaGain));
7801
+ const primaryL = clamp2(
7802
+ primaryLightness + (sampled.l - 0.6) * 0.5,
7803
+ 0.6,
7804
+ 0.86
7805
+ );
7806
+ const blackChroma = Math.min(maxBlackChroma, chroma * blackChromaFactor);
7807
+ const blackL = clamp2(blackLightness + (sampled.l - 0.6) * 0.06, 0.12, 0.18);
7797
7808
  return {
7798
- black: oklchToString(blackLightness, blackChroma, sampled.h),
7799
- primary: oklchToString(primaryLightness, primaryChroma, sampled.h)
7809
+ black: oklchToString(blackL, blackChroma, hue),
7810
+ primary: oklchToString(primaryL, primaryChroma, hue)
7800
7811
  };
7801
7812
  }
7802
7813
 
7803
7814
  // src/modules/ambient/extractor.ts
7804
7815
  function sampleImageData(imageData) {
7816
+ const { hueBins, minPixelChroma, minPresence } = COLOR_EXTRACT_CONFIG;
7805
7817
  const data = imageData.data;
7806
- const len = data.length;
7807
- const numBins = 24;
7808
- const binAngle = 360 / numBins;
7809
- const bins = Array.from({ length: numBins }, () => ({
7810
- count: 0,
7818
+ const binAngle = 360 / hueBins;
7819
+ const bins = Array.from({ length: hueBins }, () => ({
7820
+ cos: 0,
7821
+ sin: 0,
7811
7822
  sumC: 0,
7812
- sumCos: 0,
7813
7823
  sumL: 0,
7814
- sumSin: 0
7824
+ weight: 0
7815
7825
  }));
7816
- let neutralCount = 0;
7817
- let neutralSumL = 0;
7826
+ let opaqueCount = 0;
7827
+ let opaqueSumL = 0;
7818
7828
  let chromaticCount = 0;
7819
- for (let i = 0; i < len; i += 4) {
7820
- const alpha = data[i + 3];
7821
- if (alpha < 128) continue;
7822
- const r = data[i];
7823
- const g = data[i + 1];
7824
- const b = data[i + 2];
7825
- const oklch = rgbToOklch(r, g, b);
7826
- if (oklch.l < 0.04 || oklch.l > 0.96 || oklch.c < 0.02) {
7827
- neutralCount++;
7828
- neutralSumL += oklch.l;
7829
+ let midNeutralCount = 0;
7830
+ for (let i = 0; i < data.length; i += 4) {
7831
+ if (data[i + 3] < 128) continue;
7832
+ const { c, h, l } = rgbToOklch(data[i], data[i + 1], data[i + 2]);
7833
+ opaqueCount++;
7834
+ opaqueSumL += l;
7835
+ if (l < 0.06 || l > 0.96) continue;
7836
+ if (c < minPixelChroma) {
7837
+ midNeutralCount++;
7829
7838
  continue;
7830
7839
  }
7831
- const binIndex = Math.floor(oklch.h / binAngle) % numBins;
7832
- const rad = oklch.h * (Math.PI / 180);
7833
- const bin = bins[binIndex];
7834
- bin.count++;
7835
- bin.sumL += oklch.l;
7836
- bin.sumC += oklch.c;
7837
- bin.sumCos += Math.cos(rad);
7838
- bin.sumSin += Math.sin(rad);
7840
+ const usable = 1 - 0.7 * Math.min(1, Math.abs(l - 0.62) / 0.62);
7841
+ const weight2 = c * c * usable;
7842
+ const rad = h * (Math.PI / 180);
7843
+ const bin = bins[Math.floor(h / binAngle) % hueBins];
7844
+ bin.weight += weight2;
7845
+ bin.sumC += c * weight2;
7846
+ bin.sumL += l * weight2;
7847
+ bin.cos += Math.cos(rad) * weight2;
7848
+ bin.sin += Math.sin(rad) * weight2;
7839
7849
  chromaticCount++;
7840
7850
  }
7841
- if (chromaticCount === 0) {
7842
- const avgL2 = neutralCount > 0 ? neutralSumL / neutralCount : 0.55;
7843
- return { c: 0.03, h: 252, l: avgL2 };
7844
- }
7851
+ const averageL = opaqueCount > 0 ? opaqueSumL / opaqueCount : 0.5;
7852
+ const neutral = { c: 0, h: 0, l: Number(averageL.toFixed(3)) };
7853
+ const presence = chromaticCount / Math.max(1, chromaticCount + midNeutralCount);
7854
+ if (chromaticCount === 0 || presence < minPresence) return neutral;
7845
7855
  let bestIndex = 0;
7846
- let maxWindowCount = -1;
7847
- for (let i = 0; i < numBins; i++) {
7848
- const prev2 = bins[(i - 1 + numBins) % numBins];
7849
- const curr2 = bins[i];
7850
- const next2 = bins[(i + 1) % numBins];
7851
- const windowCount = prev2.count * 0.5 + curr2.count + next2.count * 0.5;
7852
- if (windowCount > maxWindowCount) {
7853
- maxWindowCount = windowCount;
7856
+ let bestScore = -1;
7857
+ for (let i = 0; i < hueBins; i++) {
7858
+ const prev = bins[(i - 1 + hueBins) % hueBins];
7859
+ const next = bins[(i + 1) % hueBins];
7860
+ const score = prev.weight * 0.5 + bins[i].weight + next.weight * 0.5;
7861
+ if (score > bestScore) {
7862
+ bestScore = score;
7854
7863
  bestIndex = i;
7855
7864
  }
7856
7865
  }
7857
- const prev = bins[(bestIndex - 1 + numBins) % numBins];
7858
- const curr = bins[bestIndex];
7859
- const next = bins[(bestIndex + 1) % numBins];
7860
- const totalCount = prev.count + curr.count + next.count;
7861
- if (totalCount === 0) {
7862
- return { c: 0.19, h: 252, l: 0.55 };
7863
- }
7864
- const avgL = (prev.sumL + curr.sumL + next.sumL) / totalCount;
7865
- const avgC = (prev.sumC + curr.sumC + next.sumC) / totalCount;
7866
- const avgSin = prev.sumSin + curr.sumSin + next.sumSin;
7867
- const avgCos = prev.sumCos + curr.sumCos + next.sumCos;
7868
- const avgH = (Math.atan2(avgSin, avgCos) * (180 / Math.PI) + 360) % 360;
7866
+ const window2 = [
7867
+ bins[(bestIndex - 1 + hueBins) % hueBins],
7868
+ bins[bestIndex],
7869
+ bins[(bestIndex + 1) % hueBins]
7870
+ ];
7871
+ const weight = window2.reduce((sum, bin) => sum + bin.weight, 0);
7872
+ if (weight === 0) return neutral;
7873
+ const sumC = window2.reduce((sum, bin) => sum + bin.sumC, 0);
7874
+ const sumL = window2.reduce((sum, bin) => sum + bin.sumL, 0);
7875
+ const sin = window2.reduce((sum, bin) => sum + bin.sin, 0);
7876
+ const cos = window2.reduce((sum, bin) => sum + bin.cos, 0);
7877
+ const dilution = 0.45 + 0.55 * Math.min(1, presence / 0.3);
7869
7878
  return {
7870
- c: Number(avgC.toFixed(3)),
7871
- h: Number(avgH.toFixed(1)),
7872
- l: Number(avgL.toFixed(3))
7879
+ c: Number((sumC / weight * dilution).toFixed(3)),
7880
+ h: Number(((Math.atan2(sin, cos) * (180 / Math.PI) + 360) % 360).toFixed(1)),
7881
+ l: Number((sumL / weight).toFixed(3))
7873
7882
  };
7874
7883
  }
7875
7884
  function createDefaultPalette(fallback) {
@@ -8618,6 +8627,7 @@ init_utils();
8618
8627
  init_atoms();
8619
8628
 
8620
8629
  // src/modules/dock/surface/context.tsx
8630
+ init_kernel();
8621
8631
  init_utils();
8622
8632
 
8623
8633
  // src/modules/dock/surface/helpers.ts
@@ -8749,7 +8759,7 @@ function normalizeSurfaceExtension(input) {
8749
8759
  if (typeof input !== "object") return null;
8750
8760
  const extension = input;
8751
8761
  const component = isValidComponentType(extension.component) ? extension.component : null;
8752
- const content = isValidElement(extension.content) || typeof extension.content === "string" || typeof extension.content === "number" ? extension.content : null;
8762
+ const content = isValidElement(extension.content) || typeof extension.content === "string" && extension.content !== "" || typeof extension.content === "number" ? extension.content : null;
8753
8763
  if (!component && content == null) return null;
8754
8764
  const align = extension.align === "right" || extension.align === "end" ? "right" : extension.align === "center" ? "center" : "left";
8755
8765
  return {
@@ -8794,8 +8804,8 @@ function resolveSurfaceFlowReturnHandshake(definition, input) {
8794
8804
  }
8795
8805
 
8796
8806
  // src/modules/dock/surface/context.tsx
8797
- var SurfaceExtensionsContext = createContext(null);
8798
- var SurfaceItemContext = createContext({
8807
+ var SurfaceExtensionsContext = getOrCreateGlobalContext("SurfaceExtensionsContext", null);
8808
+ var SurfaceItemContext = getOrCreateGlobalContext("SurfaceItemContext", {
8799
8809
  id: null,
8800
8810
  width: null
8801
8811
  });
@@ -8809,12 +8819,12 @@ var SurfaceHeaderActionStore = class {
8809
8819
  }
8810
8820
  subscribe = (listener) => this.store.subscribe(listener);
8811
8821
  getAction = (surfaceId) => {
8812
- const sId = surfaceId != null ? String(surfaceId) : "global";
8822
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8813
8823
  const { actionsBySurface } = this.store.getSnapshot();
8814
- return actionsBySurface[sId] ?? actionsBySurface.global ?? null;
8824
+ return actionsBySurface[sId] ?? actionsBySurface.active ?? actionsBySurface.global ?? null;
8815
8825
  };
8816
8826
  setAction = (surfaceId, action) => {
8817
- const sId = surfaceId != null ? String(surfaceId) : "global";
8827
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8818
8828
  const current = this.store.getSnapshot();
8819
8829
  if (current.actionsBySurface[sId] === action) return;
8820
8830
  this.store.setState({
@@ -8826,7 +8836,7 @@ var SurfaceHeaderActionStore = class {
8826
8836
  });
8827
8837
  };
8828
8838
  removeAction = (surfaceId) => {
8829
- const sId = surfaceId != null ? String(surfaceId) : "global";
8839
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8830
8840
  const current = this.store.getSnapshot();
8831
8841
  if (!(sId in current.actionsBySurface)) return;
8832
8842
  const { [sId]: _, ...nextActions } = current.actionsBySurface;
@@ -8850,17 +8860,32 @@ var SurfaceExtensionsStore = class {
8850
8860
  this.store.setState((prev) => ({ version: prev.version + 1 }));
8851
8861
  };
8852
8862
  getExtensionsForSurface = (surfaceId) => {
8853
- const sId = surfaceId != null ? String(surfaceId) : "global";
8863
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8854
8864
  if (this.cachedListBySurface.has(sId))
8855
8865
  return this.cachedListBySurface.get(sId);
8856
8866
  const globalExts = this.extensionsBySurface.get("global");
8857
- const surfaceExts = this.extensionsBySurface.get(sId);
8858
- if (!globalExts && !surfaceExts) {
8867
+ const activeExts = this.extensionsBySurface.get("active");
8868
+ const surfaceExts = sId !== "global" && sId !== "active" ? this.extensionsBySurface.get(sId) : void 0;
8869
+ let fallbackExts;
8870
+ if (!globalExts && !activeExts && !surfaceExts && this.extensionsBySurface.size > 0) {
8871
+ for (const map2 of this.extensionsBySurface.values()) {
8872
+ if (map2.size > 0) {
8873
+ fallbackExts = map2;
8874
+ break;
8875
+ }
8876
+ }
8877
+ }
8878
+ if (!globalExts && !activeExts && !surfaceExts && !fallbackExts) {
8859
8879
  const empty = [];
8860
8880
  this.cachedListBySurface.set(sId, empty);
8861
8881
  return empty;
8862
8882
  }
8863
- const merged = new Map([...globalExts || [], ...surfaceExts || []]);
8883
+ const merged = new Map([
8884
+ ...globalExts || [],
8885
+ ...activeExts || [],
8886
+ ...surfaceExts || [],
8887
+ ...fallbackExts || []
8888
+ ]);
8864
8889
  const result = Array.from(merged.values()).sort(
8865
8890
  (a, b) => a.order - b.order
8866
8891
  );
@@ -8871,7 +8896,7 @@ var SurfaceExtensionsStore = class {
8871
8896
  if (!extension) return;
8872
8897
  const normalized = normalizeSurfaceExtension(extension);
8873
8898
  if (!normalized) return;
8874
- const sId = surfaceId != null ? String(surfaceId) : "global";
8899
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8875
8900
  let surfaceMap = this.extensionsBySurface.get(sId);
8876
8901
  if (!surfaceMap) {
8877
8902
  surfaceMap = /* @__PURE__ */ new Map();
@@ -8885,17 +8910,23 @@ var SurfaceExtensionsStore = class {
8885
8910
  };
8886
8911
  removeExtension = (surfaceId, extensionId) => {
8887
8912
  if (!extensionId) return;
8888
- const sId = surfaceId != null ? String(surfaceId) : "global";
8889
- const surfaceMap = this.extensionsBySurface.get(sId);
8890
- if (!surfaceMap || !surfaceMap.has(extensionId)) return;
8891
- surfaceMap.delete(extensionId);
8892
- if (surfaceMap.size === 0) this.extensionsBySurface.delete(sId);
8893
- this.notify();
8913
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8914
+ let removed = false;
8915
+ for (const [key, map2] of this.extensionsBySurface.entries()) {
8916
+ if (key === sId || key === "active" || key === "global") {
8917
+ if (map2.has(extensionId)) {
8918
+ map2.delete(extensionId);
8919
+ if (map2.size === 0) this.extensionsBySurface.delete(key);
8920
+ removed = true;
8921
+ }
8922
+ }
8923
+ }
8924
+ if (removed) this.notify();
8894
8925
  };
8895
8926
  clearSurface = (surfaceId) => {
8896
- const sId = surfaceId != null ? String(surfaceId) : "global";
8897
- if (!this.extensionsBySurface.has(sId)) return;
8927
+ const sId = surfaceId != null ? String(surfaceId) : "active";
8898
8928
  this.extensionsBySurface.delete(sId);
8929
+ this.extensionsBySurface.delete("active");
8899
8930
  this.notify();
8900
8931
  };
8901
8932
  };
@@ -11626,7 +11657,7 @@ function useDockSurfaceControlsModel({
11626
11657
  const phase = propSurfacePhase ?? activeItem?.surfacePhase;
11627
11658
  const isBodyVisible = phase ? phase === DOCK_SURFACE_PHASE.EXPANDING_BODY || phase === DOCK_SURFACE_PHASE.OPEN : true;
11628
11659
  const actionStore = use(SurfaceExtensionsContext)?.headerActions ?? null;
11629
- const surfaceId = activeItem?.surfaceId || "global";
11660
+ const surfaceId = activeItem?.surfaceId || "active";
11630
11661
  const subscribeAction = useCallback(
11631
11662
  (onStoreChange) => actionStore ? actionStore.subscribe(onStoreChange) : () => {
11632
11663
  },
@@ -11654,7 +11685,7 @@ function SurfaceExtensionsProvider({
11654
11685
  }
11655
11686
  function useIsSurfaceExtensionsVisible(activeItem) {
11656
11687
  const store = use(SurfaceExtensionsContext)?.extensions ?? null;
11657
- const surfaceId = activeItem?.surfaceId || "global";
11688
+ const surfaceId = activeItem?.surfaceId || "active";
11658
11689
  const isSurface = Boolean(activeItem?.isSurface);
11659
11690
  const phase = activeItem?.surfacePhase;
11660
11691
  const isBodyVisible = phase === DOCK_SURFACE_PHASE.EXPANDING_BODY || phase === DOCK_SURFACE_PHASE.OPEN;
@@ -11673,14 +11704,14 @@ function useIsSurfaceExtensionsVisible(activeItem) {
11673
11704
  return Array.isArray(raw) ? raw.length : 0;
11674
11705
  }, [activeItem?.surfaceExtensions, activeItem?.extensions]);
11675
11706
  return Boolean(
11676
- isSurface && isBodyVisible && (dynamicCount > 0 || descriptorCount > 0)
11707
+ isSurface && (isBodyVisible && dynamicCount > 0 || descriptorCount > 0)
11677
11708
  );
11678
11709
  }
11679
11710
  function useDockSurfaceExtensionsBarModel({
11680
11711
  activeItem
11681
11712
  }) {
11682
11713
  const store = use(SurfaceExtensionsContext)?.extensions ?? null;
11683
- const surfaceId = activeItem?.surfaceId || "global";
11714
+ const surfaceId = activeItem?.surfaceId || "active";
11684
11715
  const subscribe2 = useCallback(
11685
11716
  (onStoreChange) => store ? store.subscribe(onStoreChange) : () => {
11686
11717
  },