@cognigy/chat-components-vue 0.1.0 → 0.2.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.
- package/dist/chat-components-vue.css +1 -1
- package/dist/chat-components-vue.js +12222 -5673
- package/dist/components/messages/AdaptiveCardRenderer.vue.d.ts +35 -0
- package/dist/types/index.d.ts +50 -1
- package/dist/utils/helpers.d.ts +3 -2
- package/dist/utils/matcher.d.ts +3 -3
- package/package.json +3 -2
- package/src/components/Message.vue +17 -6
- package/src/components/messages/AdaptiveCard.vue +322 -225
- package/src/components/messages/AdaptiveCardRenderer.vue +260 -0
- package/src/composables/useCollation.ts +28 -45
- package/src/types/index.ts +56 -2
- package/src/utils/helpers.ts +46 -24
- package/src/utils/matcher.ts +20 -6
- package/src/utils/sanitize.ts +1 -2
- package/src/utils/theme.ts +6 -0
|
@@ -1,143 +1,114 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<ChatBubble
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
v-if="hasAdaptiveCard"
|
|
4
|
+
:class="wrapperClasses"
|
|
5
|
+
data-testid="adaptive-card-message"
|
|
6
6
|
>
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
:width="24"
|
|
14
|
-
:height="24"
|
|
15
|
-
fill="none"
|
|
16
|
-
stroke="currentColor"
|
|
17
|
-
stroke-width="2"
|
|
18
|
-
stroke-linecap="round"
|
|
19
|
-
stroke-linejoin="round"
|
|
20
|
-
>
|
|
21
|
-
<rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
|
|
22
|
-
<line x1="9" y1="9" x2="15" y2="9"></line>
|
|
23
|
-
<line x1="9" y1="15" x2="15" y2="15"></line>
|
|
24
|
-
</svg>
|
|
25
|
-
</div>
|
|
26
|
-
|
|
27
|
-
<!-- Card content -->
|
|
28
|
-
<div :class="$style.content">
|
|
29
|
-
<Typography
|
|
30
|
-
variant="title1-semibold"
|
|
31
|
-
component="div"
|
|
32
|
-
:class="$style.title"
|
|
33
|
-
>
|
|
34
|
-
{{ cardTitle }}
|
|
35
|
-
</Typography>
|
|
36
|
-
|
|
37
|
-
<Typography
|
|
38
|
-
v-if="cardBody"
|
|
39
|
-
variant="body-regular"
|
|
40
|
-
component="div"
|
|
41
|
-
:class="$style.body"
|
|
42
|
-
>
|
|
43
|
-
{{ cardBody }}
|
|
44
|
-
</Typography>
|
|
45
|
-
|
|
46
|
-
<div v-if="hasActions" :class="$style.actions">
|
|
47
|
-
<Typography variant="copy-medium" component="span" :class="$style.actionsLabel">
|
|
48
|
-
{{ actionsLabel }}
|
|
49
|
-
</Typography>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
7
|
+
<AdaptiveCardRenderer
|
|
8
|
+
:payload="cardPayload"
|
|
9
|
+
:host-config="adaptiveCardsHostConfig"
|
|
10
|
+
:readonly="isReadonly"
|
|
11
|
+
:input-data="submittedData"
|
|
12
|
+
/>
|
|
53
13
|
</ChatBubble>
|
|
54
14
|
</template>
|
|
55
15
|
|
|
56
16
|
<script setup lang="ts">
|
|
57
|
-
|
|
17
|
+
/**
|
|
18
|
+
* AdaptiveCard - Message component for rendering Microsoft Adaptive Cards
|
|
19
|
+
*
|
|
20
|
+
* This component wraps the AdaptiveCardRenderer in a ChatBubble and handles
|
|
21
|
+
* payload extraction from the message context. It's designed for presentation-only
|
|
22
|
+
* mode (display only, no interactivity).
|
|
23
|
+
*
|
|
24
|
+
* The actual card rendering is handled by the AdaptiveCardRenderer component
|
|
25
|
+
* which uses Microsoft's adaptivecards library.
|
|
26
|
+
*/
|
|
27
|
+
import { computed, useCssModule } from 'vue'
|
|
58
28
|
import ChatBubble from '../common/ChatBubble.vue'
|
|
59
|
-
import
|
|
29
|
+
import AdaptiveCardRenderer from './AdaptiveCardRenderer.vue'
|
|
60
30
|
import { useMessageContext } from '../../composables/useMessageContext'
|
|
61
|
-
import {
|
|
31
|
+
import type { IMessageDataExtended } from '../../types'
|
|
32
|
+
|
|
33
|
+
const styles = useCssModule()
|
|
34
|
+
const { message, config } = useMessageContext()
|
|
62
35
|
|
|
63
36
|
/**
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
37
|
+
* Host configuration for Adaptive Cards styling
|
|
38
|
+
* Matches the React version's configuration
|
|
39
|
+
*
|
|
40
|
+
* Note: foregroundColors are applied as inline styles by the adaptivecards library,
|
|
41
|
+
* so we use actual color values here. For customization, consumers should use
|
|
42
|
+
* the CSS variables (--cc-adaptive-card-text-color) which override via !important.
|
|
43
|
+
*
|
|
44
|
+
* This is typed as a plain object (not Partial<HostConfig>) because the HostConfig
|
|
45
|
+
* constructor accepts plain objects and parses them internally.
|
|
67
46
|
*/
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
47
|
+
const adaptiveCardsHostConfig = {
|
|
48
|
+
fontFamily: 'inherit',
|
|
49
|
+
fontSizes: {
|
|
50
|
+
small: 10,
|
|
51
|
+
default: 14,
|
|
52
|
+
medium: 16,
|
|
53
|
+
large: 18,
|
|
54
|
+
extraLarge: 34,
|
|
55
|
+
},
|
|
56
|
+
fontWeights: {
|
|
57
|
+
lighter: 300,
|
|
58
|
+
default: 400,
|
|
59
|
+
bolder: 600,
|
|
60
|
+
},
|
|
61
|
+
lineHeights: {
|
|
62
|
+
small: 12,
|
|
63
|
+
default: 18.2,
|
|
64
|
+
medium: 22.4,
|
|
65
|
+
large: 23.4,
|
|
66
|
+
extraLarge: 40.8,
|
|
67
|
+
},
|
|
68
|
+
containerStyles: {
|
|
69
|
+
default: {
|
|
70
|
+
backgroundColor: '#fff',
|
|
71
|
+
foregroundColors: {
|
|
72
|
+
default: {
|
|
73
|
+
default: '#333333',
|
|
74
|
+
subtle: '#666666',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
73
79
|
}
|
|
74
80
|
|
|
75
81
|
/**
|
|
76
|
-
*
|
|
82
|
+
* Type-safe access to extended message data
|
|
77
83
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
plugin: AdaptiveCardData | undefined
|
|
82
|
-
}
|
|
84
|
+
const messageData = computed<IMessageDataExtended | undefined>(() => {
|
|
85
|
+
return message?.data as IMessageDataExtended | undefined
|
|
86
|
+
})
|
|
83
87
|
|
|
84
88
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* Note on types: The socket-client types have limitations:
|
|
88
|
-
* - _defaultPreview is typed as `any`
|
|
89
|
-
* - _plugin.data is `any` for adaptivecards type
|
|
90
|
-
* We use runtime type guards to safely access these properties.
|
|
89
|
+
* Check if this message has an adaptive card payload
|
|
91
90
|
*/
|
|
92
|
-
function getAdaptiveCardSources(message: ReturnType<typeof useMessageContext>['message']): AdaptiveCardSources {
|
|
93
|
-
const cognigyData = message?.data?._cognigy
|
|
94
|
-
const pluginData = message?.data?._plugin
|
|
95
|
-
|
|
96
|
-
// _webchat can be IWebchatMessage | IAdaptiveCardMessage - use type guard
|
|
97
|
-
const webchatPayload = cognigyData?._webchat
|
|
98
|
-
const webchat = isAdaptiveCardPayload(webchatPayload)
|
|
99
|
-
? (webchatPayload.adaptiveCard as AdaptiveCardData)
|
|
100
|
-
: undefined
|
|
101
|
-
|
|
102
|
-
// _defaultPreview is typed as `any` in socket-client (upstream limitation)
|
|
103
|
-
// We safely check for adaptiveCard property
|
|
104
|
-
const defaultPreviewPayload = cognigyData?._defaultPreview
|
|
105
|
-
const defaultPreview = isAdaptiveCardPayload(defaultPreviewPayload)
|
|
106
|
-
? (defaultPreviewPayload.adaptiveCard as AdaptiveCardData)
|
|
107
|
-
: undefined
|
|
108
|
-
|
|
109
|
-
// Plugin data can come in two formats:
|
|
110
|
-
// 1. Typed format: { type: 'adaptivecards', data: cardData }
|
|
111
|
-
// 2. Legacy format: { payload: cardData }
|
|
112
|
-
let plugin: AdaptiveCardData | undefined
|
|
113
|
-
if (pluginData) {
|
|
114
|
-
if (pluginData.type === 'adaptivecards' && 'data' in pluginData) {
|
|
115
|
-
plugin = pluginData.data as AdaptiveCardData
|
|
116
|
-
} else if ('payload' in pluginData) {
|
|
117
|
-
plugin = (pluginData as { payload?: unknown }).payload as AdaptiveCardData
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return { webchat, defaultPreview, plugin }
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Message context
|
|
125
|
-
const { message, config } = useMessageContext()
|
|
126
|
-
|
|
127
|
-
// Get all adaptive card sources
|
|
128
|
-
const cardSources = computed(() => getAdaptiveCardSources(message))
|
|
129
|
-
|
|
130
|
-
// Check if this message has an adaptive card
|
|
131
91
|
const hasAdaptiveCard = computed(() => {
|
|
132
|
-
const
|
|
92
|
+
const data = messageData.value
|
|
93
|
+
const webchat = data?._cognigy?._webchat?.adaptiveCard
|
|
94
|
+
const defaultPreview = data?._cognigy?._defaultPreview?.adaptiveCard
|
|
95
|
+
const plugin = data?._plugin?.payload
|
|
96
|
+
|
|
133
97
|
return !!(webchat || defaultPreview || plugin)
|
|
134
98
|
})
|
|
135
99
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Extract the card payload from the message
|
|
102
|
+
* Follows the same priority logic as the React version
|
|
103
|
+
*/
|
|
104
|
+
const cardPayload = computed(() => {
|
|
105
|
+
const data = messageData.value
|
|
106
|
+
const webchat = data?._cognigy?._webchat?.adaptiveCard
|
|
107
|
+
const defaultPreview = data?._cognigy?._defaultPreview?.adaptiveCard
|
|
108
|
+
const plugin = data?._plugin?.payload
|
|
139
109
|
const defaultPreviewEnabled = config?.settings?.widgetSettings?.enableDefaultPreview
|
|
140
110
|
|
|
111
|
+
// Priority: webchat over defaultPreview (unless defaultPreview is enabled)
|
|
141
112
|
if (webchat && defaultPreview && !defaultPreviewEnabled) {
|
|
142
113
|
return webchat
|
|
143
114
|
}
|
|
@@ -148,145 +119,271 @@ const cardPayload = computed((): AdaptiveCardData | undefined => {
|
|
|
148
119
|
})
|
|
149
120
|
|
|
150
121
|
/**
|
|
151
|
-
*
|
|
122
|
+
* Compute wrapper classes
|
|
152
123
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
124
|
+
const wrapperClasses = computed(() => [
|
|
125
|
+
styles.adaptivecardWrapper,
|
|
126
|
+
'adaptivecard-wrapper',
|
|
127
|
+
'internal',
|
|
128
|
+
])
|
|
158
129
|
|
|
159
130
|
/**
|
|
160
|
-
*
|
|
131
|
+
* Extract submitted data from the message
|
|
132
|
+
* This data will be used to pre-fill input fields in the card
|
|
133
|
+
* Checks multiple locations where Cognigy might store the submitted data
|
|
161
134
|
*/
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Try to get from body elements
|
|
182
|
-
const body = card.body
|
|
183
|
-
if (body && Array.isArray(body)) {
|
|
184
|
-
// Look for large text block (likely a title)
|
|
185
|
-
const titleElement = body.find(
|
|
186
|
-
(item): item is AdaptiveCardElement =>
|
|
187
|
-
isTextBlock(item) && item.size === 'large'
|
|
188
|
-
)
|
|
189
|
-
if (titleElement?.text) {
|
|
190
|
-
return titleElement.text
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Fallback to first TextBlock
|
|
194
|
-
const firstText = body.find(isTextBlock)
|
|
195
|
-
if (firstText?.text) {
|
|
196
|
-
return firstText.text
|
|
197
|
-
}
|
|
135
|
+
const submittedData = computed<Record<string, unknown> | undefined>(() => {
|
|
136
|
+
const data = messageData.value
|
|
137
|
+
const webchatData = data?._cognigy?._webchat
|
|
138
|
+
|
|
139
|
+
// Check various locations where submitted data might be stored
|
|
140
|
+
// Priority: request.value > adaptiveCardData > data > formData
|
|
141
|
+
const submittedValue =
|
|
142
|
+
data?.request?.value ||
|
|
143
|
+
webchatData?.adaptiveCardData ||
|
|
144
|
+
webchatData?.data ||
|
|
145
|
+
webchatData?.formData ||
|
|
146
|
+
data?.adaptiveCardData ||
|
|
147
|
+
data?.data ||
|
|
148
|
+
data?.formData
|
|
149
|
+
|
|
150
|
+
if (submittedValue && typeof submittedValue === 'object' && !Array.isArray(submittedValue)) {
|
|
151
|
+
return submittedValue
|
|
198
152
|
}
|
|
199
153
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return card.speak.substring(0, 50)
|
|
203
|
-
}
|
|
154
|
+
return undefined
|
|
155
|
+
})
|
|
204
156
|
|
|
205
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Determine if the card should be rendered in readonly mode
|
|
159
|
+
*
|
|
160
|
+
* Readonly when:
|
|
161
|
+
* - config.settings.behavior.adaptiveCardsReadonly is true (forced presentation mode)
|
|
162
|
+
* - OR submitted data exists (card was already submitted, showing history)
|
|
163
|
+
*/
|
|
164
|
+
const isReadonly = computed(() => {
|
|
165
|
+
const configReadonly = config?.settings?.behavior?.adaptiveCardsReadonly
|
|
166
|
+
return configReadonly === true || submittedData.value !== undefined
|
|
206
167
|
})
|
|
168
|
+
</script>
|
|
207
169
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
170
|
+
<style module>
|
|
171
|
+
/* Main wrapper styles - match React version */
|
|
172
|
+
.adaptivecardWrapper {
|
|
173
|
+
width: 100%;
|
|
174
|
+
box-sizing: border-box;
|
|
175
|
+
max-width: 100%;
|
|
176
|
+
padding: 16px !important;
|
|
177
|
+
}
|
|
214
178
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
isTextBlock(item) && item.text !== titleText
|
|
220
|
-
)
|
|
221
|
-
.map(item => item.text)
|
|
222
|
-
.slice(0, 2) // Limit to first 2 text blocks
|
|
179
|
+
.adaptivecardWrapper > *:focus {
|
|
180
|
+
outline: 1px solid var(--cc-primary-color-focus, #0b3694);
|
|
181
|
+
border-color: var(--cc-primary-color-focus, #0b3694);
|
|
182
|
+
}
|
|
223
183
|
|
|
224
|
-
|
|
225
|
-
|
|
184
|
+
/* Button styles */
|
|
185
|
+
.adaptivecardWrapper :global(button) {
|
|
186
|
+
appearance: none;
|
|
187
|
+
background: var(--cc-primary-color, #0b3694);
|
|
188
|
+
border-radius: 10px;
|
|
189
|
+
border: none;
|
|
190
|
+
color: var(--cc-primary-contrast-color, white);
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
font-size: 14px !important;
|
|
193
|
+
font-weight: 600;
|
|
194
|
+
line-height: 160% !important;
|
|
195
|
+
min-width: 100%;
|
|
196
|
+
padding-block: 11px;
|
|
197
|
+
width: 100%;
|
|
198
|
+
}
|
|
226
199
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
})
|
|
200
|
+
.adaptivecardWrapper :global(button:hover) {
|
|
201
|
+
background: var(--cc-primary-color-hover, #092d7a);
|
|
202
|
+
}
|
|
231
203
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
204
|
+
.adaptivecardWrapper :global(button:focus-visible) {
|
|
205
|
+
outline: 2px solid var(--cc-primary-color-focus, #0b3694);
|
|
206
|
+
outline-offset: 2px;
|
|
207
|
+
}
|
|
236
208
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}
|
|
240
|
-
</script>
|
|
209
|
+
.adaptivecardWrapper :global(button:disabled) {
|
|
210
|
+
background: var(--cc-primary-color-disabled, #999);
|
|
211
|
+
}
|
|
241
212
|
|
|
242
|
-
|
|
243
|
-
.
|
|
244
|
-
|
|
213
|
+
/* Text styles - use CSS variable for customizable font color */
|
|
214
|
+
.adaptivecardWrapper :global(.ac-textRun) {
|
|
215
|
+
color: var(--cc-adaptive-card-text-color, #333) !important;
|
|
216
|
+
font-size: 12px !important;
|
|
217
|
+
line-height: 140%;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Container styles */
|
|
221
|
+
.adaptivecardWrapper :global(.ac-container) {
|
|
222
|
+
border-radius: 15px;
|
|
245
223
|
}
|
|
246
224
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
225
|
+
/* Input styles - use CSS variables for customizable colors */
|
|
226
|
+
.adaptivecardWrapper :global(input),
|
|
227
|
+
.adaptivecardWrapper :global(textarea),
|
|
228
|
+
.adaptivecardWrapper :global(select) {
|
|
229
|
+
align-self: stretch;
|
|
230
|
+
background-position: right 12px center;
|
|
231
|
+
background-repeat: no-repeat;
|
|
232
|
+
background: var(--cc-adaptive-card-input-background, #fff);
|
|
233
|
+
border-radius: 10px;
|
|
234
|
+
border: 1px solid var(--cc-adaptive-card-input-border, #ccc);
|
|
235
|
+
color: var(--cc-adaptive-card-input-color, #333) !important;
|
|
236
|
+
font-size: 14px !important;
|
|
237
|
+
gap: 10px;
|
|
238
|
+
line-height: 140%;
|
|
239
|
+
padding: 8px 12px 8px 12px;
|
|
240
|
+
resize: none;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
@media screen and (max-width: 575px) {
|
|
244
|
+
.adaptivecardWrapper :global(input),
|
|
245
|
+
.adaptivecardWrapper :global(textarea),
|
|
246
|
+
.adaptivecardWrapper :global(select) {
|
|
247
|
+
font-size: 16px !important;
|
|
248
|
+
}
|
|
253
249
|
}
|
|
254
250
|
|
|
255
|
-
.
|
|
256
|
-
|
|
257
|
-
color: var(--cc-primary-color, #1976d2);
|
|
258
|
-
display: flex;
|
|
259
|
-
align-items: flex-start;
|
|
260
|
-
padding-top: 2px;
|
|
251
|
+
.adaptivecardWrapper :global(textarea) {
|
|
252
|
+
min-height: 98px;
|
|
261
253
|
}
|
|
262
254
|
|
|
263
|
-
.
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
255
|
+
:global(.ac-horizontal-separator) {
|
|
256
|
+
height: 16px !important;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.adaptivecardWrapper :global(textarea::-webkit-scrollbar) {
|
|
260
|
+
width: 27px;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.adaptivecardWrapper :global(textarea::-webkit-scrollbar-track) {
|
|
264
|
+
background: transparent;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.adaptivecardWrapper :global(textarea::-webkit-scrollbar-thumb) {
|
|
268
|
+
background-color: var(--cc-black-80, rgba(0, 0, 0, 0.8));
|
|
269
|
+
border-radius: 10px;
|
|
270
|
+
border: 12px solid var(--cc-white, #fff);
|
|
271
|
+
border-block: none;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.adaptivecardWrapper :global(input:focus),
|
|
275
|
+
.adaptivecardWrapper :global(textarea:focus),
|
|
276
|
+
.adaptivecardWrapper :global(select:focus) {
|
|
277
|
+
outline: 1px solid var(--cc-primary-color-focus, #0b3694);
|
|
278
|
+
border-color: var(--cc-primary-color-focus, #0b3694);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.adaptivecardWrapper :global(input:focus-visible),
|
|
282
|
+
.adaptivecardWrapper :global(textarea:focus-visible),
|
|
283
|
+
.adaptivecardWrapper :global(select:focus-visible) {
|
|
284
|
+
outline: 2px solid var(--cc-primary-color-focus, #0b3694);
|
|
285
|
+
border-color: var(--cc-primary-color-focus, #0b3694);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* Action set styles */
|
|
289
|
+
.adaptivecardWrapper :global(.ac-actionSet) {
|
|
290
|
+
flex-wrap: wrap;
|
|
267
291
|
gap: 8px;
|
|
268
|
-
min-width: 0;
|
|
269
292
|
}
|
|
270
293
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
294
|
+
/* Card container styles */
|
|
295
|
+
.adaptivecardWrapper > * {
|
|
296
|
+
background-color: white;
|
|
297
|
+
border-radius: 15px;
|
|
298
|
+
box-shadow: none;
|
|
299
|
+
padding: 0;
|
|
300
|
+
border: 1px solid var(--cc-black-80, #ccc);
|
|
301
|
+
margin: -17px;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/* Checkbox styles */
|
|
305
|
+
.adaptivecardWrapper :global([type='checkbox']) {
|
|
306
|
+
appearance: none;
|
|
307
|
+
background-color: var(--cc-white, #fff);
|
|
308
|
+
border: 1px solid var(--cc-black-60, #666);
|
|
309
|
+
border-radius: 1px;
|
|
310
|
+
width: 16px;
|
|
311
|
+
height: 16px;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.adaptivecardWrapper :global([type='checkbox']:checked) {
|
|
315
|
+
background-color: var(--cc-primary-color, #0b3694);
|
|
316
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12.5172 4.4569C12.8172 4.74256 12.8288 5.2173 12.5431 5.51724L7.19089 11.1371C6.69828 11.6543 5.87315 11.6543 5.38054 11.1371L3.4569 9.11724C3.17123 8.8173 3.18281 8.34256 3.48276 8.0569C3.78271 7.77123 4.25744 7.78281 4.5431 8.08276L6.28572 9.9125L11.4569 4.48276C11.7426 4.18281 12.2173 4.17123 12.5172 4.4569Z' fill='white'/%3E%3C/svg%3E");
|
|
317
|
+
background-position: -1px -1px;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.adaptivecardWrapper :global([type='checkbox']:active) {
|
|
321
|
+
background-color: var(--cc-primary-color-hover, #092d7a);
|
|
322
|
+
border-color: var(--cc-primary-color-hover, #092d7a);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
.adaptivecardWrapper :global([type='checkbox']:checked:hover) {
|
|
326
|
+
background-color: var(--cc-primary-color-hover, #092d7a);
|
|
327
|
+
border-color: var(--cc-primary-color-hover, #092d7a);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.adaptivecardWrapper :global(input:invalid) {
|
|
331
|
+
border-color: red;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/* Date/Time picker icons */
|
|
335
|
+
.adaptivecardWrapper :global([type='date']::-webkit-calendar-picker-indicator),
|
|
336
|
+
.adaptivecardWrapper :global([type='time']::-webkit-calendar-picker-indicator) {
|
|
337
|
+
background: none;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
.adaptivecardWrapper :global([type='date']),
|
|
341
|
+
.adaptivecardWrapper :global([type='time']) {
|
|
342
|
+
background-repeat: no-repeat;
|
|
343
|
+
background-position: right 12px center;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.adaptivecardWrapper :global([type='date']) {
|
|
347
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M3 0.75C3 0.335786 3.33579 0 3.75 0C4.16421 0 4.5 0.335786 4.5 0.75V3H11V0.75C11 0.335786 11.3358 0 11.75 0C12.1642 0 12.5 0.335786 12.5 0.75V3H14C15.1046 3 16 3.89543 16 5V14C16 15.1046 15.1046 16 14 16H2C0.895431 16 0 15.1046 0 14V5C0 3.89543 0.895431 3 2 3H3V0.75ZM1.5 6H14.5V14C14.5 14.2761 14.2761 14.5 14 14.5H2C1.72386 14.5 1.5 14.2761 1.5 14V6Z' fill='%232455E6'/%3E%3C/svg%3E");
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.adaptivecardWrapper :global([type='time']) {
|
|
351
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5ZM8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16Z' fill='%232455E6'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M11.0303 12.0303C10.7374 12.3232 10.2626 12.3232 9.96967 12.0303L7.25 9.31066L7.25 4C7.25 3.58579 7.58578 3.25 8 3.25C8.41421 3.25 8.75 3.58579 8.75 4L8.75 8.68934L11.0303 10.9697C11.3232 11.2626 11.3232 11.7374 11.0303 12.0303Z' fill='%232455E6'/%3E%3C/svg%3E");
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/* Select dropdown styles */
|
|
355
|
+
.adaptivecardWrapper :global(select) {
|
|
356
|
+
appearance: none;
|
|
357
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='none'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M1.34923 4.24022C1.76855 3.8808 2.39985 3.92936 2.75927 4.34869L8.00002 10.4629L13.2408 4.34869C13.6002 3.92936 14.2315 3.8808 14.6508 4.24022C15.0701 4.59965 15.1187 5.23095 14.7593 5.65027L9.51853 11.7645C8.72034 12.6957 7.2797 12.6957 6.4815 11.7645L1.24076 5.65027C0.881339 5.23095 0.929901 4.59965 1.34923 4.24022Z' fill='%232455E6'/%3E%3C/svg%3E");
|
|
358
|
+
background-repeat: no-repeat;
|
|
359
|
+
background-position: right 12px center;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.adaptivecardWrapper :global(select::-ms-expand) {
|
|
363
|
+
display: none;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.adaptivecardWrapper :global(select option) {
|
|
367
|
+
color: var(--cc-adaptive-card-input-color, #333);
|
|
368
|
+
border-bottom: 1px solid var(--cc-black-80, #ccc);
|
|
274
369
|
}
|
|
275
370
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
371
|
+
/* Readonly/disabled state styles */
|
|
372
|
+
.adaptivecardWrapper :global(.ac-readonly) input:disabled,
|
|
373
|
+
.adaptivecardWrapper :global(.ac-readonly) textarea:disabled,
|
|
374
|
+
.adaptivecardWrapper :global(.ac-readonly) select:disabled {
|
|
375
|
+
background-color: var(--cc-black-95, #f5f5f5);
|
|
376
|
+
cursor: not-allowed;
|
|
377
|
+
opacity: 0.8;
|
|
280
378
|
}
|
|
281
379
|
|
|
282
|
-
.
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
border-top: 1px solid var(--cc-black-80, rgba(0, 0, 0, 0.8));
|
|
380
|
+
.adaptivecardWrapper :global(.ac-readonly) button:disabled {
|
|
381
|
+
cursor: not-allowed;
|
|
382
|
+
opacity: 0.6;
|
|
286
383
|
}
|
|
287
384
|
|
|
288
|
-
.
|
|
289
|
-
|
|
290
|
-
|
|
385
|
+
.adaptivecardWrapper :global(.ac-readonly) [type='checkbox']:disabled {
|
|
386
|
+
cursor: not-allowed;
|
|
387
|
+
opacity: 0.6;
|
|
291
388
|
}
|
|
292
389
|
</style>
|