likec4 0.48.0 → 0.50.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.
Files changed (51) hide show
  1. package/README.md +12 -6
  2. package/dist/@likec4/diagrams/diagram/Diagram.js +55 -27
  3. package/dist/@likec4/diagrams/diagram/Edges.js +14 -11
  4. package/dist/@likec4/diagrams/diagram/Nodes.js +212 -23
  5. package/dist/@likec4/diagrams/diagram/icons/ZoomIn.js +2 -1
  6. package/dist/@likec4/diagrams/diagram/shapes/Compound.js +2 -1
  7. package/dist/@likec4/diagrams/diagram/shapes/Edge.js +1 -1
  8. package/dist/@likec4/diagrams/diagram/state/atoms.js +35 -60
  9. package/dist/@likec4/diagrams/diagram/utils.js +14 -0
  10. package/dist/@likec4/diagrams/hooks/useDiagramApi.js +4 -5
  11. package/dist/@likec4/diagrams/hooks/useImageLoader.js +1 -1
  12. package/dist/__app__/likec4.css +8 -5
  13. package/dist/__app__/src/App.jsx +9 -11
  14. package/dist/__app__/src/components/CopyToClipboard.jsx +29 -0
  15. package/dist/__app__/src/components/CopyToClipboard.module.css +16 -0
  16. package/dist/__app__/src/components/DiagramNotFound.jsx +2 -2
  17. package/dist/__app__/src/components/index.js +2 -1
  18. package/dist/__app__/src/components/sidebar/Sidebar.jsx +1 -1
  19. package/dist/__app__/src/components/sidebar/styles.module.css +4 -1
  20. package/dist/__app__/src/components/view-page/DisplayModeSelector.jsx +15 -9
  21. package/dist/__app__/src/components/view-page/Header.jsx +97 -0
  22. package/dist/__app__/src/components/view-page/Header.module.css +24 -0
  23. package/dist/__app__/src/components/view-page/ShareDialog.jsx +23 -15
  24. package/dist/__app__/src/components/view-page/ViewActions.jsx +69 -0
  25. package/dist/__app__/src/data/atoms.js +4 -22
  26. package/dist/__app__/src/data/hooks.js +5 -4
  27. package/dist/__app__/src/data/index-page.js +22 -0
  28. package/dist/__app__/src/likec4-views.js +1 -1
  29. package/dist/__app__/src/pages/index-page/index.jsx +99 -0
  30. package/dist/__app__/src/pages/index-page/index.module.css +20 -0
  31. package/dist/__app__/src/pages/index.js +1 -1
  32. package/dist/__app__/src/pages/useTransparentBackground.js +2 -2
  33. package/dist/__app__/src/pages/view-page/ViewAsReact.jsx +60 -0
  34. package/dist/__app__/src/pages/view-page/index.js +11 -0
  35. package/dist/__app__/src/pages/view-page/other-formats/ViewAsD2.jsx +18 -0
  36. package/dist/__app__/src/pages/view-page/other-formats/ViewAsDot.jsx +33 -0
  37. package/dist/__app__/src/pages/view-page/other-formats/ViewAsMmd.jsx +18 -0
  38. package/dist/__app__/src/pages/view-page/other-formats.jsx +43 -0
  39. package/dist/__app__/src/pages/view-page/view-page.module.css +81 -0
  40. package/dist/__app__/src/pages/view.page.jsx +12 -65
  41. package/dist/__app__/src/router.js +90 -20
  42. package/dist/__app__/src/utils/utils.js +1 -2
  43. package/dist/__app__/tsconfig.json +1 -0
  44. package/dist/cli/index.js +288 -207
  45. package/package.json +17 -17
  46. package/dist/__app__/postcss.config.cjs +0 -11
  47. package/dist/__app__/src/components/view-page/ViewActionsToolbar.jsx +0 -66
  48. package/dist/__app__/src/pages/index.module.css +0 -11
  49. package/dist/__app__/src/pages/index.page.jsx +0 -57
  50. package/dist/__app__/src/pages/view-page.module.css +0 -30
  51. package/dist/__app__/tailwind.config.cjs +0 -17
@@ -1,14 +1,20 @@
1
1
  import { useStore } from '@nanostores/react';
2
- import { createSearchParams, createRouter, openPage, getPagePath } from '@nanostores/router';
2
+ import { createRouter, createSearchParams, getPagePath } from '@nanostores/router';
3
3
  import { computed } from 'nanostores';
4
+ import { equals, isEmpty, isString, mapValues, omitBy } from 'remeda';
4
5
  import { BaseUrl } from './const';
6
+ import { startTransition } from 'react';
5
7
  export const $router = createRouter({
6
8
  index: BaseUrl,
7
9
  view: `${BaseUrl}view/:viewId?`,
8
10
  export: `${BaseUrl}export/:viewId`,
9
11
  embed: `${BaseUrl}embed/:viewId`
12
+ }, {
13
+ links: true
14
+ });
15
+ const $searchParams = createSearchParams({
16
+ links: true
10
17
  });
