@ankhorage/zora 1.0.4 → 1.0.5

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 (122) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +214 -5
  3. package/dist/components/avatar/Avatar.d.ts +4 -0
  4. package/dist/components/avatar/Avatar.d.ts.map +1 -0
  5. package/dist/components/avatar/Avatar.js +80 -0
  6. package/dist/components/avatar/Avatar.js.map +1 -0
  7. package/dist/components/avatar/index.d.ts +4 -0
  8. package/dist/components/avatar/index.d.ts.map +1 -0
  9. package/dist/components/avatar/index.js +3 -0
  10. package/dist/components/avatar/index.js.map +1 -0
  11. package/dist/components/avatar/resolveAvatarInitials.d.ts +2 -0
  12. package/dist/components/avatar/resolveAvatarInitials.d.ts.map +1 -0
  13. package/dist/components/avatar/resolveAvatarInitials.js +44 -0
  14. package/dist/components/avatar/resolveAvatarInitials.js.map +1 -0
  15. package/dist/components/avatar/types.d.ts +17 -0
  16. package/dist/components/avatar/types.d.ts.map +1 -0
  17. package/dist/components/avatar/types.js +2 -0
  18. package/dist/components/avatar/types.js.map +1 -0
  19. package/dist/components/avatar-group/AvatarGroup.d.ts +4 -0
  20. package/dist/components/avatar-group/AvatarGroup.d.ts.map +1 -0
  21. package/dist/components/avatar-group/AvatarGroup.js +26 -0
  22. package/dist/components/avatar-group/AvatarGroup.js.map +1 -0
  23. package/dist/components/avatar-group/index.d.ts +3 -0
  24. package/dist/components/avatar-group/index.d.ts.map +1 -0
  25. package/dist/components/avatar-group/index.js +2 -0
  26. package/dist/components/avatar-group/index.js.map +1 -0
  27. package/dist/components/avatar-group/types.d.ts +22 -0
  28. package/dist/components/avatar-group/types.d.ts.map +1 -0
  29. package/dist/components/avatar-group/types.js +2 -0
  30. package/dist/components/avatar-group/types.js.map +1 -0
  31. package/dist/components/chip/Chip.d.ts +4 -0
  32. package/dist/components/chip/Chip.d.ts.map +1 -0
  33. package/dist/components/chip/Chip.js +54 -0
  34. package/dist/components/chip/Chip.js.map +1 -0
  35. package/dist/components/chip/index.d.ts +3 -0
  36. package/dist/components/chip/index.d.ts.map +1 -0
  37. package/dist/components/chip/index.js +2 -0
  38. package/dist/components/chip/index.js.map +1 -0
  39. package/dist/components/chip/resolveChipColors.d.ts +10 -0
  40. package/dist/components/chip/resolveChipColors.d.ts.map +1 -0
  41. package/dist/components/chip/resolveChipColors.js +47 -0
  42. package/dist/components/chip/resolveChipColors.js.map +1 -0
  43. package/dist/components/chip/types.d.ts +26 -0
  44. package/dist/components/chip/types.d.ts.map +1 -0
  45. package/dist/components/chip/types.js +2 -0
  46. package/dist/components/chip/types.js.map +1 -0
  47. package/dist/components/chip-group/ChipGroup.d.ts +4 -0
  48. package/dist/components/chip-group/ChipGroup.d.ts.map +1 -0
  49. package/dist/components/chip-group/ChipGroup.js +32 -0
  50. package/dist/components/chip-group/ChipGroup.js.map +1 -0
  51. package/dist/components/chip-group/index.d.ts +3 -0
  52. package/dist/components/chip-group/index.d.ts.map +1 -0
  53. package/dist/components/chip-group/index.js +2 -0
  54. package/dist/components/chip-group/index.js.map +1 -0
  55. package/dist/components/chip-group/types.d.ts +31 -0
  56. package/dist/components/chip-group/types.d.ts.map +1 -0
  57. package/dist/components/chip-group/types.js +2 -0
  58. package/dist/components/chip-group/types.js.map +1 -0
  59. package/dist/components/input/Input.d.ts.map +1 -1
  60. package/dist/components/input/Input.js +3 -2
  61. package/dist/components/input/Input.js.map +1 -1
  62. package/dist/components/input/index.d.ts +1 -1
  63. package/dist/components/input/index.d.ts.map +1 -1
  64. package/dist/components/input/index.js.map +1 -1
  65. package/dist/components/input/types.d.ts +15 -2
  66. package/dist/components/input/types.d.ts.map +1 -1
  67. package/dist/components/input/types.js.map +1 -1
  68. package/dist/components/search-bar/SearchBar.d.ts +4 -0
  69. package/dist/components/search-bar/SearchBar.d.ts.map +1 -0
  70. package/dist/components/search-bar/SearchBar.js +18 -0
  71. package/dist/components/search-bar/SearchBar.js.map +1 -0
  72. package/dist/components/search-bar/index.d.ts +3 -0
  73. package/dist/components/search-bar/index.d.ts.map +1 -0
  74. package/dist/components/search-bar/index.js +2 -0
  75. package/dist/components/search-bar/index.js.map +1 -0
  76. package/dist/components/search-bar/types.d.ts +14 -0
  77. package/dist/components/search-bar/types.d.ts.map +1 -0
  78. package/dist/components/search-bar/types.js +2 -0
  79. package/dist/components/search-bar/types.js.map +1 -0
  80. package/dist/index.d.ts +13 -1
  81. package/dist/index.d.ts.map +1 -1
  82. package/dist/index.js +6 -0
  83. package/dist/index.js.map +1 -1
  84. package/dist/patterns/filter-bar/FilterBar.d.ts +4 -0
  85. package/dist/patterns/filter-bar/FilterBar.d.ts.map +1 -0
  86. package/dist/patterns/filter-bar/FilterBar.js +12 -0
  87. package/dist/patterns/filter-bar/FilterBar.js.map +1 -0
  88. package/dist/patterns/filter-bar/index.d.ts +3 -0
  89. package/dist/patterns/filter-bar/index.d.ts.map +1 -0
  90. package/dist/patterns/filter-bar/index.js +2 -0
  91. package/dist/patterns/filter-bar/index.js.map +1 -0
  92. package/dist/patterns/filter-bar/types.d.ts +9 -0
  93. package/dist/patterns/filter-bar/types.d.ts.map +1 -0
  94. package/dist/patterns/filter-bar/types.js +2 -0
  95. package/dist/patterns/filter-bar/types.js.map +1 -0
  96. package/package.json +1 -1
  97. package/src/components/avatar/Avatar.tsx +133 -0
  98. package/src/components/avatar/index.ts +3 -0
  99. package/src/components/avatar/resolveAvatarInitials.test.ts +27 -0
  100. package/src/components/avatar/resolveAvatarInitials.ts +46 -0
  101. package/src/components/avatar/types.ts +20 -0
  102. package/src/components/avatar-group/AvatarGroup.tsx +74 -0
  103. package/src/components/avatar-group/index.ts +2 -0
  104. package/src/components/avatar-group/types.ts +24 -0
  105. package/src/components/chip/Chip.tsx +95 -0
  106. package/src/components/chip/index.ts +2 -0
  107. package/src/components/chip/resolveChipColors.ts +65 -0
  108. package/src/components/chip/types.ts +29 -0
  109. package/src/components/chip-group/ChipGroup.tsx +66 -0
  110. package/src/components/chip-group/index.ts +2 -0
  111. package/src/components/chip-group/types.ts +36 -0
  112. package/src/components/input/Input.tsx +17 -1
  113. package/src/components/input/index.ts +1 -1
  114. package/src/components/input/types.ts +19 -2
  115. package/src/components/search-bar/SearchBar.tsx +50 -0
  116. package/src/components/search-bar/index.ts +2 -0
  117. package/src/components/search-bar/types.ts +14 -0
  118. package/src/index.ts +13 -1
  119. package/src/patterns/filter-bar/FilterBar.tsx +25 -0
  120. package/src/patterns/filter-bar/index.ts +2 -0
  121. package/src/patterns/filter-bar/types.ts +10 -0
  122. package/src/showcaseCoverage.test.ts +6 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - 9d9f997: Add common UI primitives: `Avatar`, `AvatarGroup`, `Chip`, `ChipGroup`, `SearchBar`, and `FilterBar`. Also add `InputTrailingAction` / `trailingAction` support to `Input`.
