@likec4/diagram 1.8.1 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import { LikeC4CustomColorsProperties } from './LikeC4CustomColors.props';
2
+
3
+ export declare function LikeC4CustomColors({ customColors }: LikeC4CustomColorsProperties): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { CustomColorDefinitions } from '@likec4/core';
2
+
3
+ export interface LikeC4CustomColorsProperties {
4
+ customColors: CustomColorDefinitions;
5
+ }
@@ -2,3 +2,6 @@ import { LikeC4DiagramEventHandlers, LikeC4DiagramProperties } from './LikeC4Dia
2
2
 
3
3
  export type LikeC4DiagramProps = LikeC4DiagramProperties & LikeC4DiagramEventHandlers;
4
4
  export declare function LikeC4Diagram({ view, className, fitView, fitViewPadding, readonly, pannable, zoomable, nodesSelectable, nodesDraggable, background, controls, showElementLinks, showDiagramTitle, showNotations, enableDynamicViewWalkthrough, enableFocusMode, initialWidth, initialHeight, keepAspectRatio, experimentalEdgeEditing, onCanvasClick, onCanvasContextMenu, onCanvasDblClick, onEdgeClick, onChange, onEdgeContextMenu, onNavigateTo, onNodeClick, onNodeContextMenu, onOpenSourceElement, onOpenSourceView, onOpenSourceRelation, onBurgerMenuClick, renderIcon, where, showNavigationButtons }: LikeC4DiagramProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare namespace LikeC4Diagram {
6
+ var displayName: string;
7
+ }
@@ -1,39 +1,9 @@
1
- import { DiagramEdge, DiagramNode, DiagramView, Fqn, NonEmptyArray, RelationID, ViewChange, ViewID } from '@likec4/core';
1
+ import { DiagramEdge, DiagramNode, DiagramView, Fqn, RelationID, ViewChange, ViewID, WhereOperator } from '@likec4/core';
2
2
  import { MouseEvent as ReactMouseEvent, ReactNode } from 'react';
3
3
  import { XYFlowEdge, XYFlowNode } from './xyflow/types';
4
4
  import { XYBackground } from './xyflow/XYFlowBackground';
5
5
 
6
- type EqualOperator<V> = {
7
- eq: V;
8
- neq?: never;
9
- } | {
10
- eq?: never;
11
- neq: V;
12
- };
13
- type AllNever = {
14
- not?: never;
15
- and?: never;
16
- or?: never;
17
- tag?: never;
18
- kind?: never;
19
- };
20
- type TagKindOperator<Tag, Kind> = Omit<AllNever, 'tag' | 'kind'> & ({
21
- tag: EqualOperator<Tag>;
22
- kind?: never;
23
- } | {
24
- tag?: never;
25
- kind: EqualOperator<Kind>;
26
- });
27
- type NotOperator<Tag, Kind> = Omit<AllNever, 'not'> & {
28
- not: TagKindOperator<Tag, Kind> | AndOperator<Tag, Kind> | OrOperator<Tag, Kind>;
29
- };
30
- type AndOperator<Tag, Kind> = Omit<AllNever, 'and'> & {
31
- and: NonEmptyArray<TagKindOperator<Tag, Kind> | OrOperator<Tag, Kind> | NotOperator<Tag, Kind>>;
32
- };
33
- type OrOperator<Tag, Kind> = Omit<AllNever, 'or'> & {
34
- or: NonEmptyArray<TagKindOperator<Tag, Kind> | AndOperator<Tag, Kind> | NotOperator<Tag, Kind>>;
35
- };
36
- export type WhereOperator<Tag extends string, Kind extends string> = TagKindOperator<Tag, Kind> | NotOperator<Tag, Kind> | AndOperator<Tag, Kind> | OrOperator<Tag, Kind>;
6
+ export type { WhereOperator };
37
7
  export type DiagramNodeWithNavigate = Omit<DiagramNode, 'navigateTo'> & {
38
8
  navigateTo: ViewID;
39
9
  };
@@ -182,4 +152,3 @@ export interface LikeC4DiagramEventHandlers {
182
152
  onOpenSourceElement?: null | undefined | ((fqn: Fqn) => void);
183
153
  onOpenSourceRelation?: null | undefined | ((id: RelationID) => void);
184
154
  }
185
- export {};
package/dist/index.mjs CHANGED
@@ -724,6 +724,7 @@ function DiagramContextProvider({
724
724
  }
725
725
  );
726
726
  }
