@cloudscape-design/components-themeable 3.0.1314 → 3.0.1316

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/lib/internal/manifest.json +1 -1
  2. package/lib/internal/scss/internal/generated/custom-css-properties/index.scss +1 -1
  3. package/lib/internal/scss/link/styles.scss +16 -0
  4. package/lib/internal/scss/side-navigation/styles.scss +221 -48
  5. package/lib/internal/scss/side-navigation/test-classes/styles.scss +4 -0
  6. package/lib/internal/scss/top-navigation/test-classes/styles.scss +8 -0
  7. package/lib/internal/template/file-token-group/file-token.d.ts.map +1 -1
  8. package/lib/internal/template/file-token-group/file-token.js +33 -27
  9. package/lib/internal/template/file-token-group/file-token.js.map +1 -1
  10. package/lib/internal/template/internal/base-component/styles.scoped.css +13 -1
  11. package/lib/internal/template/internal/breakpoints.d.ts +1 -1
  12. package/lib/internal/template/internal/breakpoints.d.ts.map +1 -1
  13. package/lib/internal/template/internal/breakpoints.js +25 -3
  14. package/lib/internal/template/internal/breakpoints.js.map +1 -1
  15. package/lib/internal/template/internal/environment.js +2 -2
  16. package/lib/internal/template/internal/environment.json +2 -2
  17. package/lib/internal/template/internal/generated/styles/tokens.d.ts +5 -0
  18. package/lib/internal/template/internal/generated/styles/tokens.js +5 -0
  19. package/lib/internal/template/internal/generated/theming/index.cjs +99 -0
  20. package/lib/internal/template/internal/generated/theming/index.cjs.d.ts +36 -0
  21. package/lib/internal/template/internal/generated/theming/index.d.ts +36 -0
  22. package/lib/internal/template/internal/generated/theming/index.js +99 -0
  23. package/lib/internal/template/internal/hooks/container-queries/use-container-breakpoints.d.ts.map +1 -1
  24. package/lib/internal/template/internal/hooks/container-queries/use-container-breakpoints.js +2 -1
  25. package/lib/internal/template/internal/hooks/container-queries/use-container-breakpoints.js.map +1 -1
  26. package/lib/internal/template/link/internal.js +1 -1
  27. package/lib/internal/template/link/internal.js.map +1 -1
  28. package/lib/internal/template/link/styles.css.js +21 -21
  29. package/lib/internal/template/link/styles.scoped.css +118 -72
  30. package/lib/internal/template/link/styles.selectors.js +21 -21
  31. package/lib/internal/template/prompt-input/index.d.ts.map +1 -1
  32. package/lib/internal/template/prompt-input/index.js +3 -1
  33. package/lib/internal/template/prompt-input/index.js.map +1 -1
  34. package/lib/internal/template/side-navigation/implementation.d.ts +1 -1
  35. package/lib/internal/template/side-navigation/implementation.d.ts.map +1 -1
  36. package/lib/internal/template/side-navigation/implementation.js +4 -4
  37. package/lib/internal/template/side-navigation/implementation.js.map +1 -1
  38. package/lib/internal/template/side-navigation/index.d.ts +1 -1
  39. package/lib/internal/template/side-navigation/index.d.ts.map +1 -1
  40. package/lib/internal/template/side-navigation/index.js +5 -3
  41. package/lib/internal/template/side-navigation/index.js.map +1 -1
  42. package/lib/internal/template/side-navigation/interfaces.d.ts +20 -1
  43. package/lib/internal/template/side-navigation/interfaces.d.ts.map +1 -1
  44. package/lib/internal/template/side-navigation/interfaces.js.map +1 -1
  45. package/lib/internal/template/side-navigation/parts.d.ts +3 -2
  46. package/lib/internal/template/side-navigation/parts.d.ts.map +1 -1
  47. package/lib/internal/template/side-navigation/parts.js +147 -37
  48. package/lib/internal/template/side-navigation/parts.js.map +1 -1
  49. package/lib/internal/template/side-navigation/styles.css.js +46 -30
  50. package/lib/internal/template/side-navigation/styles.scoped.css +223 -74
  51. package/lib/internal/template/side-navigation/styles.selectors.js +46 -30
  52. package/lib/internal/template/side-navigation/test-classes/styles.css.js +2 -1
  53. package/lib/internal/template/side-navigation/test-classes/styles.scoped.css +5 -1
  54. package/lib/internal/template/side-navigation/test-classes/styles.selectors.js +2 -1
  55. package/lib/internal/template/test-utils/dom/top-navigation/index.d.ts +2 -1
  56. package/lib/internal/template/test-utils/dom/top-navigation/index.js +4 -0
  57. package/lib/internal/template/test-utils/dom/top-navigation/index.js.map +1 -1
  58. package/lib/internal/template/test-utils/selectors/top-navigation/index.d.ts +1 -0
  59. package/lib/internal/template/test-utils/selectors/top-navigation/index.js +4 -0
  60. package/lib/internal/template/test-utils/selectors/top-navigation/index.js.map +1 -1
  61. package/lib/internal/template/token/internal.d.ts +18 -2
  62. package/lib/internal/template/token/internal.d.ts.map +1 -1
  63. package/lib/internal/template/token/internal.js +20 -9
  64. package/lib/internal/template/token/internal.js.map +1 -1
  65. package/lib/internal/template/top-navigation/index.d.ts +1 -1
  66. package/lib/internal/template/top-navigation/index.d.ts.map +1 -1
  67. package/lib/internal/template/top-navigation/index.js +2 -2
  68. package/lib/internal/template/top-navigation/index.js.map +1 -1
  69. package/lib/internal/template/top-navigation/interfaces.d.ts +14 -1
  70. package/lib/internal/template/top-navigation/interfaces.d.ts.map +1 -1
  71. package/lib/internal/template/top-navigation/interfaces.js.map +1 -1
  72. package/lib/internal/template/top-navigation/internal.d.ts +2 -2
  73. package/lib/internal/template/top-navigation/internal.d.ts.map +1 -1
  74. package/lib/internal/template/top-navigation/internal.js +42 -21
  75. package/lib/internal/template/top-navigation/internal.js.map +1 -1
  76. package/lib/internal/template/top-navigation/test-classes/styles.css.js +6 -0
  77. package/lib/internal/template/top-navigation/test-classes/styles.scoped.css +7 -0
  78. package/lib/internal/template/top-navigation/test-classes/styles.selectors.js +7 -0
  79. package/lib/internal/template/top-navigation/use-top-navigation.d.ts +5 -0
  80. package/lib/internal/template/top-navigation/use-top-navigation.d.ts.map +1 -1
  81. package/lib/internal/template/top-navigation/use-top-navigation.js +12 -5
  82. package/lib/internal/template/top-navigation/use-top-navigation.js.map +1 -1
  83. package/package.json +1 -1