11
- const $searchParams = createSearchParams();
12
18
  const asTheme = (v) => {
13
19
  const vlower = v?.toLowerCase();
14
20
  if (vlower === 'light' || vlower === 'dark') {
@@ -21,17 +27,61 @@ const asPadding = (v) => {
21
27
  if (parsed && isFinite(parsed) && isNaN(parsed) === false) {
22
28
  return Math.round(parsed);
23
29
  }
24
- return 20;
30
+ return undefined;
31
+ };
32
+ const asViewMode = (v) => {
33
+ const mode = v?.toLowerCase() ?? '';
34
+ switch (mode) {
35
+ case 'dot':
36
+ case 'mmd':
37
+ case 'd2':
38
+ case 'react': {
39
+ return mode;
40
+ }
41
+ default: {
42
+ return undefined;
43
+ }
44
+ }
25
45
  };
26
- const $route = computed([$router, $searchParams], (r, v) => {
46
+ const searchParams = computed($searchParams, v => {
47
+ return {
48
+ theme: asTheme(v.theme),
49
+ padding: asPadding(v.padding),
50
+ mode: asViewMode(v.mode),
51
+ showUI: 'showUI' in v ? v.showUI === 'true' : undefined
52
+ };
53
+ });
54
+ const filter = (v, k) => v == undefined ||
55
+ (k === 'theme' && v === 'dark') ||
56
+ (k === 'mode' && v === 'react') ||
57
+ (k === 'padding' && v === 20);
58
+ function omitDefaults(v) {
59
+ return omitBy(v, filter);
60
+ }
61
+ export function updateSearchParams(update) {
62
+ const current = searchParams.get();
63
+ const next = {
64
+ ...current,
65
+ ...update
66
+ };
67
+ if (!equals(current, next)) {
68
+ const params = mapValues(omitDefaults(next), v => (isString(v) ? v : String(v)));
69
+ startTransition(() => {
70
+ $searchParams.open(params);
71
+ });
72
+ }
73
+ }
74
+ export const useSearchParams = () => useStore(searchParams);
75
+ const $route = computed([$router, searchParams], (r, v) => {
27
76
  if (r?.route === 'view') {
28
77
  return {
29
78
  route: 'view',
30
79
  params: {
31
- viewId: r.params.viewId ?? 'index',
32
- theme: asTheme(v.theme) ?? 'dark'
80
+ viewId: (r.params.viewId ?? 'index'),
81
+ theme: v.theme ?? 'dark',
82
+ mode: v.mode ?? 'react'
33
83
  },
34
- showUI: 'showUI' in v ? v.showUI === 'true' : true
84
+ showUI: v.showUI ?? true
35
85
  };
36
86
  }
37
87
  if (r?.route === 'export' || r?.route === 'embed') {
@@ -39,7 +89,7 @@ const $route = computed([$router, $searchParams], (r, v) => {
39
89
  route: r.route,
40
90
  params: {
41
91
  viewId: r.params.viewId,
42
- padding: asPadding(v.padding),
92
+ padding: v.padding ?? 20,
43
93
  theme: r.route === 'embed' ? asTheme(v.theme) : undefined
44
94
  },
45
95
  showUI: false
@@ -50,29 +100,49 @@ const $route = computed([$router, $searchParams], (r, v) => {
50
100
  params: {
51
101
  theme: asTheme(v.theme) ?? 'dark'
52
102
  },
53
- showUI: 'showUI' in v ? v.showUI === 'true' : true
103
+ showUI: v.showUI ?? false
54
104
  };
55
105
  });
56
106
  export const useRoute = () => useStore($route);
57
107
  export const isCurrentDiagram = (view) => {
58
108
  const r = $route.get();
59
- return (r.route === 'view' || r.route === 'export') && r.params.viewId === view.id;
109
+ return ((r.route === 'view' || r.route === 'export' || r.route === 'embed') &&
110
+ r.params.viewId === view.id);
60
111
  };
112
+ function currentSearchParams() {
113
+ const params = omitDefaults(searchParams.get());
114
+ if (isEmpty(params)) {
115
+ return '';
116
+ }
117
+ const urlSearchParams = new URLSearchParams();
118
+ for (const [k, v] of Object.entries(params)) {
119
+ urlSearchParams.set(k, isString(v) ? v : String(v));
120
+ }
121
+ const asString = urlSearchParams.toString();
122
+ return asString !== '' ? '?' + asString : '';
123
+ }
124
+ function getRoutePath(name, ...params) {
125
+ // if (params.length > 1) {
126
+ // let p = params[0]!
127
+ // p.
128
+ // }
129
+ return getPagePath($router, name, ...params) + currentSearchParams();
130
+ }
131
+ function openRoute(name, ...params) {
132
+ startTransition(() => {
133
+ $router.open(getRoutePath(name, ...params));
134
+ });
135
+ }
61
136
  export const $pages = {
62
137
  index: {
63
- open: () => openPage($router, 'index')
138
+ url: () => getRoutePath('index'),
139
+ open: () => openRoute('index')
64
140
  },
65
141
  view: {
66
- open: (viewId) => openPage($router, 'view', { viewId })
142
+ url: (viewId) => getRoutePath('view', { viewId }),
143
+ open: (viewId) => openRoute('view', { viewId })
67
144
  },
68
145
  embed: {
69
- path: (viewId) => getPagePath($router, 'embed', { viewId })
146
+ path: (viewId) => getRoutePath('embed', { viewId })
70
147
  }
71
148
  };
72
- // if (import.meta.env.DEV) {
73
- // logger({
74
- // $searchParams,
75
- // $router,
76
- // $route
77
- // })
78
- // }
@@ -1,5 +1,4 @@
1
1
  import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
2
  export function cn(...inputs) {
4
- return twMerge(clsx(inputs));
3
+ return clsx(inputs);
5
4
  }
@@ -11,6 +11,7 @@
11
11
  "skipLibCheck": true,
12
12
  "outDir": "dist",
13
13
  "allowJs": true,
14
+ "exactOptionalPropertyTypes": true,
14
15
  "moduleResolution": "bundler",
15
16
  "esModuleInterop": true,
16
17
  "allowArbitraryExtensions": true,