8
+
3
9
  ## 1.0.4
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -306,6 +306,83 @@ Inherits behavior from Surface `IconButton` including `disabled`, `loading`,
306
306
 
307
307
  </details>
308
308
 
309
+ ### `Avatar`
310
+
311
+ User/profile image with name-based initials and optional icon fallback.
312
+
313
+ ```tsx
314
+ <Avatar name="Zora Kit" />
315
+ <Avatar size="l" tone="primary" name="Fabio Gartenmann" />
316
+ ```
317
+
318
+ <details>
319
+ <summary>Props</summary>
320
+
321
+ ZORA props:
322
+
323
+ | Prop | Type | Default | Notes |
324
+ | -------------- | --------------------- | ----------- | ----------------------------------------------- |
325
+ | `source` | `ImageSourcePropType` | - | React Native `Image` source for the avatar. |
326
+ | `name` | `string` | - | Used to derive initials when `initials` absent. |
327
+ | `initials` | `string` | - | Explicit initials override. |
328
+ | `iconFallback` | `ButtonIconSpec` | - | Optional icon spec when no source/initials. |
329
+ | `label` | `string` | - | Accessibility label for the rendered content. |
330
+ | `size` | `AvatarSize` | `'m'` | `xs`..`xl` size preset. |
331
+ | `shape` | `AvatarShape` | `'circle'` | `circle` or `rounded`. |
332
+ | `tone` | `ZoraTone` | `'neutral'` | Drives background and fallback content tone. |
333
+ | `testID` | `string` | - | Test id. |
334
+
335
+ Inherited props:
336
+
337
+ No inherited props. `AvatarProps` is declared directly by ZORA.
338
+
339
+ </details>
340
+
341
+ ### `AvatarGroup`
342
+
343
+ Overlapping avatar stack with optional overflow label.
344
+
345
+ ```tsx
346
+ <AvatarGroup
347
+ items={[
348
+ { id: '1', name: 'Ada Lovelace' },
349
+ { id: '2', name: 'Grace Hopper', tone: 'success' },
350
+ ]}
351
+ />
352
+ ```
353
+
354
+ <details>
355
+ <summary>Props</summary>
356
+
357
+ ZORA props:
358
+
359
+ | Prop | Type | Default | Notes |
360
+ | --------------- | --------------------------- | ---------- | ------------------------------------ |
361
+ | `items` | `AvatarGroupItem[]` | - | Avatar sources and fallback fields. |
362
+ | `max` | `number` | `4` | Max visible avatars before overflow. |
363
+ | `size` | `AvatarSize` | `'s'` | Avatar size preset. |
364
+ | `shape` | `AvatarShape` | `'circle'` | Avatar shape preset. |
365
+ | `overflowLabel` | `(overflowCount) => string` | `+N` | Overflow label formatter. |
366
+ | `testID` | `string` | - | Test id. |
367
+
368
+ `AvatarGroupItem`:
369
+
370
+ | Prop | Type | Notes |
371
+ | -------------- | --------------------- | ------------------------------- |
372
+ | `id` | `string` | Optional stable key. |
373
+ | `source` | `ImageSourcePropType` | Image source for the avatar. |
374
+ | `name` | `string` | Used to derive initials. |
375
+ | `initials` | `string` | Explicit initials override. |
376
+ | `iconFallback` | `ButtonIconSpec` | Optional icon fallback. |
377
+ | `label` | `string` | Accessibility label. |
378
+ | `tone` | `ZoraTone` | Overrides avatar tone per item. |
379
+
380
+ Inherited props:
381
+
382
+ No inherited props. `AvatarGroupProps` is declared directly by ZORA.
383
+
384
+ </details>
385
+
309
386
  ### `Badge`