@@ -1,3 +1,3 @@
1
1
  {
2
- "commit": "2f2e31910a4929a517635f51286b40f489d8a43f"
2
+ "commit": "d326da3c16c88585b9246abc7852a858f91b5efc"
3
3
  }
@@ -1,6 +1,6 @@
1
1
 
2
2
  // Build environment
3
- $awsui-commit-hash: "2f2e3191";
3
+ $awsui-commit-hash: "d326da3c";
4
4
  // Manually managed CSS-variables
5
5
  $maxContentWidth: --awsui-max-content-width-6b9ypa;
6
6
  $minContentWidth: --awsui-min-content-width-6b9ypa;
@@ -10,6 +10,7 @@
10
10
  @use './constants' as constants;
11
11
  @use '../internal/generated/custom-css-properties/index.scss' as custom-props;
12
12
  @use '../internal/styles/foundation' as foundation;
13
+ @use '../internal/styles/utils/theming' as theming;
13
14
 
14
15
  .link {
15
16
  @include styles.styles-reset;
@@ -38,6 +39,21 @@
38
39
  &.button {
39
40
  @include styles.font-smoothing;
40
41
  @include styles.link-variant-style(map.get(constants.$link-styles, 'button'));
42
+
43
+ @include theming.one-theme-only {
44
+ @include styles.link-variant-style(map.get(constants.$link-variants, 'primary'));
45
+ & {
46
+ font-weight: inherit;
47
+ letter-spacing: normal;
48
+ }
49
+ &.color-inverted {
50
+ color: awsui.$color-text-notification-default;
51
+ text-decoration-color: currentColor;
52
+ &:hover {
53
+ color: awsui.$color-text-link-inverted-hover;
54
+ }
55
+ }
56
+ }
41
57
  }
42
58
 
43
59
  &.color-inverted {
@@ -7,11 +7,36 @@
7
7
  @use '../internal/styles/tokens' as awsui;
8
8
  @use '@cloudscape-design/component-toolkit/internal/focus-visible' as focus-visible;
9
9
 
10
+ // ==========================================================================
11
+ // Item sizing — single source of truth for navigation density.
12
+ // Adjust awsui.$size-side-navigation-item-height and awsui.$space-side-navigation-item-gap/awsui.$space-side-navigation-item-collapsed-gap to scale all items uniformly.
13
+ // ==========================================================================
14
+ $item-icon-text-gap: awsui.$space-xs;
15
+ // Padding is calculated to be able to horizontally align items without having to use align-items: center for wrapping
16
+ $item-padding-block: calc((#{awsui.$size-side-navigation-item-height} - #{awsui.$line-height-body-m}) / 2);
17
+ $item-padding-inline: awsui.$space-xs;
18
+ $item-indent: calc(awsui.$size-icon-normal + #{$item-icon-text-gap} - #{$item-padding-inline});
19
+ $expandable-icon-negative-margin: awsui.$space-l;
20
+
21
+ @mixin item-radius {
22
+ border-start-start-radius: awsui.$border-radius-item;
23
+ border-start-end-radius: awsui.$border-radius-item;
24
+ border-end-start-radius: awsui.$border-radius-item;
25
+ border-end-end-radius: awsui.$border-radius-item;
26
+ }
27
+
10
28
  .root {
11
29
  @include styles.styles-reset;
12
30
  @include styles.text-wrapping;
13
31
  }
14
32
 
33
+ .with-toolbar {
34
+ /* Structural class — parent context for toolbar margin resets. */
35
+ }
36
+
37
+ // ==========================================================================
38
+ // Header
39
+ // ==========================================================================
15
40
  .header {
16
41
  @include styles.font-panel-header;
17
42
  margin-block: 0;
@@ -20,13 +45,19 @@
20
45
  padding-inline-start: awsui.$space-panel-nav-left;
21
46
  // Additional xl space to prevent text from overlapping the close button.
22
47
  padding-inline-end: calc(#{awsui.$space-scaled-xxl} + #{awsui.$space-xl});
48
+
49
+ &--collapsed {
50
+ padding-inline: 0;
51
+ display: flex;
52
+ justify-content: center;
53
+ align-items: center;
54
+ }
23
55
  }
24
56
 
25
57
  .header-link {
26
58
  @include styles.font-panel-header;
27
59
  color: awsui.$color-text-heading-default;
28
60
  min-block-size: awsui.$font-panel-header-line-height;
29
-
30
61
  display: flex;
31
62
 
32
63
  &--has-logo {
@@ -49,8 +80,12 @@
49
80
  }
50
81
  }
51
82
 
83
+ // ==========================================================================
84
+ // List structure
85
+ // ==========================================================================
52
86
  .items-control {
53
87
  padding-inline: awsui.$space-l;
88
+ padding-block-start: $item-padding-block;
54
89
  }
55
90
 
56
91
  .list-container {
@@ -59,10 +94,10 @@
59
94
 
60
95
  .items-control,
61
96
  .list-container {
62
- margin-block-start: awsui.$space-panel-content-top;
63
- // Toolbar removes margin for whichever one comes first after the header
97
+ margin-block-start: calc(#{awsui.$space-panel-content-top} - #{$item-padding-block});
98
+ // Toolbar removes margin and item padding for whatever comes first after the header
64
99
  .with-toolbar > .divider-header + & {
65
- margin-block-start: 0;
100
+ margin-block-start: calc(-1 * #{$item-padding-block});
66
101
  }
67
102
  }
68
103
 
@@ -71,93 +106,214 @@
71
106
  margin-inline: 0;
72
107
  padding-block: 0;
73
108
  padding-inline-end: 0;
74
- padding-inline-start: awsui.$space-l;
109
+ padding-inline-start: $item-indent;
75
110
  }
76
111
 
77
112
  .list-variant-root {
78
113
  margin-block: 0;
79
114
  margin-inline: 0;
80
115
  padding-block: 0;
81
- padding-inline-start: awsui.$space-panel-nav-left;
82
- padding-inline-end: awsui.$space-panel-side-right;
116
+ padding-inline-start: calc(#{awsui.$space-panel-nav-left} - #{$item-padding-inline});
117
+ padding-inline-end: calc(#{awsui.$space-panel-side-right} - #{$item-padding-inline});
83
118
 
84
119
  &--first {
85
120
  margin-block-start: 0;
86
121
  }
122
+
123
+ &--collapsed {
124
+ padding-inline-start: 0;
125
+ padding-inline-end: 0;
126
+ }
87
127
  }
88
128
 
89
129
  .list-variant-expandable-link-group {
90
- padding-inline-start: awsui.$space-xxxl;
130
+ padding-inline-start: calc(#{$item-indent} + #{$expandable-icon-negative-margin});
91
131
  }
92
132
 
133
+ .list-variant-section {
134
+ padding-inline-start: calc(#{$expandable-icon-negative-margin} - #{$item-padding-inline});
135
+ }
136
+
137
+ .list-variant-link-group {
138
+ padding-inline-start: $item-indent;
139
+ }
140
+
141
+ .list-variant-section-group {
142
+ margin-block: calc(#{awsui.$space-scaled-xs} - #{$item-padding-block});
143
+ margin-inline: calc(-1 * #{$item-padding-inline});
144
+ padding-block: 0;
145
+ padding-inline: 0;
146
+ }
147
+
148
+ // ==========================================================================
149
+ // List items
150
+ // ==========================================================================
93
151
  .list-item {
94
- margin-block: awsui.$space-scaled-xs;
95
152
  margin-inline: 0;
153
+ margin-block: awsui.$space-side-navigation-item-gap;
96
154
  padding-block: 0;
97
- padding-inline: 0;
155
+ padding-inline: $item-padding-inline;
98
156
  list-style: none;
99
-
157
+ @include styles.with-motion {
158
+ transition: margin awsui.$motion-duration-expressive awsui.$motion-easing-responsive;
159
+ }
100
160
  // Remove margin from first item in side nav, outer block margins are covered by list-container
101
161
  .list-variant-root--first > &:first-child {
102
162
  margin-block-start: 0px;
103
163
  }
164
+
165
+ &--collapsed {
166
+ margin-block: awsui.$space-side-navigation-item-collapsed-gap;
167
+ display: flex;
168
+ justify-content: center;
169
+ padding-block: 0;
170
+ padding-inline: 0;
171
+ @include styles.with-motion {
172
+ transition: margin awsui.$motion-duration-expressive awsui.$motion-easing-responsive;
173
+ }
174
+ }
175
+
176
+ &--group {
177
+ padding-inline: 0;
178
+ padding-block: awsui.$space-scaled-s;
179
+ list-style: none;
180
+
181
+ &-no-padding-start {
182
+ padding-block-start: 0;
183
+ }
184
+
185
+ &-no-padding-end {
186
+ padding-block-end: 0;
187
+ }
188
+ }
189
+
190
+ &--info {
191
+ display: flex;
192
+ align-items: baseline;
193
+ }
104
194
  }
105
195
 
196
+ .list-item--info > .list {
197
+ inline-size: 100%;
198
+ }
199
+
200
+ .list--collapsed-group {
201
+ margin-block: 0;
202
+ margin-inline: 0;
203
+ padding-block: 0;
204
+ padding-inline: 0;
205
+ list-style: none;
206
+ }
207
+
208
+ // ==========================================================================
209
+ // Sections and expandable link groups (InternalExpandableSection)
210
+ // ==========================================================================
106
211
  .section,
107
212
  .expandable-link-group {
108
- margin-inline-start: calc(-1 * #{awsui.$space-l});
213
+ margin-inline-start: calc(-1 * #{$expandable-icon-negative-margin});
214
+
215
+ // HACK: Remove padding from section header and content to rely on margin collapsing rules.
216
+ // Hits the two direct <div> children of the ExpandableSection root: the header
217
+ // (.wrapper-footer / .header-footer) and the content (.content-footer).
218
+ /* stylelint-disable-next-line selector-max-type */
219
+ & > div {
220
+ padding-block: 0;
221
+ padding-inline: 0;
222
+ }
223
+
224
+ // Hits the header's first child only — the .icon-container inside the
225
+ // ExpandableSection header — to vertically align the icon with the text.
226
+ // Must NOT match the content div's first child (our <ul>); turning the <ul>
227
+ // into a grid container breaks sibling margin collapse on the .list-item children.
228
+ /* stylelint-disable-next-line selector-max-type */
229
+ & > div:first-child > :first-child {
230
+ display: grid;
231
+ align-items: flex-start;
232
+ padding-block: $item-padding-block;
233
+ }
109
234
 
110
235
  &--no-ident {
111
236
  margin-inline-start: 0;
112
237
  }
113
238
  }
114
239
 
240
+ .expandable-link-group > div:first-child {
241
+ @include item-radius;
242
+ display: flex;
243
+ padding-inline: $item-padding-inline;
244
+ margin-inline: calc(-1 * #{$item-padding-inline});
245
+ box-sizing: content-box;
246
+ }
247
+
248
+ .expandable-link-group--active > div:first-child {
249
+ background-color: awsui.$color-background-side-navigation-item-active;
250
+ }
251
+
115
252
  .section {
116
253
  margin-block: calc(#{awsui.$space-scaled-2x-l} - #{awsui.$border-divider-section-width});
117
254
  &.refresh {
118
- margin-block: calc(#{awsui.$space-scaled-2x-m} - #{awsui.$border-divider-section-width});
255
+ margin-block: calc(#{awsui.$space-scaled-xs} - #{awsui.$border-divider-section-width});
119
256
  }
120
257
  // Remove margin from section if it is the first item in side nav to prevent double margin stacking
121
258
  .list-variant-root--first > .list-item:first-child > & {
122
259
  margin-block-start: 0px;
123
260
  }
124
- // HACK: Remove padding from section header and content to rely on margin collapsing rules.
125
- /* stylelint-disable-next-line selector-max-type */
126
- > div {
127
- padding-block: 0;
128
- padding-inline: 0;
129
- }
130
- }
131
-
132
- .list-variant-section-group {
133
- margin-block: 0;
134
- margin-inline: 0;
135
- padding-block: 0;
136
- padding-inline: 0;
137
261
  }
138
262
 
263
+ // ==========================================================================
264
+ // Section groups
265
+ // ==========================================================================
139
266
  .section-group {
140
267
  @include styles.font-heading-m;
141
- margin-block: 0;
268
+ margin-block: calc(#{awsui.$space-scaled-xs} - #{awsui.$border-divider-section-width});
142
269
  margin-inline: 0;
270
+
271
+ .list-variant-root--first > .list-item:first-child > & {
272
+ margin-block-start: 0px;
273
+ }
143
274
  }
144
275
 
145
276
  .section-group-title {
146
- /* used in test-utils */
277
+ display: flex;
278
+ align-items: center;
279
+ margin-block: 0;
147
280
  }
148
281
 
282
+ // ==========================================================================
283
+ // Links — all links use awsui.$size-side-navigation-item-height for consistent row sizing and collapse icon size.
284
+ // ==========================================================================
149
285
  .link {
150
286
  @include styles.font-body-m;
151
287
  color: awsui.$color-text-body-secondary;
288
+ display: inline-flex;
289
+ padding-block: $item-padding-block;
290
+ min-inline-size: awsui.$size-side-navigation-item-height;
291
+ padding-inline: $item-padding-inline;
292
+ margin-inline: calc(-1 * #{$item-padding-inline});
293
+ align-items: flex-start;
294
+ @include item-radius;
152
295
  font-weight: styles.$font-weight-normal;
153
296
  -webkit-font-smoothing: auto;
154
297
  -moz-osx-font-smoothing: auto;
155
- }
298
+ @include styles.with-motion {
299
+ transition:
300
+ background-color awsui.$motion-duration-expressive awsui.$motion-easing-responsive,
301
+ color awsui.$motion-duration-expressive awsui.$motion-easing-expressive;
302
+ }
303
+
304
+ &-active {
305
+ font-weight: awsui.$font-wayfinding-link-active-weight;
306
+ @include styles.font-smoothing;
307
+ color: awsui.$color-text-side-navigation-item-active;
308
+ background-color: awsui.$color-background-side-navigation-item-active;
309
+ }
156
310
 
157
- .link-active {
158
- font-weight: awsui.$font-wayfinding-link-active-weight;
159
- @include styles.font-smoothing;
160
- color: awsui.$color-text-accent;
311
+ &--collapsed {
312
+ padding-inline: 0;
313
+ margin-inline: 0;
314
+ justify-content: center;
315
+ align-items: center;
316
+ }
161
317
  }
162
318
 
163
319
  .header-link,
@@ -165,7 +321,7 @@
165
321
  text-decoration: none;
166
322
 
167
323
  &:hover {
168
- color: awsui.$color-text-accent;
324
+ color: awsui.$color-text-side-navigation-item-active;
169
325
  }
170
326
 
171
327
  &:focus {
@@ -182,8 +338,24 @@
182
338
  }
183
339
  }
184
340
 
341
+ // ==========================================================================
342
+ // Misc
343
+ // ==========================================================================
344
+ .link-text-wrapper {
345
+ min-inline-size: 0;
346
+ }
347
+
185
348
  .info {
186
- margin-inline-start: awsui.$space-xs;
349
+ margin-inline-start: awsui.$space-s;
350
+ flex-shrink: 0;
351
+ }
352
+
353
+ .item-icon {
354
+ display: inline-flex;
355
+ flex-shrink: 0;
356
+ &:not(.item-icon--collapsed) {
357
+ margin-inline-end: $item-icon-text-gap;
358
+ }
187
359
  }
188
360
 
189
361
  .external-icon {
@@ -193,18 +365,19 @@
193
365
  .divider {
194
366
  border-block: none;
195
367
  border-inline: none;
196
- }
197
-
198
- .divider-default {
199
- margin-block: awsui.$space-scaled-2x-xl;
200
- margin-inline: calc(-1 * #{awsui.$space-panel-divider-margin-horizontal});
201
- border-block-start: awsui.$border-divider-section-width solid awsui.$color-border-divider-default;
202
- }
203
-
204
- .divider-header {
205
- margin-block: 0;
206
- border-block-start: awsui.$border-divider-section-width solid awsui.$color-border-panel-header;
207
- .with-toolbar > & {
208
- border-color: transparent;
368
+ &-default {
369
+ margin-block: calc(#{awsui.$space-scaled-2x-xl} - #{$item-padding-block});
370
+ border-block-start: awsui.$border-divider-section-width solid awsui.$color-border-divider-default;
371
+ &.divider--collapsed {
372
+ margin-block: awsui.$space-scaled-2x-m;
373
+ margin-inline: awsui.$space-xs;
374
+ }
375
+ }
376
+ &-header {
377
+ margin-block: 0;
378
+ border-block-start: awsui.$border-divider-section-width solid awsui.$color-border-panel-header;
379
+ .with-toolbar > & {
380
+ border-color: transparent;
381
+ }
209
382
  }
210
383
  }
@@ -5,3 +5,7 @@
5
5
  .info {
6
6
  /* used in test-utils */
7
7
  }
8
+
9
+ .item-icon {
10
+ /* used in test-utils */
11
+ }
@@ -0,0 +1,8 @@
1
+ /*
2
+ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ SPDX-License-Identifier: Apache-2.0
4
+ */
5
+
6
+ .custom-content {
7
+ /* used in test-utils */
8
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"file-token.d.ts","sourceRoot":"","sources":["../../../src/file-token-group/file-token.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAOhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAIzE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAQ/D,yBAAiB,cAAc,CAAC;IAC9B,UAAiB,WAAW;QAC1B,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;QACjD,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;KACjD;CACF;AAED,UAAU,cAAe,SAAQ,kBAAkB;IACjD,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iBAAS,iBAAiB,CAAC,EACzB,IAAI,EACJ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,OAAO,EACP,SAAS,EACT,kBAAkB,EAClB,OAAO,EACP,KAAK,GACN,EAAE,cAAc,eA6IhB;AAED,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"file-token.d.ts","sourceRoot":"","sources":["../../../src/file-token-group/file-token.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAOhD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAIzE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAQ/D,yBAAiB,cAAc,CAAC;IAC9B,UAAiB,WAAW;QAC1B,mBAAmB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;QACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,cAAc,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;QACjD,sBAAsB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;KACjD;CACF;AAED,UAAU,cAAe,SAAQ,kBAAkB;IACjD,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,cAAc,CAAC,WAAW,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,eAAe,CAAC,SAAS,CAAC;IACtC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,iBAAS,iBAAiB,CAAC,EACzB,IAAI,EACJ,oBAAoB,EACpB,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,QAAQ,EACR,OAAO,EACP,SAAS,EACT,kBAAkB,EAClB,OAAO,EACP,KAAK,GACN,EAAE,cAAc,eAuJhB;AAED,eAAe,iBAAiB,CAAC"}
@@ -7,7 +7,7 @@ import InternalBox from '../box/internal.js';
7
7
  import { FormFieldError, FormFieldWarning } from '../form-field/internal';
8
8
  import InternalSpaceBetween from '../space-between/internal.js';
9
9
  import InternalSpinner from '../spinner/internal.js';
10
- import DismissButton from '../token/dismiss-button.js';
10
+ import InternalToken from '../token/internal.js';
11
11
  import Tooltip from '../tooltip/internal.js';
12
12
  import * as defaultFormatters from './default-formatters.js';
13
13
  import { FileOptionThumbnail } from './thumbnail.js';
@@ -25,10 +25,7 @@ function InternalFileToken({ file, showFileLastModified, showFileSize, showFileT
25
25
  const fileNameContainerRef = useRef(null);
26
26
  const [showTooltip, setShowTooltip] = useState(false);
27
27
  const [isTruncated, setIsTruncated] = useState(false);
28
- const getDismissLabel = (fileIndex) => {
29
- var _a;
30
- return (_a = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.removeFileAriaLabel) === null || _a === void 0 ? void 0 : _a.call(i18nStrings, fileIndex, file.name);
31
- };
28
+ const getDismissLabel = (fileIndex) => { var _a; return (_a = i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.removeFileAriaLabel) === null || _a === void 0 ? void 0 : _a.call(i18nStrings, fileIndex, file.name); };
32
29
  function isEllipsisActive() {
33
30
  const span = fileNameRef.current;
34
31
  const container = fileNameContainerRef.current;
@@ -39,36 +36,45 @@ function InternalFileToken({ file, showFileLastModified, showFileSize, showFileT
39
36
  }
40
37
  useResizeObserver(() => fileNameContainerRef.current, () => setIsTruncated(isEllipsisActive()));
41
38
  const fileIsSingleRow = !showFileLastModified && !showFileSize && (!groupContainsImage || (groupContainsImage && !showFileThumbnail));
39
+ // The full body of the token. Rendered through InternalToken's customContent slot so this
40
+ // component owns the inner layout (thumbnail + metadata column + loading overlay), while
41
+ // InternalToken handles the token-box and the dismiss button.
42
+ const fileContent = (React.createElement(React.Fragment, null,
43
+ loading && (React.createElement("div", { className: clsx(styles['file-loading-overlay'], {
44
+ [styles['file-loading-overlay-single-row']]: loading && fileIsSingleRow,
45
+ }) },
46
+ React.createElement(InternalSpinner, { variant: "normal", size: "normal" }))),
47
+ React.createElement(InternalBox, { className: styles['file-option'] },
48
+ showFileThumbnail && isImage && React.createElement(FileOptionThumbnail, { file: file }),
49
+ React.createElement("div", { className: clsx(styles['file-option-metadata'], {
50
+ [styles['with-image']]: showFileThumbnail && isImage,
51
+ [styles['single-row-loading']]: loading && fileIsSingleRow,
52
+ }) },
53
+ React.createElement(InternalSpaceBetween, { direction: "vertical", size: "xxxs" },
54
+ React.createElement("div", { className: styles['file-name-container'], onMouseOver: () => setShowTooltip(true), onMouseOut: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), role: isTruncated ? 'button' : undefined, "aria-expanded": isTruncated ? showTooltip : undefined, tabIndex: isTruncated ? 0 : -1, ref: fileNameContainerRef },
55
+ React.createElement(InternalBox, { fontWeight: "normal", className: clsx(styles['file-option-name'], testUtilStyles['file-option-name'], {
56
+ [testUtilStyles['ellipsis-active']]: isTruncated,
57
+ }) },
58
+ React.createElement("span", { ref: fileNameRef }, file.name))),
59
+ showFileSize && file.size ? (React.createElement(InternalBox, { fontSize: "body-s", color: 'text-body-secondary', className: clsx(styles['file-option-size'], testUtilStyles['file-option-size']) }, formatFileSize(file.size))) : null,
60
+ showFileLastModified && file.lastModified ? (React.createElement(InternalBox, { fontSize: "body-s", color: 'text-body-secondary', className: clsx(styles['file-option-last-modified'], testUtilStyles['file-option-last-modified']) }, formatFileLastModified(new Date(file.lastModified)))) : null)))));
42
61
  return (React.createElement("div", { ref: containerRef, className: clsx(styles.token, {
43
62
  [styles['token-grid']]: alignment === 'horizontal',
44
63
  [styles['token-contains-image']]: groupContainsImage && showFileThumbnail,
45
- }), role: "group", "aria-label": file.name, "aria-describedby": errorText ? errorId : warningText ? warningId : undefined, "aria-disabled": loading, "data-index": index },
46
- React.createElement("div", { className: clsx(styles['token-box'], {
64
+ }), role: "group", "aria-label": file.name, "aria-describedby": errorText ? errorId : warningText ? warningId : undefined, "aria-disabled": loading || undefined, "data-index": index },
65
+ React.createElement(InternalToken
66
+ // The outer wrapper above is the accessibility group (role="group" + aria-label). The
67
+ // token itself is presentation-only so screen readers don't see two nested groups.
68
+ , {
69
+ // The outer wrapper above is the accessibility group (role="group" + aria-label). The
70
+ // token itself is presentation-only so screen readers don't see two nested groups.
71
+ role: "presentation", __customContent: fileContent, onDismiss: readOnly ? undefined : onDismiss, dismissLabel: getDismissLabel(index), __tokenBoxClassName: clsx(styles['token-box'], {
47
72
  [styles.loading]: loading,
48
73
  [styles.error]: errorText,
49
74
  [styles.warning]: showWarning,
50
75
  [styles.horizontal]: alignment === 'horizontal',
51
76
  [styles['read-only']]: readOnly,
52
- }) },
53
- loading && (React.createElement("div", { className: clsx(styles['file-loading-overlay'], {
54
- [styles['file-loading-overlay-single-row']]: loading && fileIsSingleRow,
55
- }) },
56
- React.createElement(InternalSpinner, { variant: "normal", size: "normal" }))),
57
- React.createElement(InternalBox, { className: styles['file-option'] },
58
- showFileThumbnail && isImage && React.createElement(FileOptionThumbnail, { file: file }),
59
- React.createElement("div", { className: clsx(styles['file-option-metadata'], {
60
- [styles['with-image']]: showFileThumbnail && isImage,
61
- [styles['single-row-loading']]: loading && fileIsSingleRow,
62
- }) },
63
- React.createElement(InternalSpaceBetween, { direction: "vertical", size: "xxxs" },
64
- React.createElement("div", { className: styles['file-name-container'], onMouseOver: () => setShowTooltip(true), onMouseOut: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), role: isTruncated ? 'button' : undefined, "aria-expanded": isTruncated ? showTooltip : undefined, tabIndex: isTruncated ? 0 : -1, ref: fileNameContainerRef },
65
- React.createElement(InternalBox, { fontWeight: "normal", className: clsx(styles['file-option-name'], testUtilStyles['file-option-name'], {
66
- [testUtilStyles['ellipsis-active']]: isTruncated,
67
- }) },
68
- React.createElement("span", { ref: fileNameRef }, file.name))),
69
- showFileSize && file.size ? (React.createElement(InternalBox, { fontSize: "body-s", color: 'text-body-secondary', className: clsx(styles['file-option-size'], testUtilStyles['file-option-size']) }, formatFileSize(file.size))) : null,
70
- showFileLastModified && file.lastModified ? (React.createElement(InternalBox, { fontSize: "body-s", color: 'text-body-secondary', className: clsx(styles['file-option-last-modified'], testUtilStyles['file-option-last-modified']) }, formatFileLastModified(new Date(file.lastModified)))) : null))),
71
- onDismiss && !readOnly && React.createElement(DismissButton, { dismissLabel: getDismissLabel(index), onDismiss: onDismiss })),
77
+ }) }),
72
78
  errorText && (React.createElement(FormFieldError, { id: errorId, errorIconAriaLabel: i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.errorIconAriaLabel }, errorText)),
73
79
  showWarning && (React.createElement(FormFieldWarning, { id: warningId, warningIconAriaLabel: i18nStrings === null || i18nStrings === void 0 ? void 0 : i18nStrings.warningIconAriaLabel }, warningText)),
74
80
  showTooltip && isTruncated && (React.createElement(Tooltip, { getTrack: () => containerRef.current, content: React.createElement(InternalBox, { fontWeight: "normal" }, file.name), onEscape: () => setShowTooltip(false) }))));
@@ -1 +1 @@
1
- {"version":3,"file":"file-token.js","sourceRoot":"","sources":["../../../src/file-token-group/file-token.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport React, { useRef, useState } from 'react';\nimport clsx from 'clsx';\n\nimport { useResizeObserver, useUniqueId } from '@cloudscape-design/component-toolkit/internal';\n\nimport InternalBox from '../box/internal.js';\nimport { FormFieldError, FormFieldWarning } from '../form-field/internal';\nimport { BaseComponentProps } from '../internal/base-component/index.js';\nimport InternalSpaceBetween from '../space-between/internal.js';\nimport InternalSpinner from '../spinner/internal.js';\nimport DismissButton from '../token/dismiss-button.js';\nimport { TokenGroupProps } from '../token-group/interfaces.js';\nimport Tooltip from '../tooltip/internal.js';\nimport * as defaultFormatters from './default-formatters.js';\nimport { FileOptionThumbnail } from './thumbnail.js';\n\nimport styles from './styles.css.js';\nimport testUtilStyles from './test-classes/styles.css.js';\n\nexport namespace FileTokenProps {\n export interface I18nStrings {\n removeFileAriaLabel?: (fileIndex: number, fileName: string) => string;\n errorIconAriaLabel?: string;\n warningIconAriaLabel?: string;\n formatFileSize?: (sizeInBytes: number) => string;\n formatFileLastModified?: (date: Date) => string;\n }\n}\n\ninterface FileTokenProps extends BaseComponentProps {\n file: File;\n onDismiss: () => void;\n showFileSize?: boolean;\n showFileLastModified?: boolean;\n showFileThumbnail?: boolean;\n errorText?: React.ReactNode;\n warningText?: React.ReactNode;\n loading?: boolean;\n readOnly?: boolean;\n i18nStrings?: FileTokenProps.I18nStrings;\n dismissLabel?: string;\n alignment?: TokenGroupProps.Alignment;\n groupContainsImage?: boolean;\n isImage: boolean;\n index: number;\n}\n\nfunction InternalFileToken({\n file,\n showFileLastModified,\n showFileSize,\n showFileThumbnail,\n i18nStrings,\n onDismiss,\n errorText,\n warningText,\n readOnly,\n loading,\n alignment,\n groupContainsImage,\n isImage,\n index,\n}: FileTokenProps) {\n const formatFileSize = i18nStrings?.formatFileSize ?? defaultFormatters.formatFileSize;\n const formatFileLastModified = i18nStrings?.formatFileLastModified ?? defaultFormatters.formatFileLastModified;\n\n const errorId = useUniqueId('error');\n const warningId = useUniqueId('warning');\n\n const showWarning = warningText && !errorText;\n const containerRef = useRef<HTMLDivElement>(null);\n const fileNameRef = useRef<HTMLSpanElement>(null);\n const fileNameContainerRef = useRef<HTMLDivElement>(null);\n const [showTooltip, setShowTooltip] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n\n const getDismissLabel = (fileIndex: number) => {\n return i18nStrings?.removeFileAriaLabel?.(fileIndex, file.name);\n };\n\n function isEllipsisActive() {\n const span = fileNameRef.current;\n const container = fileNameContainerRef.current;\n\n if (span && container) {\n return span.offsetWidth >= container.offsetWidth;\n }\n return false;\n }\n\n useResizeObserver(\n () => fileNameContainerRef.current,\n () => setIsTruncated(isEllipsisActive())\n );\n\n const fileIsSingleRow =\n !showFileLastModified && !showFileSize && (!groupContainsImage || (groupContainsImage && !showFileThumbnail));\n\n return (\n <div\n ref={containerRef}\n className={clsx(styles.token, {\n [styles['token-grid']]: alignment === 'horizontal',\n [styles['token-contains-image']]: groupContainsImage && showFileThumbnail,\n })}\n role=\"group\"\n aria-label={file.name}\n aria-describedby={errorText ? errorId : warningText ? warningId : undefined}\n aria-disabled={loading}\n data-index={index}\n >\n <div\n className={clsx(styles['token-box'], {\n [styles.loading]: loading,\n [styles.error]: errorText,\n [styles.warning]: showWarning,\n [styles.horizontal]: alignment === 'horizontal',\n [styles['read-only']]: readOnly,\n })}\n >\n {loading && (\n <div\n className={clsx(styles['file-loading-overlay'], {\n [styles['file-loading-overlay-single-row']]: loading && fileIsSingleRow,\n })}\n >\n <InternalSpinner variant=\"normal\" size=\"normal\" />\n </div>\n )}\n <InternalBox className={styles['file-option']}>\n {showFileThumbnail && isImage && <FileOptionThumbnail file={file} />}\n\n <div\n className={clsx(styles['file-option-metadata'], {\n [styles['with-image']]: showFileThumbnail && isImage,\n [styles['single-row-loading']]: loading && fileIsSingleRow,\n })}\n >\n <InternalSpaceBetween direction=\"vertical\" size=\"xxxs\">\n <div\n className={styles['file-name-container']}\n onMouseOver={() => setShowTooltip(true)}\n onMouseOut={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n role={isTruncated ? 'button' : undefined}\n aria-expanded={isTruncated ? showTooltip : undefined}\n tabIndex={isTruncated ? 0 : -1}\n ref={fileNameContainerRef}\n >\n <InternalBox\n fontWeight=\"normal\"\n className={clsx(styles['file-option-name'], testUtilStyles['file-option-name'], {\n [testUtilStyles['ellipsis-active']]: isTruncated,\n })}\n >\n <span ref={fileNameRef}>{file.name}</span>\n </InternalBox>\n </div>\n\n {showFileSize && file.size ? (\n <InternalBox\n fontSize=\"body-s\"\n color={'text-body-secondary'}\n className={clsx(styles['file-option-size'], testUtilStyles['file-option-size'])}\n >\n {formatFileSize(file.size)}\n </InternalBox>\n ) : null}\n\n {showFileLastModified && file.lastModified ? (\n <InternalBox\n fontSize=\"body-s\"\n color={'text-body-secondary'}\n className={clsx(styles['file-option-last-modified'], testUtilStyles['file-option-last-modified'])}\n >\n {formatFileLastModified(new Date(file.lastModified))}\n </InternalBox>\n ) : null}\n </InternalSpaceBetween>\n </div>\n </InternalBox>\n {onDismiss && !readOnly && <DismissButton dismissLabel={getDismissLabel(index)} onDismiss={onDismiss} />}\n </div>\n {errorText && (\n <FormFieldError id={errorId} errorIconAriaLabel={i18nStrings?.errorIconAriaLabel}>\n {errorText}\n </FormFieldError>\n )}\n {showWarning && (\n <FormFieldWarning id={warningId} warningIconAriaLabel={i18nStrings?.warningIconAriaLabel}>\n {warningText}\n </FormFieldWarning>\n )}\n {showTooltip && isTruncated && (\n <Tooltip\n getTrack={() => containerRef.current}\n content={<InternalBox fontWeight=\"normal\">{file.name}</InternalBox>}\n onEscape={() => setShowTooltip(false)}\n />\n )}\n </div>\n );\n}\n\nexport default InternalFileToken;\n"]}
1
+ {"version":3,"file":"file-token.js","sourceRoot":"","sources":["../../../src/file-token-group/file-token.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport React, { useRef, useState } from 'react';\nimport clsx from 'clsx';\n\nimport { useResizeObserver, useUniqueId } from '@cloudscape-design/component-toolkit/internal';\n\nimport InternalBox from '../box/internal.js';\nimport { FormFieldError, FormFieldWarning } from '../form-field/internal';\nimport { BaseComponentProps } from '../internal/base-component/index.js';\nimport InternalSpaceBetween from '../space-between/internal.js';\nimport InternalSpinner from '../spinner/internal.js';\nimport InternalToken from '../token/internal.js';\nimport { TokenGroupProps } from '../token-group/interfaces.js';\nimport Tooltip from '../tooltip/internal.js';\nimport * as defaultFormatters from './default-formatters.js';\nimport { FileOptionThumbnail } from './thumbnail.js';\n\nimport styles from './styles.css.js';\nimport testUtilStyles from './test-classes/styles.css.js';\n\nexport namespace FileTokenProps {\n export interface I18nStrings {\n removeFileAriaLabel?: (fileIndex: number, fileName: string) => string;\n errorIconAriaLabel?: string;\n warningIconAriaLabel?: string;\n formatFileSize?: (sizeInBytes: number) => string;\n formatFileLastModified?: (date: Date) => string;\n }\n}\n\ninterface FileTokenProps extends BaseComponentProps {\n file: File;\n onDismiss: () => void;\n showFileSize?: boolean;\n showFileLastModified?: boolean;\n showFileThumbnail?: boolean;\n errorText?: React.ReactNode;\n warningText?: React.ReactNode;\n loading?: boolean;\n readOnly?: boolean;\n i18nStrings?: FileTokenProps.I18nStrings;\n dismissLabel?: string;\n alignment?: TokenGroupProps.Alignment;\n groupContainsImage?: boolean;\n isImage: boolean;\n index: number;\n}\n\nfunction InternalFileToken({\n file,\n showFileLastModified,\n showFileSize,\n showFileThumbnail,\n i18nStrings,\n onDismiss,\n errorText,\n warningText,\n readOnly,\n loading,\n alignment,\n groupContainsImage,\n isImage,\n index,\n}: FileTokenProps) {\n const formatFileSize = i18nStrings?.formatFileSize ?? defaultFormatters.formatFileSize;\n const formatFileLastModified = i18nStrings?.formatFileLastModified ?? defaultFormatters.formatFileLastModified;\n\n const errorId = useUniqueId('error');\n const warningId = useUniqueId('warning');\n\n const showWarning = warningText && !errorText;\n const containerRef = useRef<HTMLDivElement>(null);\n const fileNameRef = useRef<HTMLSpanElement>(null);\n const fileNameContainerRef = useRef<HTMLDivElement>(null);\n const [showTooltip, setShowTooltip] = useState(false);\n const [isTruncated, setIsTruncated] = useState(false);\n\n const getDismissLabel = (fileIndex: number) => i18nStrings?.removeFileAriaLabel?.(fileIndex, file.name);\n\n function isEllipsisActive() {\n const span = fileNameRef.current;\n const container = fileNameContainerRef.current;\n\n if (span && container) {\n return span.offsetWidth >= container.offsetWidth;\n }\n return false;\n }\n\n useResizeObserver(\n () => fileNameContainerRef.current,\n () => setIsTruncated(isEllipsisActive())\n );\n\n const fileIsSingleRow =\n !showFileLastModified && !showFileSize && (!groupContainsImage || (groupContainsImage && !showFileThumbnail));\n\n // The full body of the token. Rendered through InternalToken's customContent slot so this\n // component owns the inner layout (thumbnail + metadata column + loading overlay), while\n // InternalToken handles the token-box and the dismiss button.\n const fileContent = (\n <>\n {loading && (\n <div\n className={clsx(styles['file-loading-overlay'], {\n [styles['file-loading-overlay-single-row']]: loading && fileIsSingleRow,\n })}\n >\n <InternalSpinner variant=\"normal\" size=\"normal\" />\n </div>\n )}\n <InternalBox className={styles['file-option']}>\n {showFileThumbnail && isImage && <FileOptionThumbnail file={file} />}\n\n <div\n className={clsx(styles['file-option-metadata'], {\n [styles['with-image']]: showFileThumbnail && isImage,\n [styles['single-row-loading']]: loading && fileIsSingleRow,\n })}\n >\n <InternalSpaceBetween direction=\"vertical\" size=\"xxxs\">\n <div\n className={styles['file-name-container']}\n onMouseOver={() => setShowTooltip(true)}\n onMouseOut={() => setShowTooltip(false)}\n onFocus={() => setShowTooltip(true)}\n onBlur={() => setShowTooltip(false)}\n role={isTruncated ? 'button' : undefined}\n aria-expanded={isTruncated ? showTooltip : undefined}\n tabIndex={isTruncated ? 0 : -1}\n ref={fileNameContainerRef}\n >\n <InternalBox\n fontWeight=\"normal\"\n className={clsx(styles['file-option-name'], testUtilStyles['file-option-name'], {\n [testUtilStyles['ellipsis-active']]: isTruncated,\n })}\n >\n <span ref={fileNameRef}>{file.name}</span>\n </InternalBox>\n </div>\n\n {showFileSize && file.size ? (\n <InternalBox\n fontSize=\"body-s\"\n color={'text-body-secondary'}\n className={clsx(styles['file-option-size'], testUtilStyles['file-option-size'])}\n >\n {formatFileSize(file.size)}\n </InternalBox>\n ) : null}\n\n {showFileLastModified && file.lastModified ? (\n <InternalBox\n fontSize=\"body-s\"\n color={'text-body-secondary'}\n className={clsx(styles['file-option-last-modified'], testUtilStyles['file-option-last-modified'])}\n >\n {formatFileLastModified(new Date(file.lastModified))}\n </InternalBox>\n ) : null}\n </InternalSpaceBetween>\n </div>\n </InternalBox>\n </>\n );\n\n return (\n <div\n ref={containerRef}\n className={clsx(styles.token, {\n [styles['token-grid']]: alignment === 'horizontal',\n [styles['token-contains-image']]: groupContainsImage && showFileThumbnail,\n })}\n role=\"group\"\n aria-label={file.name}\n aria-describedby={errorText ? errorId : warningText ? warningId : undefined}\n aria-disabled={loading || undefined}\n data-index={index}\n >\n <InternalToken\n // The outer wrapper above is the accessibility group (role=\"group\" + aria-label). The\n // token itself is presentation-only so screen readers don't see two nested groups.\n role=\"presentation\"\n __customContent={fileContent}\n onDismiss={readOnly ? undefined : onDismiss}\n dismissLabel={getDismissLabel(index)}\n __tokenBoxClassName={clsx(styles['token-box'], {\n [styles.loading]: loading,\n [styles.error]: errorText,\n [styles.warning]: showWarning,\n [styles.horizontal]: alignment === 'horizontal',\n [styles['read-only']]: readOnly,\n })}\n />\n {errorText && (\n <FormFieldError id={errorId} errorIconAriaLabel={i18nStrings?.errorIconAriaLabel}>\n {errorText}\n </FormFieldError>\n )}\n {showWarning && (\n <FormFieldWarning id={warningId} warningIconAriaLabel={i18nStrings?.warningIconAriaLabel}>\n {warningText}\n </FormFieldWarning>\n )}\n {showTooltip && isTruncated && (\n <Tooltip\n getTrack={() => containerRef.current}\n content={<InternalBox fontWeight=\"normal\">{file.name}</InternalBox>}\n onEscape={() => setShowTooltip(false)}\n />\n )}\n </div>\n );\n}\n\nexport default InternalFileToken;\n"]}