@salesforcedevs/docs-components 0.0.0 → 0.0.1-superscript

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 (83) hide show
  1. package/lwc.config.json +12 -2
  2. package/package.json +29 -27
  3. package/src/modules/doc/{amfReference/utils.ts → amfModelParser/amfModelParser.ts} +10 -5
  4. package/src/modules/doc/amfReference/amfReference.css +11 -3
  5. package/src/modules/doc/amfReference/amfReference.html +35 -26
  6. package/src/modules/doc/amfReference/amfReference.ts +239 -95
  7. package/src/modules/doc/amfReference/types.ts +3 -11
  8. package/src/modules/doc/amfTopic/amfTopic.css +20 -0
  9. package/src/modules/doc/amfTopic/amfTopic.ts +59 -18
  10. package/src/modules/doc/amfTopic/types.ts +15 -13
  11. package/src/modules/doc/amfTopic/utils.ts +12 -6
  12. package/src/modules/doc/breadcrumbItem/breadcrumbItem.ts +17 -10
  13. package/src/modules/doc/breadcrumbs/breadcrumbs.html +6 -9
  14. package/src/modules/doc/breadcrumbs/breadcrumbs.ts +30 -34
  15. package/src/modules/doc/componentPlayground/componentPlayground.css +30 -0
  16. package/src/modules/doc/componentPlayground/componentPlayground.html +20 -0
  17. package/src/modules/doc/componentPlayground/componentPlayground.ts +97 -0
  18. package/src/modules/doc/content/content.css +70 -76
  19. package/src/modules/doc/content/content.html +1 -0
  20. package/src/modules/doc/content/content.ts +24 -46
  21. package/src/modules/doc/contentCallout/contentCallout.css +11 -7
  22. package/src/modules/doc/contentCallout/contentCallout.html +11 -4
  23. package/src/modules/doc/contentCallout/contentCallout.ts +8 -1
  24. package/src/modules/doc/contentLayout/contentLayout.css +1 -98
  25. package/src/modules/doc/contentLayout/contentLayout.html +46 -31
  26. package/src/modules/doc/contentLayout/contentLayout.ts +337 -89
  27. package/src/modules/doc/contentMedia/contentMedia.css +1 -1
  28. package/src/modules/doc/doDont/doDont.css +47 -0
  29. package/src/modules/doc/doDont/doDont.html +27 -0
  30. package/src/modules/doc/doDont/doDont.ts +17 -0
  31. package/src/modules/doc/header/header.css +65 -36
  32. package/src/modules/doc/header/header.html +44 -138
  33. package/src/modules/doc/header/header.ts +62 -74
  34. package/src/modules/doc/heading/heading.css +16 -37
  35. package/src/modules/doc/heading/heading.html +4 -4
  36. package/src/modules/doc/heading/heading.ts +12 -10
  37. package/src/modules/doc/headingAnchor/headingAnchor.css +2 -2
  38. package/src/modules/doc/headingAnchor/headingAnchor.ts +2 -2
  39. package/src/modules/doc/headingContent/headingContent.css +1 -1
  40. package/src/modules/doc/headingContent/headingContent.html +2 -2
  41. package/src/modules/doc/headingContent/headingContent.ts +2 -2
  42. package/src/modules/doc/lwcContentLayout/lwcContentLayout.css +9 -0
  43. package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +64 -0
  44. package/src/modules/doc/lwcContentLayout/lwcContentLayout.ts +269 -0
  45. package/src/modules/doc/overview/overview.css +40 -0
  46. package/src/modules/doc/overview/overview.html +34 -0
  47. package/src/modules/doc/overview/overview.ts +12 -0
  48. package/src/modules/doc/phase/phase.css +11 -3
  49. package/src/modules/doc/phase/phase.html +12 -2
  50. package/src/modules/doc/phase/phase.ts +44 -8
  51. package/src/modules/doc/redocReference/redocReference.css +7 -0
  52. package/src/modules/doc/redocReference/redocReference.html +13 -0
  53. package/src/modules/doc/redocReference/redocReference.ts +425 -0
  54. package/src/modules/doc/specificationContent/specificationContent.css +36 -0
  55. package/src/modules/doc/specificationContent/specificationContent.html +177 -0
  56. package/src/modules/doc/specificationContent/specificationContent.ts +166 -0
  57. package/src/modules/doc/sprigSurvey/sprigSurvey.html +20 -0
  58. package/src/modules/doc/sprigSurvey/sprigSurvey.scoped.css +16 -0
  59. package/src/modules/doc/sprigSurvey/sprigSurvey.ts +16 -0
  60. package/src/modules/doc/superscriptSubscript/superscriptSubscript.html +8 -0
  61. package/src/modules/doc/superscriptSubscript/superscriptSubscript.ts +16 -0
  62. package/src/modules/doc/toc/toc.html +1 -3
  63. package/src/modules/doc/toc/toc.ts +1 -1
  64. package/src/modules/doc/toolbar/toolbar.ts +6 -6
  65. package/src/modules/doc/versionPicker/versionPicker.css +64 -0
  66. package/src/modules/doc/versionPicker/versionPicker.html +40 -0
  67. package/src/modules/doc/versionPicker/versionPicker.ts +65 -0
  68. package/src/modules/doc/xmlContent/types.ts +9 -3
  69. package/src/modules/doc/xmlContent/utils.ts +3 -1
  70. package/src/modules/doc/xmlContent/xmlContent.css +16 -4
  71. package/src/modules/doc/xmlContent/xmlContent.html +36 -21
  72. package/src/modules/doc/xmlContent/xmlContent.ts +295 -120
  73. package/src/modules/docHelpers/amfStyle/amfStyle.css +6 -8
  74. package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +162 -0
  75. package/src/modules/docHelpers/imgStyle/imgStyle.css +59 -0
  76. package/src/modules/docHelpers/status/status.css +1 -1
  77. package/src/modules/docUtils/{SearchSyncer/SearchSyncer.ts → searchSyncer/searchSyncer.ts} +1 -0
  78. package/src/modules/docUtils/utils/__mocks__/coveo.analytics.ts +16 -0
  79. package/src/modules/docUtils/utils/coveo.analytics.d.ts +10 -0
  80. package/src/modules/docUtils/utils/utils.ts +32 -0
  81. package/LICENSE +0 -12
  82. package/src/modules/docBaseElements/lightningElementWithState/lightningElementWithState.ts +0 -93
  83. package/src/modules/docHelpers/phaseContentLayout/phaseContentLayout.css +0 -39