727
+ DiagramContextProvider.displayName = "DiagramContextProvider";
727
728
  function useDiagramState(selector2, equalityFn) {
728
729
  const store = useContext(DiagramContext);
729
730
  if (store === null)
@@ -736,12 +737,35 @@ function useDiagramStoreApi() {
736
737
  throw new Error("useDiagramStoreApi could be used only inside DiagramContext");
737
738
  return store;
738
739
  }
740
+ var vars = { safariAnimationHook: "var(--likec4-safari-animation-hook)", default: { font: "var(--likec4-default-font-family)" }, likec4: { font: "var(--likec4-font-family)", background: { color: "var(--likec4-background-color)", pattern: { color: "var(--likec4-background-pattern-color)" } } }, compound: { font: "var(--likec4-compound-font-family)", titleColor: "var(--likec4-compound-title-color)" }, element: { font: "var(--likec4-element-font-family)", fill: "var(--likec4-element-fill)", stroke: "var(--likec4-element-stroke)", hiContrast: "var(--likec4-element-hiContrast)", loContrast: "var(--likec4-element-loContrast)" }, relation: { lineColor: "var(--likec4-relation-lineColor)", labelColor: "var(--likec4-relation-labelColor)", labelBgColor: "var(--likec4-relation-labelBg)" }, optionsPanel: { top: "var(--likec4-options-panel-top)", right: "var(--likec4-options-panel-right)" }, navigationPanel: { top: "var(--likec4-navigation-panel-top)", left: "var(--likec4-navigation-panel-left)" } };
741
+ function LikeC4CustomColors({ customColors }) {
742
+ function toStyle(name, colorValues) {
743
+ const rules = new Array(
744
+ ...entries(colorValues.elements).map(([key, value]) => `${stripCssVarReference(vars.element[key])}: ${value};`),
745
+ ...entries(colorValues.relationships).map(
746
+ ([key, value]) => `${stripCssVarReference(vars.relation[key])}: ${value};`
747
+ )
748
+ ).join(`
749
+ `);
750
+ return `:where([data-likec4-color=${name}]) {
751
+ ${rules}
752
+ }`;
753
+ }
754
+ function stripCssVarReference(ref) {
755
+ const end = ref.indexOf(",");
756
+ return ref.substring(4, end == -1 ? ref.length - 1 : end);
757
+ }
758
+ const styles = entries(customColors).map(([name, color]) => toStyle(name, color)).join(`
759
+ `);
760
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("style", { type: "text/css", dangerouslySetInnerHTML: { __html: styles } }) });
761
+ }
739
762
  var cssReactFlow = "_2h8g8h0", cssDisablePan = "_2h8g8h1", cssTransparentBg = "_2h8g8h2", cssNoControls = "_2h8g8h3";
740
763
  function EnsureMantine({ children }) {
741
764
  if (!useContext(MantineContext))
742
765
  throw new Error("LikeC4Diagram must be a child of MantineProvider");
743
766
  return /* @__PURE__ */ jsx(Fragment, { children });
744
767
  }
768
+ EnsureMantine.displayName = "EnsureMantine";
745
769
  function selectXYFlowSize(state) {
746
770
  return `${Math.round(state.width)}:${Math.round(state.height)}`;
747
771
  }
@@ -2335,6 +2359,7 @@ function XYFlow({
2335
2359
  }
2336
2360
  );
2337
2361
  }
2362
+ XYFlow.displayName = "XYFlow";
2338
2363
  var container$2 = "hbkbtj0", card$1 = "hbkbtj1", title = "hbkbtj2", description = "hbkbtj3";
2339
2364
  const selector$1 = (s) => ({
2340
2365
  id: s.view.id,
@@ -2592,7 +2617,7 @@ function DynamicViewWalkthrough() {
2592
2617
  }
2593
2618
  );
2594
2619
  }