310
387
 
311
388
  Small status label with ZORA tone, emphasis, and size defaults.
@@ -383,11 +460,12 @@ Text input wrapper with ZORA sizing and optional Surface icon specs.
383
460
 
384
461
  ZORA props:
385
462
 
386
- | Prop | Type | Default | Notes |
387
- | -------------- | ----------------- | ------- | ---------------------------------------- |
388
- | `size` | `ZoraControlSize` | `'l'` | Passed to Surface as `size`. |
389
- | `leadingIcon` | `ButtonIconSpec` | - | Rendered as Surface `leadingAccessory`. |
390
- | `trailingIcon` | `ButtonIconSpec` | - | Rendered as Surface `trailingAccessory`. |
463
+ | Prop | Type | Default | Notes |
464
+ | ---------------- | --------------------- | ------- | ------------------------------------------------------------------------------ |
465
+ | `size` | `ZoraControlSize` | `'l'` | Passed to Surface as `size`. |
466
+ | `leadingIcon` | `ButtonIconSpec` | - | Rendered as Surface `leadingAccessory`. |
467
+ | `trailingIcon` | `ButtonIconSpec` | - | Rendered as Surface `trailingAccessory`. |
468
+ | `trailingAction` | `InputTrailingAction` | - | Renders an icon-only trailing action (mutually exclusive with `trailingIcon`). |
391
469
 
392
470
  Inherited props:
393
471
 
@@ -400,6 +478,38 @@ Inherits all Surface `TextInputProps` except `leadingAccessory`, `size`, and
400
478
 
401
479
  </details>
402
480
 
481
+ ### `SearchBar`
482
+
483
+ Controlled search input with leading search icon and optional clear action.
484
+
485
+ ```tsx
486
+ <SearchBar value={query} onValueChange={setQuery} onSubmit={(value) => console.log(value)} />
487
+ ```
488
+
489
+ <details>
490
+ <summary>Props</summary>
491
+
492
+ ZORA props:
493
+
494
+ | Prop | Type | Default | Notes |
495
+ | --------------- | ------------------------- | ---------- | --------------------------------------------- |
496
+ | `value` | `string` | - | Current search query. |
497
+ | `onValueChange` | `(value: string) => void` | - | Called when the query changes. |
498
+ | `placeholder` | `string` | `'Search'` | Placeholder text. |
499
+ | `onSubmit` | `(value: string) => void` | - | Called on submit (`returnKeyType="search"`). |
500
+ | `onClear` | `() => void` | - | Called after clearing the query. |
501
+ | `clearable` | `boolean` | `true` | Shows clear action when `value` is non-empty. |
502
+ | `size` | `ZoraControlSize` | `'l'` | Passed to the underlying `Input`. |
503
+ | `disabled` | `boolean` | - | Disables the underlying `Input`. |
504
+ | `readOnly` | `boolean` | - | Makes the underlying `Input` read-only. |
505
+ | `testID` | `string` | - | Test id. |
506
+
507
+ Inherited props:
508
+
509
+ No inherited props. `SearchBarProps` is declared directly by ZORA.
510
+
511
+ </details>
512
+
403
513
  ### `RadioGroup`
