@salesforcedevs/docs-components 0.0.4 → 0.0.5-edit

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 (140) hide show
  1. package/lwc.config.json +25 -2
  2. package/package.json +18 -7
  3. package/src/modules/README.md +41 -0
  4. package/src/modules/doc/amfModelParser/amfModelParser.ts +674 -0
  5. package/src/modules/doc/amfReference/amfReference.css +25 -0
  6. package/src/modules/doc/amfReference/amfReference.html +60 -0
  7. package/src/modules/doc/amfReference/amfReference.ts +1494 -0
  8. package/src/modules/doc/amfReference/constants.ts +76 -0
  9. package/src/modules/doc/amfReference/types.ts +125 -0
  10. package/src/modules/doc/amfTopic/amfTopic.css +21 -0
  11. package/src/modules/doc/amfTopic/amfTopic.html +3 -0
  12. package/src/modules/doc/amfTopic/amfTopic.ts +111 -0
  13. package/src/modules/doc/amfTopic/types.ts +56 -0
  14. package/src/modules/doc/amfTopic/utils.ts +136 -0
  15. package/src/modules/doc/breadcrumbItem/breadcrumbItem.css +51 -0
  16. package/src/modules/doc/breadcrumbItem/breadcrumbItem.html +5 -0
  17. package/src/modules/doc/breadcrumbItem/breadcrumbItem.ts +71 -0
  18. package/src/modules/doc/breadcrumbs/breadcrumbs.css +27 -0
  19. package/src/modules/doc/breadcrumbs/breadcrumbs.html +58 -0
  20. package/src/modules/doc/breadcrumbs/breadcrumbs.ts +183 -0
  21. package/src/modules/doc/chat/README.md +179 -0
  22. package/src/modules/doc/chat/chat.css +821 -0
  23. package/src/modules/doc/chat/chat.html +241 -0
  24. package/src/modules/doc/chat/chat.ts +586 -0
  25. package/src/modules/doc/componentPlayground/componentPlayground.css +22 -0
  26. package/src/modules/doc/componentPlayground/componentPlayground.html +20 -0
  27. package/src/modules/doc/componentPlayground/componentPlayground.ts +29 -0
  28. package/src/modules/doc/content/content.css +382 -6
  29. package/src/modules/doc/content/content.html +3 -2
  30. package/src/modules/doc/content/content.ts +287 -110
  31. package/src/modules/doc/contentCallout/contentCallout.css +25 -26
  32. package/src/modules/doc/contentCallout/contentCallout.html +13 -4
  33. package/src/modules/doc/contentCallout/contentCallout.ts +22 -11
  34. package/src/modules/doc/contentLayout/contentLayout.css +13 -0
  35. package/src/modules/doc/contentLayout/contentLayout.html +73 -0
  36. package/src/modules/doc/contentLayout/contentLayout.ts +531 -0
  37. package/src/modules/doc/contentMedia/contentMedia.css +49 -0
  38. package/src/modules/doc/contentMedia/contentMedia.html +23 -0
  39. package/src/modules/doc/contentMedia/contentMedia.ts +34 -0
  40. package/src/modules/doc/doDont/doDont.css +47 -0
  41. package/src/modules/doc/doDont/doDont.html +27 -0
  42. package/src/modules/doc/doDont/doDont.ts +17 -0
  43. package/src/modules/doc/editFile/editFile.css +505 -0
  44. package/src/modules/doc/editFile/editFile.html +164 -0
  45. package/src/modules/doc/editFile/editFile.ts +213 -0
  46. package/src/modules/doc/header/header.css +132 -0
  47. package/src/modules/doc/header/header.html +55 -0
  48. package/src/modules/doc/header/header.ts +120 -0
  49. package/src/modules/doc/heading/heading.css +33 -0
  50. package/src/modules/doc/heading/heading.html +14 -0
  51. package/src/modules/doc/heading/heading.ts +67 -0
  52. package/src/modules/doc/headingAnchor/headingAnchor.css +33 -0
  53. package/src/modules/doc/headingAnchor/headingAnchor.html +19 -0
  54. package/src/modules/doc/headingAnchor/headingAnchor.ts +43 -0
  55. package/src/modules/doc/headingContent/headingContent.css +53 -0
  56. package/src/modules/doc/headingContent/headingContent.html +13 -0
  57. package/src/modules/doc/headingContent/headingContent.ts +30 -0
  58. package/src/modules/doc/lwcContentLayout/lwcContentLayout.css +1 -0
  59. package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +68 -0
  60. package/src/modules/doc/lwcContentLayout/lwcContentLayout.ts +168 -0
  61. package/src/modules/doc/nav/nav.css +4 -2
  62. package/src/modules/doc/nav/nav.html +8 -13
  63. package/src/modules/doc/nav/nav.ts +1 -1
  64. package/src/modules/doc/overview/overview.css +40 -0
  65. package/src/modules/doc/overview/overview.html +34 -0
  66. package/src/modules/doc/overview/overview.ts +12 -0
  67. package/src/modules/doc/phase/phase.css +70 -0
  68. package/src/modules/doc/phase/phase.html +38 -0
  69. package/src/modules/doc/phase/phase.ts +93 -0
  70. package/src/modules/doc/specificationContent/specificationContent.css +36 -0
  71. package/src/modules/doc/specificationContent/specificationContent.html +171 -0
  72. package/src/modules/doc/specificationContent/specificationContent.ts +127 -0
  73. package/src/modules/doc/sprigSurvey/sprigSurvey.html +20 -0
  74. package/src/modules/doc/sprigSurvey/sprigSurvey.scoped.css +16 -0
  75. package/src/modules/doc/sprigSurvey/sprigSurvey.ts +16 -0
  76. package/src/modules/doc/toc/toc.html +11 -6
  77. package/src/modules/doc/toc/toc.ts +2 -6
  78. package/src/modules/doc/toolbar/toolbar.html +8 -1
  79. package/src/modules/doc/toolbar/toolbar.ts +1 -1
  80. package/src/modules/doc/versionPicker/versionPicker.css +64 -0
  81. package/src/modules/doc/versionPicker/versionPicker.html +38 -0
  82. package/src/modules/doc/versionPicker/versionPicker.ts +65 -0
  83. package/src/modules/doc/xmlContent/types.ts +120 -0
  84. package/src/modules/doc/xmlContent/utils.ts +163 -0
  85. package/src/modules/doc/xmlContent/xmlContent.css +54 -0
  86. package/src/modules/doc/xmlContent/xmlContent.html +52 -0
  87. package/src/modules/doc/xmlContent/xmlContent.ts +792 -0
  88. package/src/modules/docHelpers/amfStyle/amfStyle.css +355 -0
  89. package/src/modules/docHelpers/contentLayoutStyle/contentLayoutStyle.css +131 -0
  90. package/src/modules/docHelpers/imgStyle/imgStyle.css +59 -0
  91. package/src/modules/docHelpers/status/status.css +22 -0
  92. package/src/modules/docUtils/searchSyncer/searchSyncer.ts +86 -0
  93. package/src/modules/docUtils/utils/__mocks__/coveo.analytics.ts +16 -0
  94. package/src/modules/docUtils/utils/coveo.analytics.d.ts +10 -0
  95. package/src/modules/docUtils/utils/utils.ts +32 -0
  96. package/src/modules/doc/container/__benchmarks__/container.benchmark.js +0 -43
  97. package/src/modules/doc/container/__mocks__/mockAvailableLanguages.js +0 -8
  98. package/src/modules/doc/container/__mocks__/mockAvailableVersions.js +0 -122
  99. package/src/modules/doc/container/__mocks__/mockContentFetchResponse.json +0 -5
  100. package/src/modules/doc/container/__mocks__/mockDocContent.js +0 -29
  101. package/src/modules/doc/container/__mocks__/mockNavigationFetchResponse.json +0 -4061
  102. package/src/modules/doc/container/__mocks__/mockPageReference.js +0 -8
  103. package/src/modules/doc/container/__mocks__/mockPdfUrl.js +0 -1
  104. package/src/modules/doc/container/__mocks__/mockSelectedLanguage.js +0 -8
  105. package/src/modules/doc/container/__mocks__/mockSelectedVersion.js +0 -8
  106. package/src/modules/doc/container/__mocks__/mockToc.js +0 -146
  107. package/src/modules/doc/container/__tests__/container.test.ts +0 -82
  108. package/src/modules/doc/container/container.css +0 -33
  109. package/src/modules/doc/container/container.html +0 -23
  110. package/src/modules/doc/container/container.stories.ts +0 -18
  111. package/src/modules/doc/container/container.ts +0 -360
  112. package/src/modules/doc/content/__tests__/content.test.ts +0 -30
  113. package/src/modules/doc/content/__tests__/mockDocContent.ts +0 -29
  114. package/src/modules/doc/content/__tests__/mockPageReference.ts +0 -8
  115. package/src/modules/doc/contentCallout/__tests__/contentCallout.test.ts +0 -80
  116. package/src/modules/doc/contentCallout/__tests__/mockProps.ts +0 -14
  117. package/src/modules/doc/contentCallout/contentCallout.stories.ts +0 -29
  118. package/src/modules/doc/nav/__tests__/mockAvailableLanguages.ts +0 -8
  119. package/src/modules/doc/nav/__tests__/mockAvailableVersions.ts +0 -122
  120. package/src/modules/doc/nav/__tests__/mockPageReference.ts +0 -8
  121. package/src/modules/doc/nav/__tests__/mockPdfUrl.ts +0 -1
  122. package/src/modules/doc/nav/__tests__/mockSelectedLanguage.ts +0 -8
  123. package/src/modules/doc/nav/__tests__/mockSelectedVersion.ts +0 -8
  124. package/src/modules/doc/nav/__tests__/mockToc.ts +0 -146
  125. package/src/modules/doc/nav/__tests__/nav.test.ts +0 -66
  126. package/src/modules/doc/prismcss/prismcss.css +0 -184
  127. package/src/modules/doc/prismjs/prismjs.html +0 -3
  128. package/src/modules/doc/prismjs/prismjs.ts +0 -1842
  129. package/src/modules/doc/search/__tests__/search.test.ts +0 -20
  130. package/src/modules/doc/search/search.html +0 -1
  131. package/src/modules/doc/search/search.ts +0 -3
  132. package/src/modules/doc/toc/__tests__/mockPageReference.ts +0 -8
  133. package/src/modules/doc/toc/__tests__/mockToc.ts +0 -146
  134. package/src/modules/doc/toc/__tests__/toc.test.ts +0 -29
  135. package/src/modules/doc/toolbar/__tests__/mockAvailableLanguages.ts +0 -8
  136. package/src/modules/doc/toolbar/__tests__/mockAvailableVersions.ts +0 -122
  137. package/src/modules/doc/toolbar/__tests__/mockPdfUrl.ts +0 -1
  138. package/src/modules/doc/toolbar/__tests__/mockSelectedLanguage.ts +0 -8
  139. package/src/modules/doc/toolbar/__tests__/mockSelectedVersion.ts +0 -8
  140. package/src/modules/doc/toolbar/__tests__/toolbar.test.ts +0 -44