@@ -2,16 +2,12 @@ import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
3
 
4
4
  import { DocPhaseInfo } from "typings/custom";
5
- import { toJson } from "dxUtils/normalizers";
5
+ import { toJson, normalizeBoolean } from "dxUtils/normalizers";
6
6
 
7
7
  export default class Phase extends LightningElement {
8
8
  _docPhaseInfo: DocPhaseInfo | null = null;
9
-
10
- isBodyHidden = false;
11
-
12
- get docPhaseTitle() {
13
- return this.docPhaseInfo?.title;
14
- }
9
+ _dismissible = false;
10
+ _iconName = "recipe";
15
11
 
16
12
  @api
17
13
  get docPhaseInfo(): DocPhaseInfo | null {
@@ -22,6 +18,34 @@ export default class Phase extends LightningElement {
22
18
  this._docPhaseInfo = toJson(value);
23
19
  }
24
20
 
21
+ @api
22
+ get dismissible(): boolean {
23
+ return this._dismissible;
24
+ }
25
+
26
+ set dismissible(value) {
27
+ if (value) {
28
+ this._dismissible = normalizeBoolean(value);
29
+ }
30
+ }
31
+
32
+ @api
33
+ get iconName(): string {
34
+ return this._iconName;
35
+ }
36
+
37
+ set iconName(value) {
38
+ if (value) {
39
+ this._iconName = value;
40
+ }
41
+ }
42
+
43
+ isBodyHidden = false;
44
+
45
+ get docPhaseTitle() {
46
+ return this.docPhaseInfo?.title;
47
+ }
48
+
25
49
  get hideBodyText() {
26
50
  return this.isBodyHidden ? "Show" : "Hide";
27
51
  }
@@ -51,7 +75,19 @@ export default class Phase extends LightningElement {
51
75
  }
52
76
  }
53
77
 
54
- onButtonClick() {
78
+ onShowHide() {
55
79
  this.isBodyHidden = !this.isBodyHidden;
56
80
  }
81
+
82
+ onDismiss() {
83
+ this.dispatchEvent(
84
+ new CustomEvent("dismissphase", {
85
+ detail: {
86
+ docPhaseInfo: this.docPhaseInfo
87
+ },
88
+ composed: true,
89
+ bubbles: true
90
+ })
91
+ );
92
+ }
57
93
  }
@@ -0,0 +1,7 @@
1
+ :host {
2
+ --dx-footer-margin-top: 142px;
3
+ --doc-c-redoc-sidebar-top: calc(
4
+ var(--dx-g-global-header-height) + var(--dx-g-doc-header-height) +
5
+ var(--dx-g-spacing-xl)
6
+ );
7
+ }
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <template lwc:if={showError}>
3
+ <dx-error
4
+ header="We lost communication with the space station."
5
+ subtitle="We encountered a server-related issue. (Don't worry, we're on it.) Refresh your browser or try again later."
6
+ image=""
7
+ code="500"
8
+ ></dx-error>
9
+ </template>
10
+ <template lwc:else>
11
+ <slot></slot>
12
+ </template>
13
+ </template>
@@ -0,0 +1,425 @@
1
+ /* eslint-disable @lwc/lwc/no-document-query */
2
+ import { createElement, LightningElement, api } from "lwc";
3
+ import DocPhase from "doc/phase";
4
+ import DxFooter from "dx/footer";
5
+ import SprigSurvey from "doc/sprigSurvey";
6
+ import { throttle } from "throttle-debounce";
7
+ import { pollUntil } from "dxUtils/async";
8
+
9
+ declare global {
10
+ interface Window {
11
+ Redoc: any;
12
+ }
13
+ }
14
+
15
+ declare const Sprig: (eventType: string, eventName: string) => void;
16
+
17
+ type ReferenceItem = {
18
+ source: string;
19
+ href: string;
20
+ isSelected?: boolean;
21
+ docPhase?: string | null;
22
+ };
23
+
24
+ type ReferenceConfig = {
25
+ refList: ReferenceItem[];
26
+ };
27
+
28
+ const SCROLL_THROTTLE_DELAY = 50;
29
+ const ELEMENT_TIMEOUT = 10000;
30
+ const ELEMENT_CHECK_INTERVAL = 100;
31
+
32
+ export default class RedocReference extends LightningElement {
33
+ private _referenceConfig: ReferenceConfig = { refList: [] };
34
+ private _parentDocPhaseInfo: string | null = null;
35
+ private redocInitialized = false;
36
+
37
+ private docHeaderElement: Element | null = null;
38
+ private docPhaseWrapperElement: Element | null = null;
39
+ private lastSidebarTop = 0;
40
+
41
+ showError = false;
42
+
43
+ @api
44
+ get referenceConfig(): ReferenceConfig {
45
+ return this._referenceConfig;
46
+ }
47
+
48
+ set referenceConfig(value: string | ReferenceConfig) {
49
+ try {
50
+ const refConfig =
51
+ typeof value === "string" ? JSON.parse(value) : value;
52
+ this._referenceConfig = refConfig;
53
+ } catch (error) {
54
+ this._referenceConfig = { refList: [] };
55
+ this.showErrorUI(
56
+ "Failed to parse reference configuration data",
57
+ error
58
+ );
59
+ }
60
+ }
61
+
62
+ @api
63
+ get docPhaseInfo(): string | null {
64
+ return this._parentDocPhaseInfo;
65
+ }
66
+
67
+ set docPhaseInfo(value: string) {
68
+ this._parentDocPhaseInfo = value;
69
+ }
70
+
71
+ connectedCallback(): void {
72
+ window.addEventListener("scroll", this.handleScrollAndResize);
73
+ window.addEventListener("resize", this.handleScrollAndResize);
74
+ }
75
+
76
+ renderedCallback(): void {
77
+ if (!this.redocInitialized) {
78
+ this.redocInitialized = true;
79
+ this.initializeRedoc();
80
+ }
81
+ }
82
+
83
+ disconnectedCallback(): void {
84
+ window.removeEventListener("scroll", this.handleScrollAndResize);
85
+ window.removeEventListener("resize", this.handleScrollAndResize);
86
+
87
+ this.handleScrollAndResize?.cancel?.();
88
+
89
+ // Clean up cached DOM element references to prevent memory leaks
90
+ this.docHeaderElement = null;
91
+ this.docPhaseWrapperElement = null;
92
+ }
93
+
94
+ // Displays error UI and logs error message for debugging
95
+ private showErrorUI(message: string, error?: any): void {
96
+ this.showError = true;
97
+ console.error(message, error);
98
+ }
99
+
100
+ private getRedocContainer(): HTMLElement | null {
101
+ return document.querySelector(".redoc-container");
102
+ }
103
+
104
+ private getSelectedReference(): ReferenceItem | null {
105
+ return (
106
+ this._referenceConfig?.refList?.find((ref) => ref.isSelected) ||
107
+ this._referenceConfig?.refList?.[0]
108
+ );
109
+ }
110
+
111
+ private getDocPhaseInfo(): string | null {
112
+ if (this._parentDocPhaseInfo) {
113
+ return this._parentDocPhaseInfo;
114
+ }
115
+ const selectedRef = this.getSelectedReference();
116
+ return selectedRef?.docPhase
117
+ ? JSON.stringify(selectedRef.docPhase)
118
+ : null;
119
+ }
120
+
121
+ // Extracts numeric value from CSS custom properties
122
+ private getGlobalCSSVariableValue(variableName: string): number {
123
+ const value = getComputedStyle(
124
+ document.documentElement
125
+ ).getPropertyValue(variableName);
126
+ return parseInt(value, 10) || 0;
127
+ }
128
+
129
+ /*
130
+ ** Since we could not use --dx-g-global-header-height as getPropertyValue returns a calc expression,
131
+ ** we are using the respective CSS variables to calculate the height.
132
+ */
133
+ private getGlobalHeaderHeight(): number {
134
+ const rowHeight = this.getGlobalCSSVariableValue(
135
+ "--dx-g-global-header-nav-row-height"
136
+ );
137
+ const rowCount = this.getGlobalCSSVariableValue(
138
+ "--dx-g-global-header-nav-row-count"
139
+ );
140
+ return rowHeight * rowCount;
141
+ }
142
+
143
+ // Gets doc header height with element caching for performance
144
+ private getDocHeaderHeight(): number {
145
+ if (!this.docHeaderElement) {
146
+ this.docHeaderElement =
147
+ document.querySelector(".sticky-doc-header");
148
+ }
149
+ return this.docHeaderElement?.getBoundingClientRect()?.height || 0;
150
+ }
151
+
152
+ // Gets doc phase wrapper height with element caching for performance
153
+ private getDocPhaseWrapperHeight(): number {
154
+ if (!this.docPhaseWrapperElement) {
155
+ this.docPhaseWrapperElement =
156
+ document.querySelector(".doc-phase-wrapper");
157
+ }
158
+ return (
159
+ this.docPhaseWrapperElement?.getBoundingClientRect()?.height || 0
160
+ );
161
+ }
162
+
163
+ calculateHeaderOffset = () => {
164
+ const globalHeaderHeight = this.getGlobalHeaderHeight();
165
+ const docHeaderHeight = this.getDocHeaderHeight();
166
+ return globalHeaderHeight + docHeaderHeight;
167
+ };
168
+
169
+ // Dynamic scroll offset calculation that Redoc will call
170
+ calculateScrollYOffset = () => {
171
+ const headerOffset = this.calculateHeaderOffset();
172
+ const phaseHeight = this.getDocPhaseWrapperHeight();
173
+ return headerOffset + phaseHeight;
174
+ };
175
+
176
+ // Updates sidebar positioning based on current header heights
177
+ private updateSidebarPosition = () => {
178
+ requestAnimationFrame(() => {
179
+ const redocContainer = this.getRedocContainer();
180
+ if (!redocContainer) {
181
+ return;
182
+ }
183
+
184
+ const currentSidebarTop = this.calculateHeaderOffset();
185
+ if (currentSidebarTop === this.lastSidebarTop) {
186
+ return;
187
+ }
188
+
189
+ const sidebarTopValue = `${currentSidebarTop}px`;
190
+ this.template.host.style.setProperty(
191
+ "--doc-c-redoc-sidebar-top",
192
+ sidebarTopValue
193
+ );
194
+ this.lastSidebarTop = currentSidebarTop;
195
+ });
196
+ };
197
+
198
+ // Updates browser URL while preserving query params and hash
199
+ private updateUrlWithReference(selectedRef: ReferenceItem): void {
200
+ if (selectedRef?.href) {
201
+ const parentReferencePath = selectedRef.href;
202
+ const currentUrl = window.location;
203
+ const existingParams = currentUrl.search + currentUrl.hash;
204
+
205
+ window.history.pushState(
206
+ {},
207
+ "",
208
+ `${parentReferencePath}${existingParams}`
209
+ );
210
+ }
211
+ }
212
+
213
+ private handleScrollAndResize = throttle(
214
+ SCROLL_THROTTLE_DELAY,
215
+ () => !this.showError && this.updateSidebarPosition()
216
+ );
217
+
218
+ // Initializes Redoc library with selected reference configuration
219
+ private async initializeRedoc(): Promise<void> {
220
+ try {
221
+ await this.waitForRedoc();
222
+
223
+ const redocContainer = this.getRedocContainer();
224
+ if (!redocContainer) {
225
+ this.showErrorUI("Redoc container is not found.");
226
+ return;
227
+ }
228
+
229
+ const selectedRef = this.getSelectedReference();
230
+ if (selectedRef) {
231
+ this.updateUrlWithReference(selectedRef);
232
+
233
+ const specUrl = selectedRef.source;
234
+ if (!specUrl) {
235
+ this.showErrorUI("Spec URL not found.");
236
+ return;
237
+ }
238
+
239
+ window.Redoc.init(
240
+ specUrl,
241
+ {
242
+ // Dynamic scroll offset to account for headers
243
+ scrollYOffset: this.calculateScrollYOffset
244
+ },
245
+ redocContainer,
246
+ (error: any) => {
247
+ if (error) {
248
+ this.showErrorUI(
249
+ "Failed to show Reference UI using Redoc: ",
250
+ error
251
+ );
252
+ } else {
253
+ this.integrateCustomComponents();
254
+ }
255
+ }
256
+ );
257
+ }
258
+ } catch (error) {
259
+ this.showErrorUI("Failed to load Redoc library:", error);
260
+ }
261
+ }
262
+
263
+ // Polls for Redoc library availability with timeout
264
+ private async waitForRedoc(timeout = ELEMENT_TIMEOUT): Promise<void> {
265
+ const success = await pollUntil(
266
+ () => !!window.Redoc,
267
+ ELEMENT_CHECK_INTERVAL,
268
+ timeout
269
+ );
270
+
271
+ if (!success) {
272
+ throw new Error(
273
+ "Redoc library failed to load within timeout period"
274
+ );
275
+ }
276
+ }
277
+
278
+ // Integrates custom elements (doc phase, footer, survey) into Redoc container
279
+ private async integrateCustomComponents(): Promise<void> {
280
+ try {
281
+ const redocContainer = this.getRedocContainer();
282
+ if (!redocContainer) {
283
+ return;
284
+ }
285
+
286
+ const apiContentDiv = await this.waitForApiContent(redocContainer);
287
+ apiContentDiv.setAttribute("lwc:dom", "manual");
288
+
289
+ const docPhaseInfo = this.getDocPhaseInfo();
290
+ if (docPhaseInfo) {
291
+ this.insertDocPhase(apiContentDiv, docPhaseInfo);
292
+ }
293
+
294
+ if (typeof Sprig !== "undefined") {
295
+ this.insertSprigSurvey(apiContentDiv);
296
+ }
297
+
298
+ this.insertFooter(apiContentDiv);
299
+
300
+ // Wait for footer to be rendered before updating styles
301
+ requestAnimationFrame(() => {
302
+ this.updateRedocThirdColumnStyle(redocContainer);
303
+
304
+ // Fix initial hash scroll after doc phase insertion
305
+ this.handleInitialHashScrollFix();
306
+ });
307
+ } catch (error) {
308
+ this.showErrorUI("Failed to integrate custom components:", error);
309
+ }
310
+ }
311
+
312
+ // Waits for Redoc's API content element to be rendered
313
+ private async waitForApiContent(
314
+ container: HTMLElement
315
+ ): Promise<HTMLElement> {
316
+ const success = await pollUntil(
317
+ () => !!container.querySelector(".api-content"),
318
+ ELEMENT_CHECK_INTERVAL,
319
+ ELEMENT_TIMEOUT
320
+ );
321
+
322
+ if (!success) {
323
+ throw new Error(
324
+ "Redoc API content element not found within timeout period"
325
+ );
326
+ }
327
+
328
+ return container.querySelector<HTMLElement>(".api-content")!;
329
+ }
330
+
331
+ // Creates and inserts doc phase component at container start
332
+ private insertDocPhase(container: HTMLElement, docPhaseInfo: string): void {
333
+ const wrapper = document.createElement("div");
334
+ wrapper.className = "doc-phase-wrapper";
335
+ container.insertBefore(wrapper, container.firstChild);
336
+
337
+ const docPhaseElement = createElement("doc-phase", { is: DocPhase });
338
+ Object.assign(docPhaseElement, { docPhaseInfo });
339
+ wrapper.appendChild(docPhaseElement);
340
+ }
341
+
342
+ // Appends footer component to container
343
+ private insertFooter(container: HTMLElement): void {
344
+ const footerElement = createElement("dx-footer", { is: DxFooter });
345
+ Object.assign(footerElement, { variant: "no-signup" });
346
+ container.appendChild(footerElement);
347
+ }
348
+
349
+ // Appends Sprig survey component to container
350
+ private insertSprigSurvey(container: HTMLElement): void {
351
+ const wrapper = document.createElement("div");
352
+ wrapper.className = "sprig-survey-wrapper";
353
+ container.appendChild(wrapper);
354
+
355
+ const feedbackElement = createElement("doc-sprig-survey", {
356
+ is: SprigSurvey
357
+ });
358
+ wrapper.appendChild(feedbackElement);
359
+ }
360
+
361
+ // Adjusts third column bottom position to prevent footer overlap
362
+ private updateRedocThirdColumnStyle(redocContainer: HTMLElement): void {
363
+ const footer = redocContainer.querySelector(
364
+ ".redoc-wrap .api-content dx-footer"
365
+ ) as HTMLElement;
366
+ if (!footer) {
367
+ console.warn(
368
+ "Footer element not found, skipping third column styling"
369
+ );
370
+ return;
371
+ }
372
+
373
+ const redocThirdColumnElement = redocContainer.querySelector(
374
+ ".redoc-wrap > div:last-child"
375
+ ) as HTMLElement;
376
+ if (!redocThirdColumnElement) {
377
+ console.warn(
378
+ "Third column element not found, skipping third column styling"
379
+ );
380
+ return;
381
+ }
382
+
383
+ const footerHeight = footer.getBoundingClientRect()?.height || 0;
384
+ const footerMarginTop = parseInt(
385
+ getComputedStyle(this.template.host).getPropertyValue(
386
+ "--dx-footer-margin-top"
387
+ ),
388
+ 10
389
+ );
390
+
391
+ redocThirdColumnElement.style.setProperty(
392
+ "bottom",
393
+ `${footerHeight + footerMarginTop}px`
394
+ );
395
+ }
396
+
397
+ // Fixes initial hash scroll positioning after doc phase insertion
398
+ private handleInitialHashScrollFix(): void {
399
+ const hash = window.location.hash;
400
+ if (!hash || hash.length <= 1) {
401
+ return;
402
+ }
403
+
404
+ // Small delay to ensure all components are fully rendered
405
+ requestAnimationFrame(() => {
406
+ const targetId = hash.substring(1);
407
+ const targetElement = document.getElementById(targetId);
408
+
409
+ if (!targetElement) {
410
+ return;
411
+ }
412
+
413
+ const elementTop =
414
+ (targetElement.getBoundingClientRect()?.top || 0) +
415
+ window.pageYOffset;
416
+ const scrollOffset = this.calculateScrollYOffset();
417
+ const correctedScrollPosition = elementTop - scrollOffset;
418
+
419
+ window.scrollTo({
420
+ top: correctedScrollPosition,
421
+ behavior: "smooth"
422
+ });
423
+ });
424
+ }
425
+ }
@@ -0,0 +1,36 @@
1
+ @import "dxHelpers/reset";
2
+ @import "dxHelpers/text";
3
+ @import "dxHelpers/table";
4
+
5
+ .code {
6
+ color: #181818;
7
+ font-family: Courier, var(--dx-g-font-mono);
8
+ font-size: var(--dx-g-text-sm);
9
+ line-height: 150%;
10
+ background-color: #f4f4f4;
11
+ }
12
+
13
+ table {
14
+ width: 100%;
15
+ }
16
+
17
+ .specification-properties table {
18
+ display: table;
19
+ }
20
+
21
+ .left-border {
22
+ border-left: 1px solid var(--dx-g-gray-90);
23
+ }
24
+
25
+ .icon-cell {
26
+ text-align: center;
27
+ }
28
+
29
+ .icon {
30
+ display: inline-block;
31
+ }
32
+
33
+ .loader {
34
+ pointer-events: none;
35
+ bottom: 30%;
36
+ }