404
514
 
405
515
  Single-selection control built on top of Surface `Radio`, designed for use inside `FormField`.
@@ -498,6 +608,76 @@ to underlying Surface `Checkbox` components.
498
608
 
499
609
  </details>
500
610
 
611
+ ### `Chip`
612
+
613
+ Compact filter/action token with optional icon and selected state.
614
+
615
+ ```tsx
616
+ <Chip selected tone="primary" onPress={() => undefined}>
617
+ Selected
618
+ </Chip>
619
+ ```
620
+
621
+ <details>
622
+ <summary>Props</summary>
623
+
624
+ ZORA props:
625
+
626
+ | Prop | Type | Default | Notes |
627
+ | ---------- | ----------------- | ----------- | ------------------------------------ |
628
+ | `children` | `React.ReactNode` | - | Chip label content. |
629
+ | `icon` | `ButtonIconSpec` | - | Optional leading icon spec. |
630
+ | `selected` | `boolean` | `false` | Selected styling state. |
631
+ | `tone` | `ZoraTone` | `'neutral'` | Selected tone. |
632
+ | `size` | `ZoraControlSize` | `'s'` | Padding and icon sizing. |
633
+ | `disabled` | `boolean` | `false` | Disables interaction and mutes tone. |
634
+ | `onPress` | `() => void` | - | Optional press handler. |
635
+ | `testID` | `string` | - | Test id. |
636
+
637
+ Inherited props:
638
+
639
+ No inherited props. `ChipProps` is declared directly by ZORA.
640
+
641
+ </details>
642
+
643
+ ### `ChipGroup`
644
+
645
+ Controlled single- or multi-select chip set for filters and facets.
646
+
647
+ ```tsx
648
+ <ChipGroup
649
+ value="all"
650
+ onValueChange={setValue}
651
+ items={[
652
+ { value: 'all', label: 'All' },
653
+ { value: 'favorites', label: 'Favorites' },
654
+ ]}
655
+ />
656
+ ```
657
+
658
+ <details>
659
+ <summary>Props</summary>
660
+
661
+ ZORA props:
662
+
663
+ | Prop | Type | Default | Notes |
664
+ | --------------- | -------------------- | ----------- | ------------------------------ |
665
+ | `items` | `ChipGroupItem[]` | - | Rendered chips. |
666
+ | `value` | `string \| string[]` | - | Selected value(s). |
667
+ | `onValueChange` | `(value) => void` | - | Selection change handler. |
668
+ | `multiple` | `boolean` | `false` | Enables multi-select mode. |
669
+ | `tone` | `ZoraTone` | `'neutral'` | Tone for selected chips. |
670
+ | `size` | `ZoraControlSize` | `'s'` | Chip size. |
671
+ | `wrap` | `boolean` | `true` | Wrap chips on smaller screens. |
672
+ | `disabled` | `boolean` | - | Disables all chips. |
673
+ | `testID` | `string` | - | Test id. |
674
+
675
+ Inherited props:
676
+
677
+ No inherited props. `ChipGroupProps` is declared directly by ZORA.
678
+
679
+ </details>
680
+
501
681
  ### `Textarea`
502
682
 
503
683
  Multiline text input wrapper with ZORA sizing and optional Surface icon specs.
@@ -1064,6 +1244,35 @@ No inherited props. `SectionHeaderProps` is declared directly by ZORA.
1064
1244
 
1065
1245
  </details>
1066
1246
 
1247
+ ### `FilterBar`
1248
+
1249
+ Composable row for search + chips + trailing actions.
1250
+
1251
+ ```tsx
1252
+ <FilterBar leading={<SearchBar value={query} onValueChange={setQuery} />}>
1253
+ <ChipGroup value="all" onValueChange={setFilter} items={[{ value: 'all', label: 'All' }]} />
1254
+ </FilterBar>
1255
+ ```
1256
+
1257
+ <details>
1258
+ <summary>Props</summary>
1259
+
1260
+ ZORA props:
1261
+
1262
+ | Prop | Type | Default | Notes |
1263
+ | ---------- | ----------------- | ------- | ------------------------------ |
1264
+ | `leading` | `React.ReactNode` | - | Optional leading content. |
1265
+ | `children` | `React.ReactNode` | - | Main filter controls. |
1266
+ | `trailing` | `React.ReactNode` | - | Optional trailing content. |
1267
+ | `wrap` | `boolean` | `true` | Wraps content on small widths. |
1268
+ | `testID` | `string` | - | Test id. |
1269
+
1270
+ Inherited props:
1271
+
1272
+ No inherited props. `FilterBarProps` is declared directly by ZORA.
1273
+
1274
+ </details>
1275
+
1067
1276
  ### `SettingsRow`
1068
1277
 
