@health-samurai/react-components 0.0.0-alpha.18 → 0.0.0-alpha.20

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 (74) hide show
  1. package/LICENSE +21 -0
  2. package/dist/bundle.css +51 -33
  3. package/dist/src/components/code-editor/fhir-autocomplete.d.ts +70 -0
  4. package/dist/src/components/code-editor/fhir-autocomplete.d.ts.map +1 -0
  5. package/dist/src/components/code-editor/fhir-autocomplete.js +1849 -0
  6. package/dist/src/components/code-editor/fhir-autocomplete.js.map +1 -0
  7. package/dist/src/components/code-editor/fhir-autocomplete.test.js +1099 -0
  8. package/dist/src/components/code-editor/fhir-autocomplete.test.js.map +1 -0
  9. package/dist/src/components/code-editor/http/index.d.ts +9 -1
  10. package/dist/src/components/code-editor/http/index.d.ts.map +1 -1
  11. package/dist/src/components/code-editor/http/index.js +423 -3
  12. package/dist/src/components/code-editor/http/index.js.map +1 -1
  13. package/dist/src/components/code-editor/index.d.ts +13 -4
  14. package/dist/src/components/code-editor/index.d.ts.map +1 -1
  15. package/dist/src/components/code-editor/index.js +505 -96
  16. package/dist/src/components/code-editor/index.js.map +1 -1
  17. package/dist/src/components/code-editor/json-ast.d.ts +46 -0
  18. package/dist/src/components/code-editor/json-ast.d.ts.map +1 -0
  19. package/dist/src/components/code-editor/json-ast.js +465 -0
  20. package/dist/src/components/code-editor/json-ast.js.map +1 -0
  21. package/dist/src/components/code-editor/json-ast.test.js +206 -0
  22. package/dist/src/components/code-editor/json-ast.test.js.map +1 -0
  23. package/dist/src/components/code-editor/sql-completion.d.ts +22 -0
  24. package/dist/src/components/code-editor/sql-completion.d.ts.map +1 -0
  25. package/dist/src/components/code-editor/sql-completion.js +895 -0
  26. package/dist/src/components/code-editor/sql-completion.js.map +1 -0
  27. package/dist/src/components/date-picker-input.d.ts +10 -0
  28. package/dist/src/components/date-picker-input.d.ts.map +1 -0
  29. package/dist/src/components/date-picker-input.js +90 -0
  30. package/dist/src/components/date-picker-input.js.map +1 -0
  31. package/dist/src/components/date-picker-input.stories.js +76 -0
  32. package/dist/src/components/date-picker-input.stories.js.map +1 -0
  33. package/dist/src/index.d.ts +1 -0
  34. package/dist/src/index.d.ts.map +1 -1
  35. package/dist/src/index.js +1 -0
  36. package/dist/src/index.js.map +1 -1
  37. package/dist/src/shadcn/components/ui/alert-dialog.d.ts +1 -1
  38. package/dist/src/shadcn/components/ui/calendar.d.ts +1 -1
  39. package/dist/src/shadcn/components/ui/carousel.d.ts +1 -1
  40. package/dist/src/shadcn/components/ui/chart.d.ts +3 -3
  41. package/dist/src/shadcn/components/ui/chart.d.ts.map +1 -1
  42. package/dist/src/shadcn/components/ui/chart.js +1 -1
  43. package/dist/src/shadcn/components/ui/chart.js.map +1 -1
  44. package/dist/src/shadcn/components/ui/command.d.ts +1 -1
  45. package/dist/src/shadcn/components/ui/pagination.d.ts +1 -1
  46. package/dist/src/shadcn/components/ui/resizable.stories.js +2 -2
  47. package/dist/src/shadcn/components/ui/resizable.stories.js.map +1 -1
  48. package/dist/src/shadcn/components/ui/sidebar.d.ts +4 -4
  49. package/dist/src/shadcn/components/ui/tabs.d.ts +3 -1
  50. package/dist/src/shadcn/components/ui/tabs.d.ts.map +1 -1
  51. package/dist/src/shadcn/components/ui/tabs.js +129 -2
  52. package/dist/src/shadcn/components/ui/tabs.js.map +1 -1
  53. package/dist/src/shadcn/components/ui/tabs.stories.js +1 -1
  54. package/dist/src/shadcn/components/ui/tabs.stories.js.map +1 -1
  55. package/dist/src/shadcn/components/ui/toggle-group.d.ts +1 -1
  56. package/dist/src/typography.css +1 -1
  57. package/package.json +24 -19
  58. package/src/components/code-editor/fhir-autocomplete.test.ts +993 -0
  59. package/src/components/code-editor/fhir-autocomplete.ts +2321 -0
  60. package/src/components/code-editor/http/index.ts +339 -2
  61. package/src/components/code-editor/index.tsx +593 -102
  62. package/src/components/code-editor/json-ast.test.ts +230 -0
  63. package/src/components/code-editor/json-ast.ts +590 -0
  64. package/src/components/code-editor/sql-completion.ts +1105 -0
  65. package/src/components/date-picker-input.stories.tsx +79 -0
  66. package/src/components/date-picker-input.tsx +104 -0
  67. package/src/index.tsx +1 -0
  68. package/src/shadcn/components/ui/chart.tsx +6 -3
  69. package/src/shadcn/components/ui/resizable.stories.tsx +2 -2
  70. package/src/shadcn/components/ui/tabs.stories.tsx +1 -1
  71. package/src/shadcn/components/ui/tabs.tsx +160 -2
  72. package/src/typography.css +1 -1
  73. package/dist/src/components/code-editor/http/grammar/http.test.d.ts +0 -2
  74. package/dist/src/components/code-editor/http/grammar/http.test.d.ts.map +0 -1