2595
- var vars = { safariAnimationHook: "var(--likec4-safari-animation-hook)", default: { font: "var(--likec4-default-font-family)" }, likec4: { font: "var(--likec4-font-family)", background: { color: "var(--likec4-background-color)", pattern: { color: "var(--likec4-background-pattern-color)" } } }, compound: { font: "var(--likec4-compound-font-family)", titleColor: "var(--likec4-compound-title-color)" }, element: { font: "var(--likec4-element-font-family)", fill: "var(--likec4-element-fill)", stroke: "var(--likec4-element-stroke)", hiContrast: "var(--likec4-element-hiContrast)", loContrast: "var(--likec4-element-loContrast)" }, relation: { lineColor: "var(--likec4-relation-lineColor)", labelColor: "var(--likec4-relation-labelColor)", labelBgColor: "var(--likec4-relation-labelBg)" }, optionsPanel: { top: "var(--likec4-options-panel-top)", right: "var(--likec4-options-panel-right)" }, navigationPanel: { top: "var(--likec4-navigation-panel-top)", left: "var(--likec4-navigation-panel-left)" } }, container = "_1ncdyfa0", card = "_1ncdyfa1", tabPanel = "_1ncdyfa2", elementNotation = "_1ncdyfa3", shapeSvg = "_1ncdyfa4", shapeBadge = "_1ncdyfa5";
2620
+ var container = "_1ncdyfa0", card = "_1ncdyfa1", tabPanel = "_1ncdyfa2", elementNotation = "_1ncdyfa3", shapeSvg = "_1ncdyfa4", shapeBadge = "_1ncdyfa5";
2596
2621
  const ElementNotation = ({ value }) => {
2597
2622
  const {
2598
2623
  title: title2,
@@ -2707,7 +2732,7 @@ function NotationPanel() {
2707
2732
  defaultValue: !0
2708
2733
  }), hasNotations = notations.length > 0, portalProps = target ? { portalProps: { target } } : { withinPortal: !1 };
2709
2734
  return /* @__PURE__ */ jsxs(AnimatePresence, { children: [
2710
- !hasNotations && /* @__PURE__ */ jsx(
2735
+ !hasNotations && isVisible && /* @__PURE__ */ jsx(
2711
2736
  m.div,
2712
2737
  {
2713
2738
  initial: { opacity: 0.75, translateX: "50%" },
@@ -2717,7 +2742,7 @@ function NotationPanel() {
2717
2742
  opacity: 0.6
2718
2743
  },
2719
2744
  className: clsx("react-flow__panel", container),
2720
- children: /* @__PURE__ */ jsx(Tooltip$2, { label: "Diagram has no notations", color: "orange", ...portalProps, children: /* @__PURE__ */ jsx(
2745
+ children: /* @__PURE__ */ jsx(Tooltip$2, { label: "View has no notations", color: "orange", ...portalProps, children: /* @__PURE__ */ jsx(
2721
2746
  ThemeIcon,
2722
2747
  {
2723
2748
  size: "xl",
@@ -3518,58 +3543,62 @@ function LikeC4Diagram({
3518
3543
  initialWidth: initialWidth ?? view.bounds.width,
3519
3544
  initialHeight: initialHeight ?? view.bounds.height
3520
3545
  });
3521
- return readonly !== !0 && where && console.warn("where filter is only supported in readonly mode"), /* @__PURE__ */ jsx(EnsureMantine, { children: /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, strict: !0, children: /* @__PURE__ */ jsx(
3546
+ return readonly !== !0 && where && console.warn("where filter is only supported in readonly mode"), /* @__PURE__ */ jsx(EnsureMantine, { children: /* @__PURE__ */ jsx(LazyMotion, { features: domAnimation, strict: !0, children: /* @__PURE__ */ jsxs(
3522
3547
  ReactFlowProvider,
3523
3548
  {
3524
3549
  fitView,
3525
3550
  ...initialRef.current,
3526
- children: /* @__PURE__ */ jsx(
3527
- DiagramContextProvider,
3528
- {
3529
- view,
3530
- keepAspectRatio,
3531
- className: clsx(rootClassName, className),
3532
- readonly,
3533
- pannable,
3534
- zoomable,
3535
- fitViewEnabled: fitView,
3536
- fitViewPadding,
3537
- showElementLinks,
3538
- showNavigationButtons,
3539
- showNotations,
3540
- nodesDraggable,
3541
- nodesSelectable,
3542
- experimentalEdgeEditing,
3543
- enableDynamicViewWalkthrough,
3544
- enableFocusMode,
3545
- whereFilter: where ?? null,
3546
- renderIcon: renderIcon ?? null,
3547
- onCanvasClick: onCanvasClick ?? null,
3548
- onCanvasContextMenu: onCanvasContextMenu ?? null,
3549
- onEdgeClick: onEdgeClick ?? null,
3550
- onEdgeContextMenu: onEdgeContextMenu ?? null,
3551
- onNodeClick: onNodeClick ?? null,
3552
- onNodeContextMenu: onNodeContextMenu ?? null,
3553
- onChange: onChange ?? null,
3554
- onNavigateTo: onNavigateTo ?? null,
3555
- onCanvasDblClick: onCanvasDblClick ?? null,
3556
- onOpenSourceView: onOpenSourceView ?? null,
3557
- onOpenSourceElement: onOpenSourceElement ?? null,
3558
- onOpenSourceRelation: onOpenSourceRelation ?? null,
3559
- onBurgerMenuClick: onBurgerMenuClick ?? null,
3560
- children: /* @__PURE__ */ jsx(
3561
- LikeC4DiagramInnerMemo,
3562
- {
3563
- controls,
3564
- background,
3565
- showDiagramTitle
3566
- }
3567
- )
3568
- }
3569
- )
3551
+ children: [
3552
+ customColorsDefined(view) && /* @__PURE__ */ jsx(LikeC4CustomColors, { customColors: view.customColorDefinitions }),
3553
+ /* @__PURE__ */ jsx(
3554
+ DiagramContextProvider,
3555
+ {
3556
+ view,
3557
+ keepAspectRatio,
3558
+ className: clsx(rootClassName, className),
3559
+ readonly,
3560
+ pannable,
3561
+ zoomable,
3562
+ fitViewEnabled: fitView,
3563
+ fitViewPadding,
3564
+ showElementLinks,
3565
+ showNavigationButtons,
3566
+ showNotations,
3567
+ nodesDraggable,
3568
+ nodesSelectable,
3569
+ experimentalEdgeEditing,
3570
+ enableDynamicViewWalkthrough,
3571
+ enableFocusMode,
3572
+ whereFilter: where ?? null,
3573
+ renderIcon: renderIcon ?? null,
3574
+ onCanvasClick: onCanvasClick ?? null,
3575
+ onCanvasContextMenu: onCanvasContextMenu ?? null,
3576
+ onEdgeClick: onEdgeClick ?? null,
3577
+ onEdgeContextMenu: onEdgeContextMenu ?? null,
3578
+ onNodeClick: onNodeClick ?? null,
3579
+ onNodeContextMenu: onNodeContextMenu ?? null,
3580
+ onChange: onChange ?? null,
3581
+ onNavigateTo: onNavigateTo ?? null,
3582
+ onCanvasDblClick: onCanvasDblClick ?? null,
3583
+ onOpenSourceView: onOpenSourceView ?? null,
3584
+ onOpenSourceElement: onOpenSourceElement ?? null,
3585
+ onOpenSourceRelation: onOpenSourceRelation ?? null,
3586
+ onBurgerMenuClick: onBurgerMenuClick ?? null,
3587
+ children: /* @__PURE__ */ jsx(
3588
+ LikeC4DiagramInnerMemo,
3589
+ {
3590
+ controls,
3591
+ background,
3592
+ showDiagramTitle
3593
+ }
3594
+ )
3595
+ }
3596
+ )
3597
+ ]
3570
3598
  }
3571
3599
  ) }) });
3572
3600
  }
3601
+ LikeC4Diagram.displayName = "LikeC4Diagram";
3573
3602
  const LikeC4DiagramInnerMemo = memo(function({
3574
3603
  background,
3575
3604
  controls,
@@ -3614,6 +3643,10 @@ const LikeC4DiagramInnerMemo = memo(function({
3614
3643
  ] })
3615
3644
  ] });
3616
3645
  }, shallowEqual);
3646
+ LikeC4DiagramInnerMemo.displayName = "LikeC4DiagramInnerMemo";
3647
+ function customColorsDefined(view) {
3648
+ return Object.keys(view.customColorDefinitions).length > 0;
3649
+ }
3617
3650
  function StaticLikeC4Diagram({
3618
3651
  view,
3619
3652
  fitView = !0,
@@ -2,4 +2,7 @@ import { PropsWithChildren } from 'react';
2
2
 
3
3
  type EnsureMantineProps = PropsWithChildren<{}>;
4
4
  export declare function EnsureMantine({ children }: EnsureMantineProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare namespace EnsureMantine {
6
+ var displayName: string;
7
+ }
5
8
  export {};
@@ -16,7 +16,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
16
16
  experimentalEdgeEditing: boolean;
17
17
  enableFocusMode: boolean;
18
18
  renderIcon: import('..').ElementIconRenderer | null;
19
- whereFilter: import('..').WhereOperator<string, string> | null;
19
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
20
20
  enableDynamicViewWalkthrough: boolean;
21
21
  xyflow: import('..').XYFlowInstance;
22
22
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -98,7 +98,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
98
98
  experimentalEdgeEditing: boolean;
99
99
  enableFocusMode: boolean;
100
100
  renderIcon: import('..').ElementIconRenderer | null;
101
- whereFilter: import('..').WhereOperator<string, string> | null;
101
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
102
102
  enableDynamicViewWalkthrough: boolean;
103
103
  xyflow: import('..').XYFlowInstance;
104
104
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -234,7 +234,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
234
234
  experimentalEdgeEditing: boolean;
235
235
  enableFocusMode: boolean;
236
236
  renderIcon: import('..').ElementIconRenderer | null;
237
- whereFilter: import('..').WhereOperator<string, string> | null;
237
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
238
238
  enableDynamicViewWalkthrough: boolean;
239
239
  xyflow: import('..').XYFlowInstance;
240
240
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -371,7 +371,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
371
371
  experimentalEdgeEditing: boolean;
372
372
  enableFocusMode: boolean;
373
373
  renderIcon: import('..').ElementIconRenderer | null;
374
- whereFilter: import('..').WhereOperator<string, string> | null;
374
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
375
375
  enableDynamicViewWalkthrough: boolean;
376
376
  xyflow: import('..').XYFlowInstance;
377
377
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -515,7 +515,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
515
515
  experimentalEdgeEditing: boolean;
516
516
  enableFocusMode: boolean;
517
517
  renderIcon: import('..').ElementIconRenderer | null;
518
- whereFilter: import('..').WhereOperator<string, string> | null;
518
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
519
519
  enableDynamicViewWalkthrough: boolean;
520
520
  xyflow: import('..').XYFlowInstance;
521
521
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -651,7 +651,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
651
651
  experimentalEdgeEditing: boolean;
652
652
  enableFocusMode: boolean;
653
653
  renderIcon: import('..').ElementIconRenderer | null;
654
- whereFilter: import('..').WhereOperator<string, string> | null;
654
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
655
655
  enableDynamicViewWalkthrough: boolean;
656
656
  xyflow: import('..').XYFlowInstance;
657
657
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -787,7 +787,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
787
787
  experimentalEdgeEditing: boolean;
788
788
  enableFocusMode: boolean;
789
789
  renderIcon: import('..').ElementIconRenderer | null;
790
- whereFilter: import('..').WhereOperator<string, string> | null;
790
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
791
791
  enableDynamicViewWalkthrough: boolean;
792
792
  xyflow: import('..').XYFlowInstance;
793
793
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -923,7 +923,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
923
923
  experimentalEdgeEditing: boolean;
924
924
  enableFocusMode: boolean;
925
925
  renderIcon: import('..').ElementIconRenderer | null;
926
- whereFilter: import('..').WhereOperator<string, string> | null;
926
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
927
927
  enableDynamicViewWalkthrough: boolean;
928
928
  xyflow: import('..').XYFlowInstance;
929
929
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -1059,7 +1059,7 @@ export declare const DiagramContext: import('react').Context<import('zustand/tra
1059
1059
  experimentalEdgeEditing: boolean;
1060
1060
  enableFocusMode: boolean;
1061
1061
  renderIcon: import('..').ElementIconRenderer | null;
1062
- whereFilter: import('..').WhereOperator<string, string> | null;
1062
+ whereFilter: import('@likec4/core').WhereOperator<string, string> | null;
1063
1063
  enableDynamicViewWalkthrough: boolean;
1064
1064
  xyflow: import('..').XYFlowInstance;
1065
1065
  xystore: import('../hooks/useXYFlow').XYStoreApi;
@@ -1187,3 +1187,6 @@ export type DiagramContextProviderProps = PropsWithChildren<Omit<DiagramInitialS
1187
1187
  keepAspectRatio: boolean;
1188
1188
  }>;
1189
1189
  export declare function DiagramContextProvider({ children, view, className, keepAspectRatio, whereFilter, ...props }: DiagramContextProviderProps): import("react/jsx-runtime").JSX.Element;
1190
+ export declare namespace DiagramContextProvider {
1191
+ var displayName: string;
1192
+ }
@@ -1,4 +1,4 @@
1
- import { DiagramView } from '@likec4/core/types';
1
+ import { DiagramView } from '@likec4/core';
2
2
  import { WhereOperator } from '../LikeC4Diagram.props';
3
3
  import { XYFlowEdge, XYFlowNode } from '../xyflow/types';
4
4
 
@@ -6,4 +6,7 @@ type XYFlowWrapperProps = PropsWithChildren<{
6
6
  style?: CSSProperties | undefined;
7
7
  }>;
8
8
  export declare function XYFlow({ colorMode, className, children, style }: XYFlowWrapperProps): import("react/jsx-runtime").JSX.Element;
9
+ export declare namespace XYFlow {
10
+ var displayName: string;
11
+ }
9
12
  export {};
@@ -1,4 +1,4 @@
1
- import { DiagramEdge, Point } from '@likec4/core/types';
1
+ import { DiagramEdge, Point } from '@likec4/core';
2
2
  import { Rect, XYPosition } from '@xyflow/react';
3
3
  import { InternalXYFlowNode } from './types';
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/diagram",
3
- "version": "1.8.1",
3
+ "version": "1.9.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -48,6 +48,7 @@
48
48
  "clean": "run -T rimraf -v -g 'dist/*' .tsbuildinfo"
49
49
  },
50
50
  "dependencies": {
51
+ "@likec4/core": "1.9.0",
51
52
  "@lume/kiwi": "^0.4.3",
52
53
  "@react-hookz/web": "^24.0.4",
53
54
  "@tabler/icons-react": "^3.14.0",
@@ -62,22 +63,22 @@
62
63
  "esm-env": "^1.0.0",
63
64
  "fast-equals": "^5.0.1",
64
65
  "framer-motion": "^11.3.30",
66
+ "khroma": "^2.1.0",
65
67
  "remeda": "^2.11.0",
68
+ "type-fest": "^4.26.0",
66
69
  "zustand": "^4.5.5"
67
70
  },
68
71
  "peerDependencies": {
69
- "@likec4/core": "1.8.1",
70
72
  "@mantine/core": "^7.11.2",
71
73
  "@mantine/hooks": "^7.11.2",
72
74
  "react": "^18.3.1",
73
75
  "react-dom": "^18.3.1"
74
76
  },
75
77
  "devDependencies": {
76
- "@likec4/core": "1.8.1",
77
- "@likec4/tsconfig": "1.8.1",
78
- "@mantine/core": "7.11.2",
79
- "@mantine/hooks": "7.11.2",
80
- "@mantine/vanilla-extract": "7.11.2",
78
+ "@likec4/tsconfig": "1.9.0",
79
+ "@mantine/core": "7.12.2",
80
+ "@mantine/hooks": "7.12.2",
81
+ "@mantine/vanilla-extract": "7.12.2",
81
82
  "@total-typescript/ts-reset": "^0.5.1",
82
83
  "@types/bezier-js": "^4.1.3",
83
84
  "@types/d3-shape": "^3.1.6",
@@ -86,10 +87,8 @@
86
87
  "@vanilla-extract/esbuild-plugin": "^2.3.10",
87
88
  "@vitejs/plugin-react": "^4.3.1",
88
89
  "execa": "^9.3.1",
89
- "khroma": "^2.1.0",
90
90
  "react": "^18.3.1",
91
91
  "react-dom": "^18.3.1",
92
- "type-fest": "^4.21.0",
93
92
  "typescript": "^5.5.4",
94
93
  "vite": "5.3.4",
95
94
  "vite-plugin-dts": "^3.9.1"
@@ -0,0 +1,5 @@
1
+ import { type CustomColorDefinitions } from '@likec4/core'
2
+
3
+ export interface LikeC4CustomColorsProperties {
4
+ customColors: CustomColorDefinitions
5
+ }
@@ -0,0 +1,37 @@
1
+ import { type ThemeColorValues } from '@likec4/core'
2
+ import { entries } from 'remeda'
3
+ import type { LikeC4CustomColorsProperties } from './LikeC4CustomColors.props'
4
+ import { vars } from './theme.css'
5
+
6
+ type CSSVarFunction = `var(--${string})` | `var(--${string}, ${string | number} )`
7
+
8
+ export function LikeC4CustomColors({ customColors }: LikeC4CustomColorsProperties) {
9
+ function toStyle(name: String, colorValues: ThemeColorValues): String {
10
+ const rules = new Array<String>(
11
+ ...entries(colorValues.elements).map(([key, value]) => `${stripCssVarReference(vars.element[key])}: ${value};`),
12
+ ...entries(colorValues.relationships).map(([key, value]) =>
13
+ `${stripCssVarReference(vars.relation[key])}: ${value};`
14
+ )
15
+ )
16
+ .join('\n')
17
+
18
+ return `:where([data-likec4-color=${name}]) {
19
+ ${rules}
20
+ }`
21
+ }
22
+
23
+ function stripCssVarReference(ref: CSSVarFunction): String {
24
+ const end = ref.indexOf(',')
25
+ return ref.substring(4, end == -1 ? ref.length - 1 : end)
26
+ }
27
+
28
+ const styles = entries(customColors)
29
+ .map(([name, color]) => toStyle(name, color))
30
+ .join('\n')
31
+
32
+ return (
33
+ <>
34
+ <style type="text/css" dangerouslySetInnerHTML={{ __html: styles }} />
35
+ </>
36
+ )
37
+ }
@@ -3,70 +3,72 @@ import type {
3
3
  DiagramNode,
4
4
  DiagramView,
5
5
  Fqn,
6
- NonEmptyArray,
7
6
  RelationID,
8
7
  ViewChange,
9
- ViewID
8
+ ViewID,
9
+ WhereOperator
10
10
  } from '@likec4/core'
11
11
  import type { MouseEvent as ReactMouseEvent, ReactNode } from 'react'
12
12
  import type { XYFlowEdge, XYFlowNode } from './xyflow/types'
13
13
  import type { XYBackground } from './xyflow/XYFlowBackground'
14
14
 
15
- type EqualOperator<V> = {
16
- eq: V
17
- neq?: never
18
- } | {
19
- eq?: never
20
- neq: V
21
- }
22
-
23
- type AllNever = {
24
- not?: never
25
- and?: never
26
- or?: never
27
- tag?: never
28
- kind?: never
29
- }
15
+ // type EqualOperator<V> = {
16
+ // eq: V
17
+ // neq?: never
18
+ // } | {
19
+ // eq?: never
20
+ // neq: V
21
+ // }
30
22
 
31
- type TagKindOperator<Tag, Kind> =
32
- & Omit<AllNever, 'tag' | 'kind'>
33
- & ({
34
- tag: EqualOperator<Tag>
35
- kind?: never
36
- } | {
37
- tag?: never
38
- kind: EqualOperator<Kind>
39
- })
40
-
41
- type NotOperator<Tag, Kind> = Omit<AllNever, 'not'> & {
42
- not: TagKindOperator<Tag, Kind> | AndOperator<Tag, Kind> | OrOperator<Tag, Kind>
43
- }
23
+ // type AllNever = {
24
+ // not?: never
25
+ // and?: never
26
+ // or?: never
27
+ // tag?: never
28
+ // kind?: never
29
+ // }
44
30
 
45
- type AndOperator<Tag, Kind> = Omit<AllNever, 'and'> & {
46
- and: NonEmptyArray<
47
- | TagKindOperator<Tag, Kind>
48
- | OrOperator<Tag, Kind>
49
- | NotOperator<Tag, Kind>
50
- >
51
- }
31
+ // type TagKindOperator<Tag, Kind> =
32
+ // & Omit<AllNever, 'tag' | 'kind'>
33
+ // & ({
34
+ // tag: EqualOperator<Tag>
35
+ // kind?: never
36
+ // } | {
37
+ // tag?: never
38
+ // kind: EqualOperator<Kind>
39
+ // })
40
+
41
+ // type NotOperator<Tag, Kind> = Omit<AllNever, 'not'> & {
42
+ // not: TagKindOperator<Tag, Kind> | AndOperator<Tag, Kind> | OrOperator<Tag, Kind>
43
+ // }
52
44
 
53
- type OrOperator<Tag, Kind> = Omit<AllNever, 'or'> & {
54
- or: NonEmptyArray<
55
- | TagKindOperator<Tag, Kind>
56
- | AndOperator<Tag, Kind>
57
- | NotOperator<Tag, Kind>
58
- >
59
- }
45
+ // type AndOperator<Tag, Kind> = Omit<AllNever, 'and'> & {
46
+ // and: NonEmptyArray<
47
+ // | TagKindOperator<Tag, Kind>
48
+ // | OrOperator<Tag, Kind>
49
+ // | NotOperator<Tag, Kind>
50
+ // >
51
+ // }
60
52
 
61
- // export const isOrOperator = (operator: WhereOperator): operator is OrOperator<WhereOperator> => {
62
- // return 'or' in operator
53
+ // type OrOperator<Tag, Kind> = Omit<AllNever, 'or'> & {
54
+ // or: NonEmptyArray<
55
+ // | TagKindOperator<Tag, Kind>
56
+ // | AndOperator<Tag, Kind>
57
+ // | NotOperator<Tag, Kind>
58
+ // >
63
59
  // }
64
60
 
65
- export type WhereOperator<Tag extends string, Kind extends string> =
66
- | TagKindOperator<Tag, Kind>
67
- | NotOperator<Tag, Kind>
68
- | AndOperator<Tag, Kind>
69
- | OrOperator<Tag, Kind>
61
+ // // export const isOrOperator = (operator: WhereOperator): operator is OrOperator<WhereOperator> => {
62
+ // // return 'or' in operator
63
+ // // }
64
+
65
+ // export type WhereOperator<Tag extends string, Kind extends string> =
66
+ // | TagKindOperator<Tag, Kind>
67
+ // | NotOperator<Tag, Kind>
68
+ // | AndOperator<Tag, Kind>
69
+ // | OrOperator<Tag, Kind>
70
+
71
+ export type { WhereOperator }
70
72
 
71
73
  export type DiagramNodeWithNavigate = Omit<DiagramNode, 'navigateTo'> & {
72
74
  navigateTo: ViewID
@@ -1,3 +1,4 @@
1
+ import type { DiagramView } from '@likec4/core'
1
2
  import { ReactFlowProvider as XYFlowProvider } from '@xyflow/react'
2
3
  import clsx from 'clsx'
3
4
  import { shallowEqual } from 'fast-equals'
@@ -5,6 +6,7 @@ import { domAnimation, LazyMotion } from 'framer-motion'
5
6
  import { memo, useRef } from 'react'
6
7
  import { rootClassName } from './globals.css'
7
8
  import { useDiagramState } from './hooks/useDiagramState'
9
+ import { LikeC4CustomColors } from './LikeC4CustomColors'
8
10
  import * as css from './LikeC4Diagram.css'
9
11
  import { type LikeC4DiagramEventHandlers, type LikeC4DiagramProperties } from './LikeC4Diagram.props'
10
12
  import { EnsureMantine } from './mantine/EnsureMantine'
@@ -70,6 +72,7 @@ export function LikeC4Diagram({
70
72
  fitView={fitView}
71
73
  {...initialRef.current}
72
74
  >
75
+ {customColorsDefined(view) && <LikeC4CustomColors customColors={view.customColorDefinitions} />}
73
76
  <DiagramContextProvider
74
77
  view={view}
75
78
  keepAspectRatio={keepAspectRatio}
@@ -114,6 +117,7 @@ export function LikeC4Diagram({
114
117
  </EnsureMantine>
115
118
  )
116
119
  }
120
+ LikeC4Diagram.displayName = 'LikeC4Diagram'
117
121
 
118
122
  type LikeC4DiagramInnerProps = {
119
123
  background: NonNullable<LikeC4DiagramProperties['background']>
@@ -164,3 +168,8 @@ const LikeC4DiagramInnerMemo = memo<LikeC4DiagramInnerProps>(function LikeC4Diag
164
168
  </>
165
169
  )
166
170
  }, shallowEqual)
171
+ LikeC4DiagramInnerMemo.displayName = 'LikeC4DiagramInnerMemo'
172
+
173
+ function customColorsDefined(view: DiagramView) {
174
+ return Object.keys(view.customColorDefinitions).length > 0
175
+ }
@@ -12,3 +12,4 @@ export function EnsureMantine({ children }: EnsureMantineProps) {
12
12
 
13
13
  return <>{children}</>
14
14
  }
15
+ EnsureMantine.displayName = 'EnsureMantine'
@@ -79,3 +79,4 @@ export function DiagramContextProvider({
79
79
  </div>
80
80
  )
81
81
  }
82
+ DiagramContextProvider.displayName = 'DiagramContextProvider'
@@ -1,5 +1,5 @@
1
1
  import { extractStep, invariant, nonNullable, whereOperatorAsPredicate } from '@likec4/core'
2
- import type { DiagramEdge, DiagramNode, DiagramView, Fqn } from '@likec4/core/types'
2
+ import type { DiagramEdge, DiagramNode, DiagramView, Fqn } from '@likec4/core'
3
3
  import { hasAtLeast } from 'remeda'
4
4
  import type { WhereOperator } from '../LikeC4Diagram.props'
5
5
  import { ZIndexes } from '../xyflow/const'
@@ -141,7 +141,7 @@ export function NotationPanel() {
141
141
 
142
142
  return (
143
143
  <AnimatePresence>
144
- {!hasNotations && (
144
+ {!hasNotations && isVisible && (
145
145
  <m.div
146
146
  key={'empty'}
147
147
  initial={{ opacity: 0.75, translateX: '50%' }}
@@ -151,7 +151,7 @@ export function NotationPanel() {
151
151
  opacity: 0.6
152
152
  }}
153
153
  className={clsx('react-flow__panel', css.container)}>
154
- <Tooltip label="Diagram has no notations" color="orange" {...portalProps}>
154
+ <Tooltip label="View has no notations" color="orange" {...portalProps}>
155
155
  <ThemeIcon
156
156
  size={'xl'}
157
157
  variant="light"
@@ -194,5 +194,6 @@ export function XYFlow({
194
194
  </ReactFlow>
195
195
  )
196
196
  }
197
+ XYFlow.displayName = 'XYFlow'
197
198
 
198
199
  // export const XYFlow = memo(XYFlowWrapper) as typeof XYFlowWrapper
@@ -1,7 +1,6 @@
1
- import type { DiagramNode } from '@likec4/core/types'
2
- import { ActionIcon, Text as MantineText, Tooltip } from '@mantine/core'
3
- import { IconFileSymlink } from '@tabler/icons-react'
4
- import { Handle, type NodeProps, NodeToolbar, Position } from '@xyflow/react'
1
+ import type { DiagramNode } from '@likec4/core'
2
+ import { Text as MantineText } from '@mantine/core'
3
+ import { Handle, type NodeProps, Position } from '@xyflow/react'
5
4
  import clsx from 'clsx'
6
5
  import { deepEqual as eq } from 'fast-equals'
7
6
  import { m, type Variants } from 'framer-motion'
@@ -1,5 +1,5 @@
1
1
  import { hasAtLeast, invariant } from '@likec4/core'
2
- import type { DiagramEdge, Point } from '@likec4/core/types'
2
+ import type { DiagramEdge, Point } from '@likec4/core'
3
3
  import type { Rect, XYPosition } from '@xyflow/react'
4
4
  import { Bezier } from 'bezier-js'
5
5
  import { isArray } from 'remeda'