1069
1278
  Compact settings row with optional metadata, control, and press handling.
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { AvatarProps } from './types';
3
+ export declare const Avatar: (props: AvatarProps) => React.ReactElement | null;
4
+ //# sourceMappingURL=Avatar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/Avatar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,KAAK,EAAE,WAAW,EAA2B,MAAM,SAAS,CAAC;AAyHpE,eAAO,MAAM,MAAM,mDAAkC,CAAC"}
@@ -0,0 +1,80 @@
1
+ import React from 'react';
2
+ import { Image } from 'react-native';
3
+ import { Box } from '../../foundation';
4
+ import { useZoraTheme } from '../../theme/useZoraTheme';
5
+ import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
6
+ import { Icon } from '../icon';
7
+ import { Text } from '../text';
8
+ import { resolveAvatarInitials } from './resolveAvatarInitials';
9
+ const AVATAR_SIZES = {
10
+ xs: 24,
11
+ s: 32,
12
+ m: 40,
13
+ l: 48,
14
+ xl: 64,
15
+ };
16
+ function resolveRoleSemantics(theme, tone) {
17
+ switch (tone) {
18
+ case 'primary':
19
+ return theme.semantics.action.primary;
20
+ case 'danger':
21
+ return theme.semantics.action.danger;
22
+ case 'success':
23
+ return theme.semantics.success;
24
+ case 'warning':
25
+ return theme.semantics.warning;
26
+ case 'neutral':
27
+ default:
28
+ return theme.semantics.action.neutral;
29
+ }
30
+ }
31
+ function resolveTextTone(tone) {
32
+ return tone === 'neutral' ? 'default' : tone;
33
+ }
34
+ function resolveTextVariant(size) {
35
+ switch (size) {
36
+ case 'xs':
37
+ case 's':
38
+ return 'caption';
39
+ case 'l':
40
+ return 'bodySmall';
41
+ case 'xl':
42
+ return 'lead';
43
+ case 'm':
44
+ default:
45
+ return 'label';
46
+ }
47
+ }
48
+ function resolveRadius(shape) {
49
+ return shape === 'circle' ? 'full' : 'l';
50
+ }
51
+ function AvatarInner({ themeId: _themeId, mode: _mode, testID, source, name, initials, iconFallback, label, size = 'm', shape = 'circle', tone = 'neutral', }) {
52
+ const { theme } = useZoraTheme();
53
+ const resolvedSize = AVATAR_SIZES[size];
54
+ const resolvedInitials = initials ?? resolveAvatarInitials(name);
55
+ const role = resolveRoleSemantics(theme, tone);
56
+ const backgroundColor = tone === 'neutral' ? theme.semantics.neutral.surface : role.softBg;
57
+ const contentColor = tone === 'neutral' ? theme.semantics.content.default : role.base;
58
+ const radius = resolveRadius(shape);
59
+ const renderFallback = () => {
60
+ if (resolvedInitials) {
61
+ return (<Text tone={resolveTextTone(tone)} variant={resolveTextVariant(size)} weight="semiBold">
62
+ {resolvedInitials}
63
+ </Text>);
64
+ }
65
+ if (iconFallback) {
66
+ const iconSize = Math.max(16, Math.round(resolvedSize * 0.48));
67
+ return (<Icon color={contentColor} name={iconFallback.name} provider={iconFallback.provider} size={iconSize}/>);
68
+ }
69
+ return null;
70
+ };
71
+ return (<Box accessibilityLabel={label} bg={backgroundColor} height={resolvedSize} radius={radius} testID={testID} width={resolvedSize} style={{
72
+ alignItems: 'center',
73
+ justifyContent: 'center',
74
+ overflow: 'hidden',
75
+ }}>
76
+ {source ? (<Image accessibilityLabel={label} source={source} style={{ height: '100%', width: '100%' }}/>) : (renderFallback())}
77
+ </Box>);
78
+ }
79
+ export const Avatar = withZoraThemeScope(AvatarInner);
80
+ //# sourceMappingURL=Avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Avatar.js","sourceRoot":"","sources":["../../../src/components/avatar/Avatar.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { RoleSemantics, SurfaceTheme } from '@ankhorage/surface';\nimport React from 'react';\nimport { Image } from 'react-native';\n\nimport { Box } from '../../foundation';\nimport type { ZoraTone } from '../../internal/recipes';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Icon } from '../icon';\nimport { Text, type TextTone, type TextVariant } from '../text';\nimport { resolveAvatarInitials } from './resolveAvatarInitials';\nimport type { AvatarProps, AvatarShape, AvatarSize } from './types';\n\nconst AVATAR_SIZES: Record<AvatarSize, number> = {\n xs: 24,\n s: 32,\n m: 40,\n l: 48,\n xl: 64,\n};\n\nfunction resolveRoleSemantics(theme: SurfaceTheme, tone: ZoraTone): RoleSemantics {\n switch (tone) {\n case 'primary':\n return theme.semantics.action.primary;\n case 'danger':\n return theme.semantics.action.danger;\n case 'success':\n return theme.semantics.success;\n case 'warning':\n return theme.semantics.warning;\n case 'neutral':\n default:\n return theme.semantics.action.neutral;\n }\n}\n\nfunction resolveTextTone(tone: ZoraTone): TextTone {\n return tone === 'neutral' ? 'default' : tone;\n}\n\nfunction resolveTextVariant(size: AvatarSize): TextVariant {\n switch (size) {\n case 'xs':\n case 's':\n return 'caption';\n case 'l':\n return 'bodySmall';\n case 'xl':\n return 'lead';\n case 'm':\n default:\n return 'label';\n }\n}\n\nfunction resolveRadius(shape: AvatarShape): 'full' | 'l' {\n return shape === 'circle' ? 'full' : 'l';\n}\n\nfunction AvatarInner({\n themeId: _themeId,\n mode: _mode,\n testID,\n source,\n name,\n initials,\n iconFallback,\n label,\n size = 'm',\n shape = 'circle',\n tone = 'neutral',\n}: AvatarProps) {\n const { theme } = useZoraTheme();\n const resolvedSize = AVATAR_SIZES[size];\n const resolvedInitials = initials ?? resolveAvatarInitials(name);\n const role = resolveRoleSemantics(theme, tone);\n const backgroundColor = tone === 'neutral' ? theme.semantics.neutral.surface : role.softBg;\n const contentColor = tone === 'neutral' ? theme.semantics.content.default : role.base;\n const radius = resolveRadius(shape);\n\n const renderFallback = () => {\n if (resolvedInitials) {\n return (\n <Text tone={resolveTextTone(tone)} variant={resolveTextVariant(size)} weight=\"semiBold\">\n {resolvedInitials}\n </Text>\n );\n }\n\n if (iconFallback) {\n const iconSize = Math.max(16, Math.round(resolvedSize * 0.48));\n return (\n <Icon\n color={contentColor}\n name={iconFallback.name}\n provider={iconFallback.provider}\n size={iconSize}\n />\n );\n }\n\n return null;\n };\n\n return (\n <Box\n accessibilityLabel={label}\n bg={backgroundColor}\n height={resolvedSize}\n radius={radius}\n testID={testID}\n width={resolvedSize}\n style={{\n alignItems: 'center',\n justifyContent: 'center',\n overflow: 'hidden',\n }}\n >\n {source ? (\n <Image\n accessibilityLabel={label}\n source={source}\n style={{ height: '100%', width: '100%' }}\n />\n ) : (\n renderFallback()\n )}\n </Box>\n );\n}\n\nexport const Avatar = withZoraThemeScope(AvatarInner);\n"]}
@@ -0,0 +1,4 @@
1
+ export { Avatar } from './Avatar';
2
+ export { resolveAvatarInitials } from './resolveAvatarInitials';
3
+ export type { AvatarProps, AvatarShape, AvatarSize } from './types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { Avatar } from './Avatar';
2
+ export { resolveAvatarInitials } from './resolveAvatarInitials';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/avatar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC","sourcesContent":["export { Avatar } from './Avatar';\nexport { resolveAvatarInitials } from './resolveAvatarInitials';\nexport type { AvatarProps, AvatarShape, AvatarSize } from './types';\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function resolveAvatarInitials(name: string | undefined): string | null;
2
+ //# sourceMappingURL=resolveAvatarInitials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveAvatarInitials.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/resolveAvatarInitials.ts"],"names":[],"mappings":"AAmBA,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CA0B7E"}
@@ -0,0 +1,44 @@
1
+ function takeFirstCharacter(value) {
2
+ const trimmed = value.trim();
3
+ if (!trimmed)
4
+ return null;
5
+ const chars = Array.from(trimmed);
6
+ return chars[0] ? chars[0].toUpperCase() : null;
7
+ }
8
+ function takeFirstTwoCharacters(value) {
9
+ const trimmed = value.trim();
10
+ if (!trimmed)
11
+ return null;
12
+ const chars = Array.from(trimmed);
13
+ const [first, second] = chars;
14
+ if (!first)
15
+ return null;
16
+ return `${first}${second ?? ''}`.toUpperCase();
17
+ }
18
+ export function resolveAvatarInitials(name) {
19
+ if (!name)
20
+ return null;
21
+ const parts = name
22
+ .trim()
23
+ .split(/\s+/)
24
+ .map((part) => part.trim())
25
+ .filter(Boolean);
26
+ if (parts.length === 0)
27
+ return null;
28
+ if (parts.length === 1) {
29
+ const [part] = parts;
30
+ return part ? takeFirstTwoCharacters(part) : null;
31
+ }
32
+ const [firstPart] = parts;
33
+ const [lastPart] = parts.slice(-1);
34
+ const first = firstPart ? takeFirstCharacter(firstPart) : null;
35
+ const last = lastPart ? takeFirstCharacter(lastPart) : null;
36
+ if (!first && !last)
37
+ return null;
38
+ if (!last)
39
+ return first;
40
+ if (!first)
41
+ return last;
42
+ return `${first}${last}`;
43
+ }
44
+ //# sourceMappingURL=resolveAvatarInitials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveAvatarInitials.js","sourceRoot":"","sources":["../../../src/components/avatar/resolveAvatarInitials.ts"],"names":[],"mappings":"AAAA,SAAS,kBAAkB,CAAC,KAAa;IACvC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAa;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAC9B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,OAAO,GAAG,KAAK,GAAG,MAAM,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAwB;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,KAAK,GAAG,IAAI;SACf,IAAI,EAAE;SACN,KAAK,CAAC,KAAK,CAAC;SACZ,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACrB,OAAO,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC;IAC1B,MAAM,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/D,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE5D,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,OAAO,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC;AAC3B,CAAC","sourcesContent":["function takeFirstCharacter(value: string): string | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n const chars = Array.from(trimmed);\n return chars[0] ? chars[0].toUpperCase() : null;\n}\n\nfunction takeFirstTwoCharacters(value: string): string | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n const chars = Array.from(trimmed);\n const [first, second] = chars;\n if (!first) return null;\n\n return `${first}${second ?? ''}`.toUpperCase();\n}\n\nexport function resolveAvatarInitials(name: string | undefined): string | null {\n if (!name) return null;\n\n const parts = name\n .trim()\n .split(/\\s+/)\n .map((part) => part.trim())\n .filter(Boolean);\n\n if (parts.length === 0) return null;\n\n if (parts.length === 1) {\n const [part] = parts;\n return part ? takeFirstTwoCharacters(part) : null;\n }\n\n const [firstPart] = parts;\n const [lastPart] = parts.slice(-1);\n const first = firstPart ? takeFirstCharacter(firstPart) : null;\n const last = lastPart ? takeFirstCharacter(lastPart) : null;\n\n if (!first && !last) return null;\n if (!last) return first;\n if (!first) return last;\n\n return `${first}${last}`;\n}\n"]}
@@ -0,0 +1,17 @@
1
+ import type { ButtonIconSpec } from '@ankhorage/surface';
2
+ import type { ImageSourcePropType } from 'react-native';
3
+ import type { ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
5
+ export type AvatarSize = 'xs' | 's' | 'm' | 'l' | 'xl';
6
+ export type AvatarShape = 'circle' | 'rounded';
7
+ export interface AvatarProps extends ZoraBaseProps {
8
+ source?: ImageSourcePropType;
9
+ name?: string;
10
+ initials?: string;
11
+ iconFallback?: ButtonIconSpec;
12
+ label?: string;
13
+ size?: AvatarSize;
14
+ shape?: AvatarShape;
15
+ tone?: ZoraTone;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/avatar/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;AAEvD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/C,MAAM,WAAW,WAAY,SAAQ,aAAa;IAChD,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/avatar/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ButtonIconSpec } from '@ankhorage/surface';\nimport type { ImageSourcePropType } from 'react-native';\n\nimport type { ZoraTone } from '../../internal/recipes';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport type AvatarSize = 'xs' | 's' | 'm' | 'l' | 'xl';\n\nexport type AvatarShape = 'circle' | 'rounded';\n\nexport interface AvatarProps extends ZoraBaseProps {\n source?: ImageSourcePropType;\n name?: string;\n initials?: string;\n iconFallback?: ButtonIconSpec;\n label?: string;\n size?: AvatarSize;\n shape?: AvatarShape;\n tone?: ZoraTone;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { AvatarGroupProps } from './types';
3
+ export declare const AvatarGroup: (props: AvatarGroupProps) => React.ReactElement | null;
4
+ //# sourceMappingURL=AvatarGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroup.d.ts","sourceRoot":"","sources":["../../../src/components/avatar-group/AvatarGroup.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAmEjE,eAAO,MAAM,WAAW,wDAAuC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import React from 'react';
2
+ import { Box, Stack } from '../../foundation';
3
+ import { useZoraTheme } from '../../theme/useZoraTheme';
4
+ import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
5
+ import { Avatar } from '../avatar';
6
+ function defaultOverflowLabel(overflowCount) {
7
+ return `+${overflowCount}`;
8
+ }
9
+ function AvatarGroupInner({ themeId: _themeId, mode: _mode, testID, items, max = 4, size = 's', shape = 'circle', overflowLabel = defaultOverflowLabel, }) {
10
+ const { theme } = useZoraTheme();
11
+ const visibleItems = items.slice(0, max);
12
+ const overflowCount = Math.max(0, items.length - visibleItems.length);
13
+ const overlap = size === 'xs' ? 8 : size === 's' ? 10 : size === 'm' ? 12 : size === 'l' ? 14 : 16;
14
+ const borderColor = theme.semantics.surface.default;
15
+ const renderItem = (item, index) => (<Box key={item.id ?? `${index}`} ml={index === 0 ? 0 : -overlap} radius="full" borderWidth={2} borderColor={borderColor}>
16
+ <Avatar iconFallback={item.iconFallback} initials={item.initials} label={item.label} name={item.name} shape={shape} size={size} source={item.source} tone={item.tone}/>
17
+ </Box>);
18
+ return (<Stack align="center" direction="row" testID={testID} wrap="nowrap">
19
+ {visibleItems.map(renderItem)}
20
+ {overflowCount > 0 ? (<Box ml={visibleItems.length === 0 ? 0 : -overlap} radius="full" borderWidth={2} borderColor={borderColor}>
21
+ <Avatar initials={overflowLabel(overflowCount)} size={size} shape={shape} tone="neutral"/>
22
+ </Box>) : null}
23
+ </Stack>);
24
+ }
25
+ export const AvatarGroup = withZoraThemeScope(AvatarGroupInner);
26
+ //# sourceMappingURL=AvatarGroup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AvatarGroup.js","sourceRoot":"","sources":["../../../src/components/avatar-group/AvatarGroup.tsx"],"names":[],"mappings":"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","sourcesContent":["import React from 'react';\n\nimport { Box, Stack } from '../../foundation';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport { Avatar } from '../avatar';\nimport type { AvatarGroupItem, AvatarGroupProps } from './types';\n\nfunction defaultOverflowLabel(overflowCount: number): string {\n return `+${overflowCount}`;\n}\n\nfunction AvatarGroupInner({\n themeId: _themeId,\n mode: _mode,\n testID,\n items,\n max = 4,\n size = 's',\n shape = 'circle',\n overflowLabel = defaultOverflowLabel,\n}: AvatarGroupProps) {\n const { theme } = useZoraTheme();\n\n const visibleItems = items.slice(0, max);\n const overflowCount = Math.max(0, items.length - visibleItems.length);\n const overlap =\n size === 'xs' ? 8 : size === 's' ? 10 : size === 'm' ? 12 : size === 'l' ? 14 : 16;\n const borderColor = theme.semantics.surface.default;\n\n const renderItem = (item: AvatarGroupItem, index: number) => (\n <Box\n key={item.id ?? `${index}`}\n ml={index === 0 ? 0 : -overlap}\n radius=\"full\"\n borderWidth={2}\n borderColor={borderColor}\n >\n <Avatar\n iconFallback={item.iconFallback}\n initials={item.initials}\n label={item.label}\n name={item.name}\n shape={shape}\n size={size}\n source={item.source}\n tone={item.tone}\n />\n </Box>\n );\n\n return (\n <Stack align=\"center\" direction=\"row\" testID={testID} wrap=\"nowrap\">\n {visibleItems.map(renderItem)}\n {overflowCount > 0 ? (\n <Box\n ml={visibleItems.length === 0 ? 0 : -overlap}\n radius=\"full\"\n borderWidth={2}\n borderColor={borderColor}\n >\n <Avatar\n initials={overflowLabel(overflowCount)}\n size={size}\n shape={shape}\n tone=\"neutral\"\n />\n </Box>\n ) : null}\n </Stack>\n );\n}\n\nexport const AvatarGroup = withZoraThemeScope(AvatarGroupInner);\n"]}
@@ -0,0 +1,3 @@
1
+ export { AvatarGroup } from './AvatarGroup';
2
+ export type { AvatarGroupItem, AvatarGroupProps } from './types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/avatar-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { AvatarGroup } from './AvatarGroup';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/components/avatar-group/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC","sourcesContent":["export { AvatarGroup } from './AvatarGroup';\nexport type { AvatarGroupItem, AvatarGroupProps } from './types';\n"]}
@@ -0,0 +1,22 @@
1
+ import type { ButtonIconSpec } from '@ankhorage/surface';
2
+ import type { ImageSourcePropType } from 'react-native';
3
+ import type { ZoraTone } from '../../internal/recipes';
4
+ import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
5
+ import type { AvatarShape, AvatarSize } from '../avatar';
6
+ export interface AvatarGroupItem {
7
+ id?: string;
8
+ source?: ImageSourcePropType;
9
+ name?: string;
10
+ initials?: string;
11
+ iconFallback?: ButtonIconSpec;
12
+ label?: string;
13
+ tone?: ZoraTone;
14
+ }
15
+ export interface AvatarGroupProps extends ZoraBaseProps {
16
+ items: readonly AvatarGroupItem[];
17
+ max?: number;
18
+ size?: AvatarSize;
19
+ shape?: AvatarShape;
20
+ overflowLabel?: (overflowCount: number) => string;
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/avatar-group/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,CAAC;CACnD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/components/avatar-group/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ButtonIconSpec } from '@ankhorage/surface';\nimport type { ImageSourcePropType } from 'react-native';\n\nimport type { ZoraTone } from '../../internal/recipes';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\nimport type { AvatarShape, AvatarSize } from '../avatar';\n\nexport interface AvatarGroupItem {\n id?: string;\n source?: ImageSourcePropType;\n name?: string;\n initials?: string;\n iconFallback?: ButtonIconSpec;\n label?: string;\n tone?: ZoraTone;\n}\n\nexport interface AvatarGroupProps extends ZoraBaseProps {\n items: readonly AvatarGroupItem[];\n max?: number;\n size?: AvatarSize;\n shape?: AvatarShape;\n overflowLabel?: (overflowCount: number) => string;\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { ChipProps } from './types';
3
+ export declare const Chip: (props: ChipProps) => React.ReactElement | null;
4
+ //# sourceMappingURL=Chip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Chip.d.ts","sourceRoot":"","sources":["../../../src/components/chip/Chip.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAS1B,OAAO,KAAK,EAAwB,SAAS,EAAE,MAAM,SAAS,CAAC;AAoF/D,eAAO,MAAM,IAAI,iDAAgC,CAAC"}