@aws-amplify/ui 6.6.2 → 6.6.4

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/index.js CHANGED
@@ -316,6 +316,23 @@ function splitObject(obj, predicate) {
316
316
  });
317
317
  return [left, right];
318
318
  }
319
+ const cloneDeep = (obj) => {
320
+ if (obj === null || obj === undefined || typeof obj !== 'object') {
321
+ return obj;
322
+ }
323
+ if (obj instanceof Array) {
324
+ return obj.reduce((arr, item, i) => {
325
+ arr[i] = cloneDeep(item);
326
+ return arr;
327
+ }, []);
328
+ }
329
+ if (obj instanceof Object) {
330
+ return Object.keys(obj || {}).reduce((cpObj, key) => {
331
+ cpObj[key] = cloneDeep(obj[key]);
332
+ return cpObj;
333
+ }, {});
334
+ }
335
+ };
319
336
 
320
337
  /**
321
338
  * @example
@@ -448,6 +465,79 @@ function humanFileSize(bytes, si = false, dp = 1) {
448
465
  return bytes.toFixed(dp) + ' ' + units[unit];
449
466
  }
450
467
 
468
+ const OPTIONS = {
469
+ openingCharacter: '{',
470
+ closingCharacter: '}',
471
+ separator: '.',
472
+ };
473
+ const REFERENCE_REGEX = /\{([^}]+)\}/g;
474
+
475
+ /**
476
+ * Checks if the value uses a value reference.
477
+ * @param {string} value
478
+ * @returns {boolean} - True, if the value uses a value reference
479
+ */
480
+ function usesReference(value) {
481
+ const regex = new RegExp(REFERENCE_REGEX);
482
+ if (typeof value === 'string') {
483
+ return regex.test(value);
484
+ }
485
+ if (typeof value === 'object') {
486
+ let hasReference = false;
487
+ // iterate over each property in the object,
488
+ // if any element passes the regex test,
489
+ // the whole thing should be true
490
+ for (const key in value) {
491
+ if (has(value, key)) {
492
+ const element = value[key];
493
+ let reference = usesReference(element);
494
+ if (reference) {
495
+ hasReference = true;
496
+ break;
497
+ }
498
+ }
499
+ }
500
+ return hasReference;
501
+ }
502
+ return false;
503
+ }
504
+ function resolveReference(path, obj) {
505
+ let ref = obj;
506
+ if (!Array.isArray(path)) {
507
+ return;
508
+ }
509
+ for (let i = 0; i < path.length; i++) {
510
+ // Check for undefined as 0 is a valid, truthy value
511
+ if (typeof ref[path[i]] !== 'undefined') {
512
+ ref = ref[path[i]];
513
+ }
514
+ else {
515
+ // set the reference as undefined if we don't find anything
516
+ ref = undefined;
517
+ break;
518
+ }
519
+ }
520
+ return ref;
521
+ }
522
+ /**
523
+ * Returns the path from a path name be splitting the name by a given separator.
524
+ */
525
+ function getPathFromName(pathName) {
526
+ if (typeof pathName !== 'string') {
527
+ throw new Error('Getting path from name failed. Name must be a string');
528
+ }
529
+ return pathName.split(OPTIONS.separator);
530
+ }
531
+ /**
532
+ * Returns the paths name be joining its parts with a given separator.
533
+ */
534
+ function getName(path) {
535
+ if (!path || !(path instanceof Array)) {
536
+ throw new Error('Getting name for path failed. Path must be an array');
537
+ }
538
+ return path.join(OPTIONS.separator);
539
+ }
540
+
451
541
  /**
452
542
  * Handles Amplify JS Auth hub events, by forwarding hub events as appropriate
453
543
  * xstate events.
@@ -5531,6 +5621,70 @@ const alert = {
5531
5621
  },
5532
5622
  };
5533
5623
 
5624
+ const aiConversation = {
5625
+ message: {
5626
+ backgroundColor: { value: '{colors.background.secondary.value}' },
5627
+ borderRadius: { value: '{radii.large.value}' },
5628
+ gap: { value: '{space.small.value}' },
5629
+ paddingBlock: { value: '{space.small.value}' },
5630
+ paddingInline: { value: '{space.small.value}' },
5631
+ user: {
5632
+ backgroundColor: { value: '{colors.background.secondary.value}' },
5633
+ },
5634
+ assistant: {
5635
+ backgroundColor: { value: '{colors.primary.10.value}' },
5636
+ },
5637
+ sender: {
5638
+ gap: { value: '{space.small.value}' },
5639
+ username: {
5640
+ color: { value: '{colors.font.primary.value}' },
5641
+ fontSize: { value: 'inherit' },
5642
+ fontWeight: { value: '{fontWeights.bold.value}' },
5643
+ },
5644
+ timestamp: {
5645
+ color: { value: '{colors.font.tertiary.value}' },
5646
+ fontSize: { value: 'inherit' },
5647
+ fontWeight: { value: 'inherit' },
5648
+ },
5649
+ },
5650
+ body: { gap: { value: '{space.xs.value}' } },
5651
+ },
5652
+ form: {
5653
+ gap: { value: '{space.small.value}' },
5654
+ padding: { value: '{space.small.value}' },
5655
+ },
5656
+ attachment: {
5657
+ borderColor: { value: '{colors.border.secondary.value}' },
5658
+ borderWidth: { value: '{borderWidths.small.value}' },
5659
+ borderRadius: { value: '{radii.small.value}' },
5660
+ fontSize: { value: '{fontSizes.small.value}' },
5661
+ paddingBlock: { value: '{space.xxxs.value}' },
5662
+ paddingInline: { value: '{space.xs.value}' },
5663
+ gap: { value: '{space.xs.value}' },
5664
+ list: {
5665
+ paddingBlockStart: { value: '{space.xs.value}' },
5666
+ gap: { value: '{space.xxs.value}' },
5667
+ },
5668
+ name: {
5669
+ color: { value: '{colors.font.primary.value}' },
5670
+ fontSize: { value: '{fontSizes.small.value}' },
5671
+ fontWeight: { value: '{fontWeights.normal.value}' },
5672
+ },
5673
+ size: {
5674
+ color: { value: '{colors.font.tertiary.value}' },
5675
+ fontSize: { value: '{fontSizes.small.value}' },
5676
+ fontWeight: { value: '{fontWeights.normal.value}' },
5677
+ },
5678
+ remove: {
5679
+ padding: { value: '{space.xxs.value}' },
5680
+ },
5681
+ image: {
5682
+ width: { value: '{fontSizes.medium.value}' },
5683
+ height: { value: '{fontSizes.medium.value}' },
5684
+ },
5685
+ },
5686
+ };
5687
+
5534
5688
  const autocomplete = {
5535
5689
  menu: {
5536
5690
  width: { value: '100%' },
@@ -8171,6 +8325,7 @@ const togglebuttongroup = {
8171
8325
 
8172
8326
  const components = {
8173
8327
  accordion,
8328
+ aiConversation,
8174
8329
  alert,
8175
8330
  authenticator,
8176
8331
  autocomplete,
@@ -8649,35 +8804,6 @@ function deepExtend(objects, collision, path) {
8649
8804
  }
8650
8805
  return target;
8651
8806
  }
8652
- /**
8653
- * Checks if the value uses a value reference.
8654
- * @param {string} value
8655
- * @returns {boolean} - True, if the value uses a value reference
8656
- */
8657
- function usesReference(value) {
8658
- const regex = new RegExp('\\{([^}]+)\\}', 'g');
8659
- if (typeof value === 'string') {
8660
- return regex.test(value);
8661
- }
8662
- if (typeof value === 'object') {
8663
- let hasReference = false;
8664
- // iterate over each property in the object,
8665
- // if any element passes the regex test,
8666
- // the whole thing should be true
8667
- for (const key in value) {
8668
- if (has(value, key)) {
8669
- const element = value[key];
8670
- let reference = usesReference(element);
8671
- if (reference) {
8672
- hasReference = true;
8673
- break;
8674
- }
8675
- }
8676
- }
8677
- return hasReference;
8678
- }
8679
- return false;
8680
- }
8681
8807
 