@@ -0,0 +1,58 @@
1
+ <template>
2
+ <nav role="navigation" aria-label={ariaLabel}>
3
+ <template if:true={displayCrumbs}>
4
+ <template if:false={renderSmallVariant}>
5
+ <doc-breadcrumb-item
6
+ href={firstCrumb.href}
7
+ label={firstCrumb.label}
8
+ breadcrumb-labels={breadcrumbLabels}
9
+ ></doc-breadcrumb-item>
10
+ <span class="breadcrumb-item_slash">/</span>
11
+ <template if:true={renderDropdown}>
12
+ <dx-dropdown
13
+ analytics-event="custEv_breadcrumbClick"
14
+ analytics-payload={ANALYTICS_PAYLOAD}
15
+ if:true={renderDropdown}
16
+ options={dropdownOptions}
17
+ open-on-hover
18
+ placement="bottom"
19
+ variant="indented"
20
+ width="fit-content"
21
+ >
22
+ <dx-button
23
+ aria-label="Open Breadcrumbs Dropdown"
24
+ icon-size="large"
25
+ icon-symbol="threedots"
26
+ variant="tertiary"
27
+ ></dx-button>
28
+ </dx-dropdown>
29
+ <span class="breadcrumb-item_slash">/</span>
30
+ </template>
31
+ <template for:each={breadcrumbItems} for:item="breadcrumb">
32
+ <doc-breadcrumb-item
33
+ href={breadcrumb.href}
34
+ key={breadcrumb.id}
35
+ label={breadcrumb.label}
36
+ level={breadcrumb.level}
37
+ breadcrumb-labels={breadcrumbLabels}
38
+ ></doc-breadcrumb-item>
39
+ <span class="breadcrumb-item_slash" key={breadcrumb.label}>
40
+ /
41
+ </span>
42
+ </template>
43
+ <doc-breadcrumb-item
44
+ label={lastCrumb.label}
45
+ breadcrumb-labels={breadcrumbLabels}
46
+ ></doc-breadcrumb-item>
47
+ </template>
48
+ <template if:true={renderSmallVariant}>
49
+ <doc-breadcrumb-item
50
+ href={lastLinkCrump.href}
51
+ label={lastLinkCrump.label}
52
+ breadcrumb-labels={breadcrumbLabels}
53
+ variant="back-arrow"
54
+ ></doc-breadcrumb-item>
55
+ </template>
56
+ </template>
57
+ </nav>
58
+ </template>
@@ -0,0 +1,183 @@
1
+ import { LightningElement, api } from "lwc";
2
+ import { Breadcrumb, OptionWithLink } from "typings/custom";
3
+ import { toJson } from "dxUtils/normalizers";
4
+
5
+ type BreadcrumbConfig = {
6
+ minWidth: number;
7
+ crumbsInDropdown: number;
8
+ };
9
+
10
+ const GAP = 8;
11
+
12
+ // Unit in pixels based on Salesforce Sans font-family.
13
+ const CONSTANTS = {
14
+ pixelPerCharacter: 7.7,
15
+ pixelPerCrumbSpace: GAP * 2 + 8.6,
16
+ minWidthPerCrumb: 200,
17
+ dropdownWidth: 32
18
+ };
19
+
20
+ export default class Breadcrumbs extends LightningElement {
21
+ @api ariaLabel: string = "Documentation Breadcrumbs";
22
+
23
+ @api
24
+ get breadcrumbs(): Breadcrumb[] {
25
+ return this._breadcrumbs;
26
+ }
27
+
28
+ set breadcrumbs(value) {
29
+ this.normalizeAndAssignBreadcrumbs(value);
30
+ this.calculateBreadcrumbsConfigs();
31
+ if (this.isRendered) {
32
+ this.onWidthOrContentChange();
33
+ }
34
+ }
35
+
36
+ @api
37
+ get pixelPerCharacter(): number {
38
+ return this._pixelPerCharacter;
39
+ }
40
+
41
+ set pixelPerCharacter(value: number | string) {
42
+ this._pixelPerCharacter = +value;
43
+ }
44
+
45
+ private _breadcrumbs: Breadcrumb[] = [];
46
+ private _pixelPerCharacter = CONSTANTS.pixelPerCharacter;
47
+ private navWidth = 0;
48
+ private breadcrumbConfigs: BreadcrumbConfig[] = [];
49
+ private dropdownOptionAmount? = 0;
50
+ private isRendered = false;
51
+
52
+ private get renderSmallVariant(): boolean {
53
+ return (
54
+ !this.dropdownOptionAmount &&
55
+ this.dropdownOptionAmount !== 0 &&
56
+ !!this.lastLinkCrump
57
+ );
58
+ }
59
+
60
+ private get lastLinkCrump(): Breadcrumb {
61
+ return this.breadcrumbs[this.breadcrumbs.length - 2];
62
+ }
63
+
64
+ private get hasInternalBreadcrumbs(): boolean {
65
+ return this.breadcrumbs.length > 2;
66
+ }
67
+
68
+ private get breadcrumbItems(): Breadcrumb[] {
69
+ return this.breadcrumbs!.slice(
70
+ this.dropdownOptionAmount! + 1,
71
+ this._breadcrumbs.length - 1
72
+ );
73
+ }
74
+
75
+ private get renderDropdown(): boolean {
76
+ return this.hasInternalBreadcrumbs && !!this.dropdownOptionAmount;
77
+ }
78
+ private get dropdownOptions(): OptionWithLink[] {
79
+ return this.breadcrumbs!.slice(1, this.dropdownOptionAmount! + 1).map(
80
+ (link) => ({
81
+ id: link.id!,
82
+ label: link.label,
83
+ link: { href: link.href! }
84
+ })
85
+ );
86
+ }
87
+
88
+ private get displayCrumbs(): boolean {
89
+ return this.breadcrumbs.length > 1;
90
+ }
91
+
92
+ private get firstCrumb(): Breadcrumb {
93
+ return this.breadcrumbs[0];
94
+ }
95
+
96
+ private get breadcrumbLabels(): string {
97
+ return this.breadcrumbs.map((crumb) => crumb.label).join(":");
98
+ }
99
+
100
+ private get lastCrumb(): Breadcrumb {
101
+ return this.breadcrumbs[this.breadcrumbs.length - 1];
102
+ }
103
+
104
+ // this payload is only used for breadcrumb dropdown
105
+ private get ANALYTICS_PAYLOAD() {
106
+ return {
107
+ element_type: "link",
108
+ nav_type: "breadcrumb",
109
+ nav_level: 1
110
+ };
111
+ }
112
+
113
+ private onWidthOrContentChange = () => {
114
+ this.navWidth = this.template
115
+ .querySelector("nav")!
116
+ .getBoundingClientRect().width;
117
+ this.updateDropdownOptionAmount();
118
+ };
119
+
120
+ renderedCallback(): void {
121
+ this.isRendered = true;
122
+ this.onWidthOrContentChange();
123
+ window.addEventListener("resize", this.onWidthOrContentChange);
124
+ }
125
+
126
+ disconnectedCallback(): void {
127
+ window.removeEventListener("resize", this.onWidthOrContentChange);
128
+ }
129
+
130
+ private normalizeAndAssignBreadcrumbs(breadcrumbs?: Breadcrumb[] | string) {
131
+ if (!breadcrumbs) {
132
+ return;
133
+ }
134
+
135
+ this._breadcrumbs = toJson(breadcrumbs).map(
136
+ (crumb: Breadcrumb, index: number) => ({
137
+ ...crumb,
138
+ id: crumb.id || crumb.href,
139
+ level: index
140
+ })
141
+ );
142
+ }
143
+
144
+ private updateDropdownOptionAmount(): void {
145
+ this.dropdownOptionAmount = this.breadcrumbConfigs.find(
146
+ ({ minWidth }) => minWidth <= this.navWidth
147
+ )?.crumbsInDropdown;
148
+ }
149
+
150
+ private calculateBreadcrumbsConfigs(): void {
151
+ this.breadcrumbConfigs = [
152
+ ...Array(this._breadcrumbs.length - 1).keys()
153
+ ].map((optionsAmount) => {
154
+ const breadcrumbs = [...this._breadcrumbs];
155
+ breadcrumbs.splice(1, optionsAmount);
156
+ return {
157
+ crumbsInDropdown: optionsAmount,
158
+ minWidth: this.reduceBreadcrumbs(
159
+ breadcrumbs,
160
+ optionsAmount
161
+ ? CONSTANTS.dropdownWidth + CONSTANTS.pixelPerCrumbSpace
162
+ : 0
163
+ )
164
+ };
165
+ });
166
+ }
167
+
168
+ private reduceBreadcrumbs(
169
+ breadcrumbs: Breadcrumb[],
170
+ offset: number = 0
171
+ ): number {
172
+ return breadcrumbs.reduce(
173
+ (previousValue, element) =>
174
+ previousValue +
175
+ Math.min(
176
+ element.label.length *
177
+ (this.pixelPerCharacter || CONSTANTS.pixelPerCharacter),
178
+ CONSTANTS.minWidthPerCrumb
179
+ ),
180
+ (breadcrumbs.length - 1) * CONSTANTS.pixelPerCrumbSpace + offset
181
+ );
182
+ }
183
+ }
@@ -0,0 +1,179 @@
1
+ # Sliding Chat Component (doc-chat)
2
+
3
+ A self-contained sliding chat component with a floating trigger button that can be embedded in any layout, perfect for customer support, documentation help, or any conversational interface.
4
+
5
+ ## Features
6
+
7
+ - 🎯 **Sliding Component**: Slides in/out with smooth animations
8
+ - 🔘 **Floating Trigger**: Built-in floating button to open chat (bottom-right corner)
9
+ - 💬 **Real-time Chat**: Interactive messaging with typing indicators
10
+ - 🎨 **Modern Design**: Clean, responsive interface with subtle animations
11
+ - ⚙️ **Configurable**: Customizable title, placeholder, and assistant name
12
+ - 📱 **Mobile Friendly**: Full-width on mobile devices
13
+ - ♿ **Accessible**: ARIA labels and keyboard navigation
14
+ - 🎭 **Storybook Ready**: Multiple story variations for testing
15
+
16
+ ## Basic Usage
17
+
18
+ The component is completely self-contained with a built-in floating trigger button:
19
+
20
+ ```html
21
+ <doc-chat
22
+ title="Customer Support"
23
+ placeholder="How can we help you today?"
24
+ assistant-name="Support Bot"
25
+ is-open="false"
26
+ show-timestamp="true"
27
+ ></doc-chat>
28
+ ```
29
+
30
+ That's it! The component will automatically show a floating chat button in the bottom-right corner when closed, and slide in the chat interface when opened.
31
+
32
+ ## Properties
33
+
34
+ | Property | Type | Default | Description |
35
+ |----------|------|---------|-------------|
36
+ | `title` | String | `"Chat"` | Title displayed in the chat header |
37
+ | `placeholder` | String | `"Type your message..."` | Placeholder text for input field |
38
+ | `assistant-name` | String | `"Assistant"` | Name of the assistant/bot |
39
+ | `disabled` | Boolean | `false` | Disables the chat functionality |
40
+ | `show-timestamp` | Boolean | `false` | Shows timestamps on messages |
41
+ | `is-open` | Boolean | `false` | Controls sidebar visibility |
42
+
43
+ ## Methods
44
+
45
+ | Method | Description |
46
+ |--------|-------------|
47
+ | `openChat()` | Opens the chat sidebar |
48
+ | `closeChat()` | Closes the chat sidebar |
49
+
50
+ ## Events
51
+
52
+ | Event | Description | Detail |
53
+ |-------|-------------|--------|
54
+ | `chatopened` | Fired when chat is opened | `{ opened: true }` |
55
+ | `chatclosed` | Fired when chat is closed | `{ closed: true }` |
56
+
57
+ ## Integration Example
58
+
59
+ ### Simple Integration (Self-Contained)
60
+ ```html
61
+ <!-- The component includes its own trigger button -->
62
+ <doc-chat
63
+ title="Customer Support"
64
+ placeholder="How can we help you today?"
65
+ assistant-name="Support Bot"
66
+ show-timestamp="true"
67
+ is-open="false"
68
+ ></doc-chat>
69
+ ```
70
+
71
+ ### Advanced Integration (With Custom Triggers)
72
+ ```html
73
+ <!-- Optional: Custom trigger button -->
74
+ <button id="chat-trigger" onclick="openSupportChat()">
75
+ 💬 Need Help?
76
+ </button>
77
+
78
+ <!-- Chat component -->
79
+ <doc-chat
80
+ id="support-chat"
81
+ title="Customer Support"
82
+ placeholder="How can we help you today?"
83
+ assistant-name="Support Bot"
84
+ show-timestamp="true"
85
+ is-open="false"
86
+ ></doc-chat>
87
+ ```
88
+
89
+ ### JavaScript
90
+ ```javascript
91
+ // Optional: Custom trigger function
92
+ function openSupportChat() {
93
+ const chat = document.getElementById('support-chat');
94
+ chat.openChat();
95
+ }
96
+
97
+ // Listen for chat events
98
+ document.getElementById('support-chat').addEventListener('chatclosed', (event) => {
99
+ console.log('Chat was closed');
100
+ });
101
+
102
+ document.getElementById('support-chat').addEventListener('chatopened', (event) => {
103
+ console.log('Chat was opened');
104
+ });
105
+ ```
106
+
107
+ ## Styling
108
+
109
+ The component uses CSS custom properties for easy theming:
110
+
111
+ ```css
112
+ doc-chat {
113
+ --chat-width: 400px;
114
+ --chat-z-index: 1000;
115
+ --chat-transition-duration: 0.3s;
116
+ --chat-header-bg: #f8f9fa;
117
+ --chat-primary-color: #0066cc;
118
+ --chat-border-color: #e0e0e0;
119
+ }
120
+ ```
121
+
122
+ ## Responsive Behavior
123
+
124
+ - **Desktop**: Fixed width component (400px)
125
+ - **Tablet**: Full width component
126
+ - **Mobile**: Full width component
127
+
128
+ ## Accessibility
129
+
130
+ - ARIA labels for screen readers
131
+ - Keyboard navigation support
132
+ - High contrast mode support
133
+ - Reduced motion preferences respected
134
+
135
+ ## Assistant Response Simulation
136
+
137
+ The component includes a built-in response simulation system that responds to:
138
+
139
+ - **Greetings**: "Hello", "Hi" → Friendly greeting
140
+ - **Help requests**: "Help" → Assistance offer
141
+ - **Documentation**: "Documentation", "Docs" → Navigation help
142
+ - **General messages**: Contextual responses
143
+
144
+ ### Replacing with Real API
145
+
146
+ To integrate with a real chat API, replace the `simulateAssistantResponse` method:
147
+
148
+ ```javascript
149
+ // Replace this method in your extended component
150
+ simulateAssistantResponse(userMessage) {
151
+ // Call your chat API
152
+ fetch('/api/chat', {
153
+ method: 'POST',
154
+ headers: { 'Content-Type': 'application/json' },
155
+ body: JSON.stringify({ message: userMessage })
156
+ })
157
+ .then(response => response.json())
158
+ .then(data => {
159
+ this.addMessage(data.response, 'assistant');
160
+ });
161
+ }
162
+ ```
163
+
164
+ ## Browser Support
165
+
166
+ - Chrome 80+
167
+ - Firefox 72+
168
+ - Safari 13+
169
+ - Edge 80+
170
+
171
+ ## Examples
172
+
173
+ Check out the Storybook examples for various use cases:
174
+
175
+ - **Default**: Basic chat setup
176
+ - **With Timestamps**: Shows message timestamps
177
+ - **Interactive Demo**: Fully functional example
178
+ - **Mobile View**: Mobile device simulation
179
+ - **Chat Trigger Example**: Integration patterns