@@ -0,0 +1,230 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { buildJsonDocumentContext } from "./json-ast";
3
+
4
+ // Helpers
5
+ const at = (doc: string, marker = "|") => {
6
+ const pos = doc.indexOf(marker);
7
+ return { doc: doc.slice(0, pos) + doc.slice(pos + 1), pos };
8
+ };
9
+
10
+ describe("buildJsonDocumentContext", () => {
11
+ describe("fullPath", () => {
12
+ it("empty object root", () => {
13
+ const { doc, pos } = at("{\n |\n}");
14
+ const ctx = buildJsonDocumentContext(doc, pos);
15
+ expect(ctx.fullPath).toEqual([]);
16
+ });
17
+
18
+ it("one level deep", () => {
19
+ const { doc, pos } = at('{\n "name": [\n {\n |\n }\n ]\n}');
20
+ const ctx = buildJsonDocumentContext(doc, pos);
21
+ expect(ctx.fullPath).toEqual(["name"]);
22
+ });
23
+
24
+ it("two levels deep", () => {
25
+ const { doc, pos } = at(
26
+ '{\n "address": [\n {\n "period": {\n |\n }\n }\n ]\n}',
27
+ );
28
+ const ctx = buildJsonDocumentContext(doc, pos);
29
+ expect(ctx.fullPath).toEqual(["address", "period"]);
30
+ });
31
+
32
+ it("second object in array has correct path", () => {
33
+ const { doc, pos } = at(
34
+ '{\n "parameter": [\n {"name": "a"},\n {\n |\n }\n ]\n}',
35
+ );
36
+ const ctx = buildJsonDocumentContext(doc, pos);
37
+ expect(ctx.fullPath).toEqual(["parameter"]);
38
+ });
39
+
40
+ it("third object in array has correct path", () => {
41
+ const { doc, pos } = at(
42
+ '{\n "parameter": [\n {"name": "a"},\n {"name": "b"},\n {\n |\n }\n ]\n}',
43
+ );
44
+ const ctx = buildJsonDocumentContext(doc, pos);
45
+ expect(ctx.fullPath).toEqual(["parameter"]);
46
+ });
47
+
48
+ it("nested array second item", () => {
49
+ const { doc, pos } = at(
50
+ '{\n "entry": [\n {"resource": {}},\n {\n "resource": {\n |\n }\n }\n ]\n}',
51
+ );
52
+ const ctx = buildJsonDocumentContext(doc, pos);
53
+ expect(ctx.fullPath).toEqual(["entry", "resource"]);
54
+ });
55
+
56
+ it("inside contained resource", () => {
57
+ const { doc, pos } = at(
58
+ '{\n "resourceType": "Bundle",\n "entry": [\n {\n "resource": {\n "resourceType": "Patient",\n |\n }\n }\n ]\n}',
59
+ );
60
+ const ctx = buildJsonDocumentContext(doc, pos);
61
+ expect(ctx.fullPath).toEqual(["entry", "resource"]);
62
+ });
63
+ });
64
+
65
+ describe("fullPath in HTTP mode", () => {
66
+ it("skips HTTP header", () => {
67
+ const { doc, pos } = at(
68
+ "POST /fhir/Patient\nContent-Type: application/json\n\n{\n |\n}",
69
+ );
70
+ const ctx = buildJsonDocumentContext(doc, pos);
71
+ expect(ctx.fullPath).toEqual([]);
72
+ });
73
+
74
+ it("nested path in HTTP mode", () => {
75
+ const { doc, pos } = at(
76
+ 'PUT /fhir/Patient/1\n\n{\n "name": [\n {\n |\n }\n ]\n}',
77
+ );
78
+ const ctx = buildJsonDocumentContext(doc, pos);
79
+ expect(ctx.fullPath).toEqual(["name"]);
80
+ });
81
+ });
82
+
83
+ describe("cursorPosition", () => {
84
+ it("property on empty line", () => {
85
+ const { doc, pos } = at("{\n |\n}");
86
+ const ctx = buildJsonDocumentContext(doc, pos);
87
+ expect(ctx.cursorPosition.kind).toBe("property");
88
+ });
89
+
90
+ it("property with partial word", () => {
91
+ const { doc, pos } = at('{\n "nam|\n}');
92
+ const ctx = buildJsonDocumentContext(doc, pos);
93
+ expect(ctx.cursorPosition.kind).toBe("property");
94
+ });
95
+
96
+ it("value after colon with string", () => {
97
+ const { doc, pos } = at('{\n "gender": "|\n}');
98
+ const ctx = buildJsonDocumentContext(doc, pos);
99
+ expect(ctx.cursorPosition).toEqual({
100
+ kind: "value",
101
+ key: "gender",
102
+ prefix: "",
103
+ });
104
+ });
105
+
106
+ it("value with partial text", () => {
107
+ const { doc, pos } = at('{\n "gender": "mal|\n}');
108
+ const ctx = buildJsonDocumentContext(doc, pos);
109
+ expect(ctx.cursorPosition).toEqual({
110
+ kind: "value",
111
+ key: "gender",
112
+ prefix: "mal",
113
+ });
114
+ });
115
+
116
+ it("value for resourceType", () => {
117
+ const { doc, pos } = at('{\n "resourceType": "|\n}');
118
+ const ctx = buildJsonDocumentContext(doc, pos);
119
+ expect(ctx.cursorPosition).toEqual({
120
+ kind: "value",
121
+ key: "resourceType",
122
+ prefix: "",
123
+ });
124
+ });
125
+
126
+ it("array-item inside canonical array", () => {
127
+ const { doc, pos } = at('{\n "profile": [\n "|\n ]\n}');
128
+ const ctx = buildJsonDocumentContext(doc, pos);
129
+ expect(ctx.cursorPosition.kind).toBe("array-item");
130
+ if (ctx.cursorPosition.kind === "array-item") {
131
+ expect(ctx.cursorPosition.parentKey).toBe("profile");
132
+ }
133
+ });
134
+
135
+ it("property after comma in object", () => {
136
+ const { doc, pos } = at('{\n "a": 1,\n |\n}');
137
+ const ctx = buildJsonDocumentContext(doc, pos);
138
+ expect(ctx.cursorPosition.kind).toBe("property");
139
+ });
140
+
141
+ it("property position after boolean value with comma on same line", () => {
142
+ const { doc, pos } = at(
143
+ '{\n "resourceType": "Patient",\n "active": true, |\n}',
144
+ );
145
+ const ctx = buildJsonDocumentContext(doc, pos);
146
+ expect(ctx.cursorPosition.kind).toBe("property");
147
+ });
148
+ });
149
+
150
+ describe("isInsideArray", () => {
151
+ it("false at object root", () => {
152
+ const { doc, pos } = at("{\n |\n}");
153
+ const ctx = buildJsonDocumentContext(doc, pos);
154
+ expect(ctx.isInsideArray()).toBe(false);
155
+ });
156
+
157
+ it("true inside array", () => {
158
+ const { doc, pos } = at('{\n "name": [\n |\n ]\n}');
159
+ const ctx = buildJsonDocumentContext(doc, pos);
160
+ expect(ctx.isInsideArray()).toBe(true);
161
+ });
162
+
163
+ it("false inside object inside array", () => {
164
+ const { doc, pos } = at('{\n "name": [\n {\n |\n }\n ]\n}');
165
+ const ctx = buildJsonDocumentContext(doc, pos);
166
+ expect(ctx.isInsideArray()).toBe(false);
167
+ });
168
+ });
169
+
170
+ describe("getScope", () => {
171
+ it("getString finds resourceType at level 0", () => {
172
+ const { doc, pos } = at('{\n "resourceType": "Patient",\n |\n}');
173
+ const ctx = buildJsonDocumentContext(doc, pos);
174
+ expect(ctx.getScope(0).getString("resourceType")).toBe("Patient");
175
+ });
176
+
177
+ it("getString finds resourceType in parent object (levelsUp=1)", () => {
178
+ const { doc, pos } = at(
179
+ '{\n "resourceType": "Patient",\n "name": [\n {\n |\n }\n ]\n}',
180
+ );
181
+ const ctx = buildJsonDocumentContext(doc, pos);
182
+ // level 0 is the inner {} (no resourceType)
183
+ expect(ctx.getScope(0).getString("resourceType")).toBe(null);
184
+ // level 1 is the outer {} with "Patient"
185
+ expect(ctx.getScope(1).getString("resourceType")).toBe("Patient");
186
+ });
187
+
188
+ it("getString finds inner resourceType for contained", () => {
189
+ const doc = [
190
+ "{",
191
+ ' "resourceType": "Bundle",',
192
+ ' "entry": [',
193
+ " {",
194
+ ' "resource": {',
195
+ ' "resourceType": "Patient",',
196
+ ' "name": [',
197
+ " {",
198
+ " |",
199
+ " }",
200
+ " ]",
201
+ " }",
202
+ " }",
203
+ " ]",
204
+ "}",
205
+ ].join("\n");
206
+ const { doc: d, pos } = at(doc);
207
+ const ctx = buildJsonDocumentContext(d, pos);
208
+ // level 0 = inner { } (name array item)
209
+ expect(ctx.getScope(0).getString("resourceType")).toBe(null);
210
+ // level 1 = resource { "resourceType": "Patient" }
211
+ expect(ctx.getScope(1).getString("resourceType")).toBe("Patient");
212
+ });
213
+
214
+ it("getStringArray finds meta.profile", () => {
215
+ const { doc, pos } = at(
216
+ '{\n "resourceType": "Patient",\n "meta": {\n "profile": ["http://example.com/Patient"]\n },\n |\n}',
217
+ );
218
+ const ctx = buildJsonDocumentContext(doc, pos);
219
+ expect(ctx.getScope(0).getStringArray("meta", "profile")).toEqual([
220
+ "http://example.com/Patient",
221
+ ]);
222
+ });
223
+
224
+ it("getStringArray returns empty for missing profile", () => {
225
+ const { doc, pos } = at('{\n "resourceType": "Patient",\n |\n}');
226
+ const ctx = buildJsonDocumentContext(doc, pos);
227
+ expect(ctx.getScope(0).getStringArray("meta", "profile")).toEqual([]);
228
+ });
229
+ });
230
+ });