8682
8808
  function addVars(selector, vars) {
8683
8809
  if (!vars)
@@ -9059,6 +9185,132 @@ function createGlobalCSS(css) {
9059
9185
  return cssText;
9060
9186
  }
9061
9187
 
9188
+ const DEFAULTS = {
9189
+ ignoreKeys: ['original'],
9190
+ };
9191
+ function resolveObject(object) {
9192
+ const foundCirc = {};
9193
+ const clone = cloneDeep(object); // This object will be edited
9194
+ const currentContext = []; // To maintain the context to be able to test for circular definitions
9195
+ if (typeof object === 'object') {
9196
+ return traverseObject({
9197
+ slice: clone,
9198
+ fullObj: clone,
9199
+ currentContext,
9200
+ foundCirc,
9201
+ });
9202
+ }
9203
+ else {
9204
+ throw new Error('Please pass an object in');
9205
+ }
9206
+ }
9207
+ /**
9208
+ * Recursively traverses an object (slice) to resolve and uses
9209
+ * compileValue to replace any string references found within it
9210
+ */
9211
+ function traverseObject({ slice, fullObj, currentContext, foundCirc, }) {
9212
+ for (let key in slice) {
9213
+ if (!has(slice, key)) {
9214
+ continue;
9215
+ }
9216
+ const prop = slice[key];
9217
+ // We want to check for ignoredKeys, this is to
9218
+ // skip over attributes that should not be
9219
+ // mutated, like a copy of the original property.
9220
+ if (DEFAULTS.ignoreKeys && DEFAULTS.ignoreKeys.indexOf(key) !== -1) {
9221
+ continue;
9222
+ }
9223
+ currentContext.push(key);
9224
+ if (typeof prop === 'object') {
9225
+ traverseObject({ currentContext, slice: prop, fullObj, foundCirc });
9226
+ }
9227
+ else {
9228
+ if (typeof prop === 'string' && prop.indexOf('{') > -1) {
9229
+ slice[key] = compileValue({
9230
+ value: prop,
9231
+ stack: [getName(currentContext)],
9232
+ foundCirc,
9233
+ fullObj,
9234
+ });
9235
+ }
9236
+ }
9237
+ currentContext.pop();
9238
+ }
9239
+ return fullObj;
9240
+ }
9241
+ /**
9242
+ * Resolves references in a value, performing recursive lookups when references are nested.
9243
+ * value: The string that may contain references (e.g., {color.border.light}) that need to be replaced
9244
+ * stack: keeps track of the current chain of references to detect circular references
9245
+ * foundCirc: stores any detected circular references
9246
+ * fullObj: The full object where references are looked up, essentially the source of all values
9247
+ */
9248
+ function compileValue({ value, stack, foundCirc, fullObj }) {
9249
+ let toRet = value, ref;
9250
+ const regex = new RegExp(REFERENCE_REGEX);
9251
+ // Replace the reference inline, but don't replace the whole string because
9252
+ // references can be part of the value such as "1px solid {color.border.light}"
9253
+ value.replace(regex, function (match, variable) {
9254
+ variable = variable.trim();
9255
+ // Find what the value is referencing
9256
+ const pathName = getPathFromName(variable);
9257
+ const refHasValue = pathName[pathName.length - 1] === 'value';
9258
+ stack.push(variable);
9259
+ ref = resolveReference(pathName, fullObj);
9260
+ // If the reference doesn't end in 'value'
9261
+ // and
9262
+ // the reference points to someplace that has a `value` attribute
9263
+ // we should take the '.value' of the reference
9264
+ // per the W3C draft spec where references do not have .value
9265
+ // https://design-tokens.github.io/community-group/format/#aliases-references
9266
+ if (!refHasValue && ref && has(ref, 'value')) {
9267
+ ref = ref.value;
9268
+ }
9269
+ if (typeof ref !== 'undefined') {
9270
+ if (typeof ref === 'string' || typeof ref === 'number') {
9271
+ toRet = value.replace(match, ref);
9272
+ // Recursive, therefore we can compute multi-layer variables like a = b, b = c, eventually a = c
9273
+ if (usesReference(toRet)) {
9274
+ var reference = toRet.slice(1, -1);
9275
+ // Compare to found circular references
9276
+ if (has(foundCirc, reference)) ;
9277
+ else if (stack.indexOf(reference) !== -1) {
9278
+ // If the current stack already contains the current reference, we found a new circular reference
9279
+ // chop down only the circular part, save it to our circular reference info, and spit out an error
9280
+ // Get the position of the existing reference in the stack
9281
+ var stackIndexReference = stack.indexOf(reference);
9282
+ // Get the portion of the stack that starts at the circular reference and brings you through until the end
9283
+ var circStack = stack.slice(stackIndexReference);
9284
+ // For all the references in this list, add them to the list of references that end up in a circular reference
9285
+ circStack.forEach(function (key) {
9286
+ foundCirc[key] = true;
9287
+ });
9288
+ // Add our found circular reference to the end of the cycle
9289
+ circStack.push(reference);
9290
+ }
9291
+ else {
9292
+ toRet = compileValue({ value: toRet, stack, foundCirc, fullObj });
9293
+ }
9294
+ }
9295
+ // if evaluated value is a number and equal to the reference, we want to keep the type
9296
+ if (typeof ref === 'number' && ref.toString() === toRet) {
9297
+ toRet = ref;
9298
+ }
9299
+ }
9300
+ else {
9301
+ // if evaluated value is not a string or number, we want to keep the type
9302
+ toRet = ref;
9303
+ }
9304
+ }
9305
+ else {
9306
+ toRet = ref;
9307
+ }
9308
+ stack.pop(variable);
9309
+ return toRet;
9310
+ });
9311
+ return toRet;
9312
+ }
9313
+
9062
9314
  const darkModeTokens = {
9063
9315
  colors: {
9064
9316
  red: {
@@ -9204,6 +9456,7 @@ exports.changePassword = changePassword;
9204
9456
  exports.classNameModifier = classNameModifier;
9205
9457
  exports.classNameModifierByFlag = classNameModifierByFlag;
9206
9458
  exports.classNames = classNames;
9459
+ exports.cloneDeep = cloneDeep;
9207
9460
  exports.countryDialCodes = countryDialCodes;
9208
9461
  exports.createAuthenticatorMachine = createAuthenticatorMachine;
9209
9462
  exports.createComponentCSS = createComponentCSS;
@@ -9211,6 +9464,7 @@ exports.createComponentClasses = createComponentClasses;
9211
9464
  exports.createGlobalCSS = createGlobalCSS;
9212
9465
  exports.createTheme = createTheme;
9213
9466
  exports.cssNameTransform = cssNameTransform;
9467
+ exports.deepExtend = deepExtend;
9214
9468
  exports.defaultAuthHubHandler = defaultAuthHubHandler;
9215
9469
  exports.defaultDarkModeOverride = defaultDarkModeOverride;
9216
9470
  exports.defaultFormFieldOptions = defaultFormFieldOptions;
@@ -9230,8 +9484,10 @@ exports.getErrors = getErrors;
9230
9484
  exports.getFormDataFromEvent = getFormDataFromEvent;
9231
9485
  exports.getFormFields = getFormFields;
9232
9486
  exports.getLogger = getLogger;
9487
+ exports.getName = getName;
9233
9488
  exports.getNextServiceContextFacade = getNextServiceContextFacade;
9234
9489
  exports.getNextServiceFacade = getNextServiceFacade;
9490
+ exports.getPathFromName = getPathFromName;
9235
9491
  exports.getPrimaryAlias = getPrimaryAlias;
9236
9492
  exports.getSendEventAliases = getSendEventAliases;
9237
9493
  exports.getServiceContextFacade = getServiceContextFacade;
@@ -9262,6 +9518,8 @@ exports.noop = noop;
9262
9518
  exports.reactNativeDarkTokens = reactNativeDarkTokens;
9263
9519
  exports.reactNativeTokens = reactNativeTokens;
9264
9520
  exports.removeOrderKeys = removeOrderKeys;
9521
+ exports.resolveObject = resolveObject;
9522
+ exports.resolveReference = resolveReference;
9265
9523
  exports.runFieldValidators = runFieldValidators;
9266
9524
  exports.sanitizeNamespaceImport = sanitizeNamespaceImport;
9267
9525
  exports.setFormOrder = setFormOrder;
@@ -9275,3 +9533,4 @@ exports.templateJoin = templateJoin;
9275
9533
  exports.translate = translate;
9276
9534
  exports.translations = translations;
9277
9535
  exports.trimValues = trimValues;
9536
+ exports.usesReference = usesReference;
@@ -2,13 +2,18 @@
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  height: 100%;
5
+ flex: 1;
5
6
  }
6
7
  .amplify-ai-conversation__message {
7
- --content-bg: transparent;
8
+ --internal-content-bg: ;
9
+ --internal-flex-direction: ;
10
+ --internal-content-padding: ;
11
+ --internal-body-align-items: ;
8
12
  display: flex;
9
- flex-direction: var(--flex-direction);
10
- gap: var(--amplify-space-small);
11
- padding: var(--amplify-space-small);
13
+ flex-direction: var(--internal-flex-direction);
14
+ gap: var(--amplify-components-ai-conversation-message-gap);
15
+ padding-inline: var(--amplify-components-ai-conversation-message-padding-inline);
16
+ padding-block: var(--amplify-components-ai-conversation-message-padding-block);
12
17
  }
13
18
  .amplify-ai-conversation__message__list {
14
19
  display: flex;
@@ -19,89 +24,105 @@
19
24
  }
20
25
  .amplify-ai-conversation__message__sender {
21
26
  display: flex;
22
- flex-direction: var(--flex-direction);
27
+ flex-direction: var(--internal-flex-direction);
23
28
  align-items: center;
24
- height: var(--amplify-components-avatar-height);
25
- gap: var(--amplify-space-small);
29
+ min-height: var(--amplify-components-avatar-height);
30
+ gap: var(--amplify-components-ai-conversation-message-sender-gap);
26
31
  }
27
32
  .amplify-ai-conversation__message__sender__username {
28
- font-weight: bold;
33
+ color: var(--amplify-components-ai-conversation-message-sender-username-color);
34
+ font-size: var(--amplify-components-ai-conversation-message-sender-username-font-size);
35
+ font-weight: var(--amplify-components-ai-conversation-message-sender-username-font-weight);
29
36
  }
30
37
  .amplify-ai-conversation__message__sender__timestamp {
31
- color: var(--amplify-colors-font-tertiary);
32
- font-size: var(--amplify-font-sizes-small);
38
+ color: var(--amplify-components-ai-conversation-message-sender-timestamp-color);
39
+ font-size: var(--amplify-components-ai-conversation-message-sender-timestamp-font-size);
40
+ font-weight: var(--amplify-components-ai-conversation-message-sender-timestamp-font-weight);
33
41
  }
34
42
  .amplify-ai-conversation__message__body {
35
43
  display: flex;
36
44
  flex-direction: column;
37
- align-items: var(--body-align-items);
38
- gap: var(--amplify-space-xs);
45
+ align-items: var(--internal-body-align-items);
46
+ gap: var(--amplify-components-ai-conversation-message-body-gap);
39
47
  }
40
48
  .amplify-ai-conversation__message__content {
41
- background-color: var(--content-bg);
49
+ background-color: var(--internal-content-bg);
42
50
  border-radius: var(--amplify-radii-medium);
43
- padding: var(--content-padding);
51
+ padding: var(--internal-content-padding);
44
52
  }
45
53
  .amplify-ai-conversation__message__actions {
46
54
  display: flex;
47
55
  flex-direction: row;
48
56
  }
49
57
  .amplify-ai-conversation__message--bubble {
50
- --content-bg: var(--bg-color);
51
- --content-padding: var(--amplify-space-xxs) var(--amplify-space-xs);
52
- --flex-direction: row-reverse;
53
- --body-align-items: flex-end;
58
+ --internal-content-bg: var(--internal-bg-color);
59
+ --internal-content-padding: var(--amplify-space-xxs)
60
+ var(--amplify-space-xs);
61
+ --internal-flex-direction: row-reverse;
62
+ --internal-body-align-items: flex-end;
54
63
  }
55
64
  .amplify-ai-conversation__message--user {
56
- --bg-color: var(--amplify-colors-background-secondary);
65
+ --internal-bg-color: var(
66
+ --amplify-components-ai-conversation-message-user-background-color
67
+ );
57
68
  }
58
69
  .amplify-ai-conversation__message--assistant {
59
- --bg-color: var(--amplify-colors-primary-10);
60
- --flex-direction: row;
61
- --body-align-items: flex-start;
70
+ --internal-bg-color: var(
71
+ --amplify-components-ai-conversation-message-assistant-background-color
72
+ );
73
+ --internal-flex-direction: row;
74
+ --internal-body-align-items: flex-start;
62
75
  }
63
76
  .amplify-ai-conversation__form {
64
77
  display: flex;
65
78
  flex-direction: row;
66
79
  align-items: flex-start;
67
- gap: var(--amplify-space-small);
80
+ gap: var(--amplify-components-ai-conversation-form-gap);
81
+ padding: var(--amplify-components-ai-conversation-form-padding);
68
82
  }
69
83
  .amplify-ai-conversation__form__dropzone {
70
84
  text-align: initial;
71
85
  border: none;
72
- padding: var(--amplify-space-xs);
86
+ padding: 0;
73
87
  }
74
88
  .amplify-ai-conversation__attachment {
75
89
  display: flex;
76
90
  flex-direction: row;
77
- padding-block: var(--amplify-space-xxxs);
78
- padding-inline: var(--amplify-space-xs);
79
- border-width: var(--amplify-border-widths-small);
80
- border-style: solid;
81
- border-color: var(--amplify-colors-border-secondary);
82
- border-radius: var(--amplify-radii-small);
83
91
  align-items: center;
84
- gap: var(--amplify-space-xs);
85
- font-size: var(--amplify-font-sizes-small);
92
+ padding-block: var(--amplify-components-ai-conversation-attachment-padding-block);
93
+ padding-inline: var(--amplify-components-ai-conversation-attachment-padding-inline);
94
+ border-width: var(--amplify-components-ai-conversation-attachment-border-width);
95
+ border-style: solid;
96
+ border-color: var(--amplify-components-ai-conversation-attachment-border-color);
97
+ border-radius: var(--amplify-components-ai-conversation-attachment-border-radius);
98
+ gap: var(--amplify-components-ai-conversation-attachment-gap);
99
+ font-size: var(--amplify-components-ai-conversation-attachment-font-size);
86
100
  }
87
101
  .amplify-ai-conversation__attachment__list {
88
102
  display: flex;
89
103
  flex-direction: row;
90
104
  flex-wrap: wrap;
91
- gap: var(--amplify-space-small);
92
- padding-block-start: var(--amplify-space-small);
105
+ gap: var(--amplify-components-ai-conversation-attachment-list-gap);
106
+ padding-block-start: var(--amplify-components-ai-conversation-attachment-padding-block-start);
93
107
  }
94
108
  .amplify-ai-conversation__attachment__image {
95
- width: 1rem;
96
- height: 1rem;
109
+ width: var(--amplify-components-ai-conversation-attachment-image-width);
110
+ height: var(--amplify-components-ai-conversation-attachment-image-height);
97
111
  -o-object-fit: cover;
98
112
  object-fit: cover;
99
113
  }
114
+ .amplify-ai-conversation__attachment__name {
115
+ color: var(--amplify-components-ai-conversation-attachment-name-color);
116
+ font-size: var(--amplify-components-ai-conversation-attachment-name-font-size);
117
+ font-weight: var(--amplify-components-ai-conversation-attachment-name-font-weight);
118
+ }
100
119
  .amplify-ai-conversation__attachment__size {
101
- color: var(--amplify-colors-font-tertiary);
120
+ color: var(--amplify-components-ai-conversation-attachment-size-color);
121
+ font-size: var(--amplify-components-ai-conversation-attachment-size-font-size);
122
+ font-weight: var(--amplify-components-ai-conversation-attachment-size-font-weight);
102
123
  }
103
124
  .amplify-ai-conversation__attachment__remove {
104
- padding: var(--amplify-space-xxs);
125
+ padding: var(--amplify-components-ai-conversation-attachment-remove-padding);
105
126
  }
106
127
  .amplify-ai-conversation__prompt {
107
128
  font-weight: normal;