panelui-native 0.4.0 → 0.5.3

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 (51) hide show
  1. package/README.md +16 -8
  2. package/lib/module/components/accordion/index.js +312 -0
  3. package/lib/module/components/accordion/index.js.map +1 -0
  4. package/lib/module/components/avatar/index.js +58 -17
  5. package/lib/module/components/avatar/index.js.map +1 -1
  6. package/lib/module/components/badge/index.js +26 -5
  7. package/lib/module/components/badge/index.js.map +1 -1
  8. package/lib/module/components/button/index.js +51 -19
  9. package/lib/module/components/button/index.js.map +1 -1
  10. package/lib/module/components/checkbox/index.js +42 -14
  11. package/lib/module/components/checkbox/index.js.map +1 -1
  12. package/lib/module/components/frame/index.js +64 -13
  13. package/lib/module/components/frame/index.js.map +1 -1
  14. package/lib/module/components/timeline/index.js +658 -0
  15. package/lib/module/components/timeline/index.js.map +1 -0
  16. package/lib/module/components/toast/index.js +145 -55
  17. package/lib/module/components/toast/index.js.map +1 -1
  18. package/lib/module/icons/index.js +388 -27
  19. package/lib/module/icons/index.js.map +1 -1
  20. package/lib/module/index.js +3 -1
  21. package/lib/module/index.js.map +1 -1
  22. package/lib/typescript/src/components/accordion/index.d.ts +56 -0
  23. package/lib/typescript/src/components/accordion/index.d.ts.map +1 -0
  24. package/lib/typescript/src/components/avatar/index.d.ts +8 -1
  25. package/lib/typescript/src/components/avatar/index.d.ts.map +1 -1
  26. package/lib/typescript/src/components/badge/index.d.ts +38 -0
  27. package/lib/typescript/src/components/badge/index.d.ts.map +1 -1
  28. package/lib/typescript/src/components/button/index.d.ts +18 -0
  29. package/lib/typescript/src/components/button/index.d.ts.map +1 -1
  30. package/lib/typescript/src/components/checkbox/index.d.ts +42 -0
  31. package/lib/typescript/src/components/checkbox/index.d.ts.map +1 -1
  32. package/lib/typescript/src/components/frame/index.d.ts +39 -5
  33. package/lib/typescript/src/components/frame/index.d.ts.map +1 -1
  34. package/lib/typescript/src/components/timeline/index.d.ts +96 -0
  35. package/lib/typescript/src/components/timeline/index.d.ts.map +1 -0
  36. package/lib/typescript/src/components/toast/index.d.ts.map +1 -1
  37. package/lib/typescript/src/icons/index.d.ts +38 -3
  38. package/lib/typescript/src/icons/index.d.ts.map +1 -1
  39. package/lib/typescript/src/index.d.ts +4 -2
  40. package/lib/typescript/src/index.d.ts.map +1 -1
  41. package/package.json +1 -1
  42. package/src/components/accordion/index.tsx +344 -0
  43. package/src/components/avatar/index.tsx +68 -20
  44. package/src/components/badge/index.tsx +35 -6
  45. package/src/components/button/index.tsx +63 -20
  46. package/src/components/checkbox/index.tsx +49 -11
  47. package/src/components/frame/index.tsx +101 -31
  48. package/src/components/timeline/index.tsx +482 -0
  49. package/src/components/toast/index.tsx +166 -45
  50. package/src/icons/index.tsx +292 -27
  51. package/src/index.ts +38 -1
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # PanelUI — React Native UI components for Expo, styled with Tailwind CSS
2
2
 
3
3
  **PanelUI** (`panelui-native`) is an accessible, high-performance React Native component
4
- library for Expo apps. 24 typed components — buttons, bottom sheets, dialogs, selects,
4
+ library for Expo apps. 26 typed components — buttons, bottom sheets, dialogs, selects,
5
5
  toasts, forms — styled with Tailwind CSS v4 and animated on the UI thread with Reanimated.
6
6
  Zero native code, so it runs in Expo Go.
7
7
 
@@ -90,16 +90,17 @@ overlays, and the toast viewport.
90
90
 
91
91
  | Component | What it does |
92
92
  | --- | --- |
93
+ | `Accordion` | Collapsible sections — five variants, single or multiple selection |
93
94
  | `Alert` | Status message with a built-in icon — info, success, warning, destructive |
94
- | `Avatar` | User image with initials fallback, four sizes |
95
- | `Badge` | Compact status label with semantic colour variants |
95
+ | `Avatar` | User image with initials fallback, four sizes, `Avatar.Badge` overlay |
96
+ | `Badge` | Status label, dot, or a count clamped at 99+ |
96
97
  | `BottomSheet` | Draggable bottom sheet with swipe-to-dismiss |
97
- | `Button` | Pressable action with variants, sizes, loading state and icon slots |
98
+ | `Button` | Variants (including social sign-in), sizes, loading, theme-aware icon slots |
98
99
  | `Card` | Content surface with `Header`, `Content` and `Footer` |
99
- | `Checkbox` | Animated checkbox with label and description |
100
+ | `Checkbox` | Animated checkbox with label, description, and a checkable card variant |
100
101
  | `Dialog` | Modal dialog with backdrop, title, description and footer actions |
101
102
  | `EmptyState` | Placeholder for an empty list or screen, with a stacked-icon media slot |
102
- | `Frame` | Grouped list section with `Header`, `Panel`, `Row` and `Footer` |
103
+ | `Frame` | Widget shell — header row with action, inset panel of rows, caption footer |
103
104
  | `InlineSelect` | Picker that expands its options in place |
104
105
  | `Input` | Text field with label, description and error message |
105
106
  | `InputGroup` | Input with leading and trailing decorators, auto-measured |
@@ -112,11 +113,17 @@ overlays, and the toast viewport.
112
113
  | `Steps` | Stepper for multi-step flows, horizontal or vertical |
113
114
  | `Switch` | Animated on/off toggle |
114
115
  | `Tabs` | Segmented navigation with animated indicator |
116
+ | `Timeline` | Vertical sequence of events — dot, icon, numbered, card or compact, with per-item tones |
115
117
  | `Toast` | Transient notification queue with swipe-to-dismiss |
116
118
  | `Typography` | Semantic text presets — `h1`–`h6`, body sizes, inline code |
117
119
 
118
120
  Plus `PanelUIProvider`, `Portal`, `AnimatedPressable`, `Text`, `useTheme`, `useThemeMode`,
119
- `useToast`, a set of SVG icons, and the `cn` class-merging helper.
121
+ `useToast`, a set of SVG icons (with brand marks for Google, Facebook and Apple), and the `cn`
122
+ class-merging helper.
123
+
124
+ Icons inside a coloured surface inherit a readable colour automatically — `Button` provides the
125
+ foreground its variant reads against, so an icon in `startContent` follows the theme without a
126
+ hardcoded hex. Wrap your own surfaces in `IconColorProvider` to do the same.
120
127
 
121
128
  Every component takes a `className`, so anything can be restyled with Tailwind utilities:
122
129
 
@@ -242,7 +249,8 @@ Named themes must be listed in `extraThemes` in your Metro config — see [Quick
242
249
 
243
250
  ## Links
244
251
 
245
- - **Documentation and source:** [github.com/panel-ui/PanelUI](https://github.com/panel-ui/PanelUI)
252
+ - **Documentation:** [panelui.dev](https://panelui.dev) — a page per component, with anatomy, props and examples
253
+ - **Source:** [github.com/panel-ui/PanelUI](https://github.com/panel-ui/PanelUI)
246
254
  - **Report an issue:** [github.com/panel-ui/PanelUI/issues](https://github.com/panel-ui/PanelUI/issues)
247
255
  - **Changelog:** [releases](https://github.com/panel-ui/PanelUI/releases)
248
256
 
@@ -0,0 +1,312 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Accordion — collapsible sections.
5
+ *
6
+ * Adapted from: heroui-inc/heroui-native src/components/accordion/
7
+ * (the Item / Trigger / Indicator / Content anatomy, single vs multiple
8
+ * selection, the rotating chevron indicator, and layout-transition expand).
9
+ *
10
+ * Upstream ships `default` and `surface`; the extra variants here follow the
11
+ * same slot structure.
12
+ */
13
+ import { Children, createContext, forwardRef, isValidElement, useCallback, useContext, useMemo, useState } from 'react';
14
+ import { Pressable, View } from 'react-native';
15
+ import Animated, { LinearTransition, useAnimatedStyle, useDerivedValue, withTiming } from 'react-native-reanimated';
16
+ import { tv } from 'tailwind-variants';
17
+ import { ChevronDownIcon } from "../../icons/index.js";
18
+ import { Text } from "../../primitives/text.js";
19
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
20
+ const accordionVariants = tv({
21
+ slots: {
22
+ root: 'w-full flex-col overflow-hidden',
23
+ separator: 'h-px bg-border',
24
+ item: 'flex-col overflow-hidden',
25
+ trigger: 'flex-row items-center justify-between gap-4 py-4',
26
+ title: 'flex-1 text-base font-medium text-foreground',
27
+ indicator: 'items-center justify-center',
28
+ content: 'pb-4',
29
+ contentText: 'text-sm text-muted-foreground'
30
+ },
31
+ variants: {
32
+ variant: {
33
+ default: {
34
+ trigger: 'px-1',
35
+ content: 'px-1'
36
+ },
37
+ surface: {
38
+ root: 'rounded-2xl border border-border bg-surface',
39
+ separator: 'mx-4',
40
+ trigger: 'px-4',
41
+ content: 'px-4'
42
+ },
43
+ separated: {
44
+ root: 'gap-2.5 overflow-visible',
45
+ separator: 'hidden',
46
+ item: 'rounded-xl border border-border bg-card',
47
+ trigger: 'px-4',
48
+ content: 'px-4'
49
+ },
50
+ bordered: {
51
+ separator: 'hidden',
52
+ item: 'mb-2 rounded-xl border border-border',
53
+ trigger: 'px-4',
54
+ content: 'px-4'
55
+ },
56
+ ghost: {
57
+ separator: 'hidden',
58
+ trigger: 'px-0',
59
+ content: 'px-0'
60
+ }
61
+ }
62
+ },
63
+ defaultVariants: {
64
+ variant: 'default'
65
+ }
66
+ });
67
+ const AccordionContext = /*#__PURE__*/createContext(null);
68
+ const AccordionItemContext = /*#__PURE__*/createContext(null);
69
+ function useAccordion(component) {
70
+ const context = useContext(AccordionContext);
71
+ if (!context) throw new Error(`${component} must be used within an <Accordion>`);
72
+ return context;
73
+ }
74
+ function useAccordionItem(component) {
75
+ const context = useContext(AccordionItemContext);
76
+ if (!context) throw new Error(`${component} must be used within an <Accordion.Item>`);
77
+ return context;
78
+ }
79
+ const toArray = value => value === undefined ? [] : Array.isArray(value) ? value : [value];
80
+ const AccordionRoot = /*#__PURE__*/forwardRef(({
81
+ className,
82
+ variant = 'default',
83
+ selectionMode = 'single',
84
+ value,
85
+ defaultValue,
86
+ onValueChange,
87
+ hideSeparator = false,
88
+ children,
89
+ ...props
90
+ }, ref) => {
91
+ const [internal, setInternal] = useState(() => toArray(defaultValue));
92
+ const isControlled = value !== undefined;
93
+ const expanded = isControlled ? toArray(value) : internal;
94
+ const toggle = useCallback(itemValue => {
95
+ const isOpen = expanded.includes(itemValue);
96
+ const next = selectionMode === 'single' ? isOpen ? [] : [itemValue] : isOpen ? expanded.filter(entry => entry !== itemValue) : [...expanded, itemValue];
97
+ if (!isControlled) setInternal(next);
98
+ // Hand back the shape the caller gave us.
99
+ onValueChange?.(selectionMode === 'single' ? next[0] ?? '' : next);
100
+ }, [expanded, selectionMode, isControlled, onValueChange]);
101
+ const context = useMemo(() => ({
102
+ expanded,
103
+ toggle,
104
+ variant
105
+ }), [expanded, toggle, variant]);
106
+ const {
107
+ root,
108
+ separator
109
+ } = accordionVariants({
110
+ variant
111
+ });
112
+ const items = Children.toArray(children).filter(isValidElement);
113
+ return /*#__PURE__*/_jsx(AccordionContext.Provider, {
114
+ value: context,
115
+ children: /*#__PURE__*/_jsx(Animated.View, {
116
+ ref: ref,
117
+ layout: LinearTransition.duration(200),
118
+ className: root({
119
+ className
120
+ }),
121
+ ...props,
122
+ children: items.map((child, index) => /*#__PURE__*/_jsxs(View, {
123
+ children: [child, !hideSeparator && index < items.length - 1 ? /*#__PURE__*/_jsx(View, {
124
+ className: separator()
125
+ }) : null]
126
+ }, child.key ?? index))
127
+ })
128
+ });
129
+ });
130
+ AccordionRoot.displayName = 'Accordion';
131
+ const AccordionItem = /*#__PURE__*/forwardRef(({
132
+ className,
133
+ value,
134
+ isDisabled = false,
135
+ children,
136
+ ...props
137
+ }, ref) => {
138
+ const {
139
+ expanded,
140
+ variant
141
+ } = useAccordion('Accordion.Item');
142
+ const isExpanded = expanded.includes(value);
143
+ const {
144
+ item
145
+ } = accordionVariants({
146
+ variant
147
+ });
148
+ const context = useMemo(() => ({
149
+ value,
150
+ isExpanded,
151
+ isDisabled
152
+ }), [value, isExpanded, isDisabled]);
153
+ return /*#__PURE__*/_jsx(AccordionItemContext.Provider, {
154
+ value: context,
155
+ children: /*#__PURE__*/_jsx(Animated.View, {
156
+ ref: ref,
157
+ layout: LinearTransition.duration(200),
158
+ className: item({
159
+ className
160
+ }),
161
+ ...props,
162
+ children: children
163
+ })
164
+ });
165
+ });
166
+ AccordionItem.displayName = 'Accordion.Item';
167
+ /** The pressable header row. Bare strings are wrapped in the title style. */
168
+ const AccordionTrigger = /*#__PURE__*/forwardRef(({
169
+ className,
170
+ children,
171
+ ...props
172
+ }, ref) => {
173
+ const {
174
+ toggle,
175
+ variant
176
+ } = useAccordion('Accordion.Trigger');
177
+ const {
178
+ value,
179
+ isExpanded,
180
+ isDisabled
181
+ } = useAccordionItem('Accordion.Trigger');
182
+ const {
183
+ trigger,
184
+ title
185
+ } = accordionVariants({
186
+ variant
187
+ });
188
+ return /*#__PURE__*/_jsx(Pressable, {
189
+ ref: ref,
190
+ accessibilityRole: "button",
191
+ accessibilityState: {
192
+ expanded: isExpanded,
193
+ disabled: isDisabled
194
+ },
195
+ disabled: isDisabled,
196
+ onPress: () => toggle(value),
197
+ className: trigger({
198
+ className
199
+ }),
200
+ ...props,
201
+ children: typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
202
+ className: title(),
203
+ children: children
204
+ }) : children
205
+ });
206
+ });
207
+ AccordionTrigger.displayName = 'Accordion.Trigger';
208
+ /** Chevron that rotates 180° while the item is open. */
209
+ const AccordionIndicator = /*#__PURE__*/forwardRef(({
210
+ className,
211
+ children,
212
+ ...props
213
+ }, ref) => {
214
+ const {
215
+ variant
216
+ } = useAccordion('Accordion.Indicator');
217
+ const {
218
+ isExpanded
219
+ } = useAccordionItem('Accordion.Indicator');
220
+ const {
221
+ indicator
222
+ } = accordionVariants({
223
+ variant
224
+ });
225
+ const rotation = useDerivedValue(() => withTiming(isExpanded ? 180 : 0, {
226
+ duration: 200
227
+ }), [isExpanded]);
228
+ const style = useAnimatedStyle(() => ({
229
+ transform: [{
230
+ rotate: `${rotation.value}deg`
231
+ }]
232
+ }));
233
+ return /*#__PURE__*/_jsx(Animated.View, {
234
+ style: style,
235
+ children: /*#__PURE__*/_jsx(View, {
236
+ ref: ref,
237
+ className: indicator({
238
+ className
239
+ }),
240
+ ...props,
241
+ children: children ?? /*#__PURE__*/_jsx(ChevronDownIcon, {
242
+ size: 18
243
+ })
244
+ })
245
+ });
246
+ });
247
+ AccordionIndicator.displayName = 'Accordion.Indicator';
248
+ /**
249
+ * The collapsible body. Unmounts when closed, per the repo's convention for
250
+ * conditionally shown content — the layout transition on the item animates
251
+ * the height change.
252
+ */
253
+ const AccordionContent = /*#__PURE__*/forwardRef(({
254
+ className,
255
+ children,
256
+ ...props
257
+ }, ref) => {
258
+ const {
259
+ variant
260
+ } = useAccordion('Accordion.Content');
261
+ const {
262
+ isExpanded
263
+ } = useAccordionItem('Accordion.Content');
264
+ const {
265
+ content,
266
+ contentText
267
+ } = accordionVariants({
268
+ variant
269
+ });
270
+ if (!isExpanded) return null;
271
+ return /*#__PURE__*/_jsx(View, {
272
+ ref: ref,
273
+ className: content({
274
+ className
275
+ }),
276
+ ...props,
277
+ children: typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
278
+ className: contentText(),
279
+ children: children
280
+ }) : children
281
+ });
282
+ });
283
+ AccordionContent.displayName = 'Accordion.Content';
284
+ const AccordionTitle = /*#__PURE__*/forwardRef(({
285
+ className,
286
+ ...props
287
+ }, ref) => {
288
+ const {
289
+ variant
290
+ } = useAccordion('Accordion.Title');
291
+ const {
292
+ title
293
+ } = accordionVariants({
294
+ variant
295
+ });
296
+ return /*#__PURE__*/_jsx(Text, {
297
+ ref: ref,
298
+ className: title({
299
+ className
300
+ }),
301
+ ...props
302
+ });
303
+ });
304
+ AccordionTitle.displayName = 'Accordion.Title';
305
+ export const Accordion = Object.assign(AccordionRoot, {
306
+ Item: AccordionItem,
307
+ Trigger: AccordionTrigger,
308
+ Title: AccordionTitle,
309
+ Indicator: AccordionIndicator,
310
+ Content: AccordionContent
311
+ });
312
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Children","createContext","forwardRef","isValidElement","useCallback","useContext","useMemo","useState","Pressable","View","Animated","LinearTransition","useAnimatedStyle","useDerivedValue","withTiming","tv","ChevronDownIcon","Text","jsx","_jsx","jsxs","_jsxs","accordionVariants","slots","root","separator","item","trigger","title","indicator","content","contentText","variants","variant","default","surface","separated","bordered","ghost","defaultVariants","AccordionContext","AccordionItemContext","useAccordion","component","context","Error","useAccordionItem","toArray","value","undefined","Array","isArray","AccordionRoot","className","selectionMode","defaultValue","onValueChange","hideSeparator","children","props","ref","internal","setInternal","isControlled","expanded","toggle","itemValue","isOpen","includes","next","filter","entry","items","Provider","layout","duration","map","child","index","length","key","displayName","AccordionItem","isDisabled","isExpanded","AccordionTrigger","accessibilityRole","accessibilityState","disabled","onPress","AccordionIndicator","rotation","style","transform","rotate","size","AccordionContent","AccordionTitle","Accordion","Object","assign","Item","Trigger","Title","Indicator","Content"],"sourceRoot":"../../../../src","sources":["components/accordion/index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SACEA,QAAQ,EACRC,aAAa,EACbC,UAAU,EACVC,cAAc,EACdC,WAAW,EACXC,UAAU,EACVC,OAAO,EACPC,QAAQ,QAEH,OAAO;AACd,SAASC,SAAS,EAAEC,IAAI,QAA6C,cAAc;AACnF,OAAOC,QAAQ,IACbC,gBAAgB,EAChBC,gBAAgB,EAChBC,eAAe,EACfC,UAAU,QACL,yBAAyB;AAChC,SAASC,EAAE,QAAQ,mBAAmB;AACtC,SAASC,eAAe,QAAQ,sBAAa;AAC7C,SAASC,IAAI,QAAwB,0BAAuB;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,IAAA,IAAAC,KAAA;AAW7D,MAAMC,iBAAiB,GAAGP,EAAE,CAAC;EAC3BQ,KAAK,EAAE;IACLC,IAAI,EAAE,iCAAiC;IACvCC,SAAS,EAAE,gBAAgB;IAC3BC,IAAI,EAAE,0BAA0B;IAChCC,OAAO,EAAE,kDAAkD;IAC3DC,KAAK,EAAE,8CAA8C;IACrDC,SAAS,EAAE,6BAA6B;IACxCC,OAAO,EAAE,MAAM;IACfC,WAAW,EAAE;EACf,CAAC;EACDC,QAAQ,EAAE;IACRC,OAAO,EAAE;MACPC,OAAO,EAAE;QAAEP,OAAO,EAAE,MAAM;QAAEG,OAAO,EAAE;MAAO,CAAC;MAC7CK,OAAO,EAAE;QACPX,IAAI,EAAE,6CAA6C;QACnDC,SAAS,EAAE,MAAM;QACjBE,OAAO,EAAE,MAAM;QACfG,OAAO,EAAE;MACX,CAAC;MACDM,SAAS,EAAE;QACTZ,IAAI,EAAE,0BAA0B;QAChCC,SAAS,EAAE,QAAQ;QACnBC,IAAI,EAAE,yCAAyC;QAC/CC,OAAO,EAAE,MAAM;QACfG,OAAO,EAAE;MACX,CAAC;MACDO,QAAQ,EAAE;QACRZ,SAAS,EAAE,QAAQ;QACnBC,IAAI,EAAE,sCAAsC;QAC5CC,OAAO,EAAE,MAAM;QACfG,OAAO,EAAE;MACX,CAAC;MACDQ,KAAK,EAAE;QACLb,SAAS,EAAE,QAAQ;QACnBE,OAAO,EAAE,MAAM;QACfG,OAAO,EAAE;MACX;IACF;EACF,CAAC;EACDS,eAAe,EAAE;IACfN,OAAO,EAAE;EACX;AACF,CAAC,CAAC;AAcF,MAAMO,gBAAgB,gBAAGvC,aAAa,CAA+B,IAAI,CAAC;AAC1E,MAAMwC,oBAAoB,gBAAGxC,aAAa,CAAmC,IAAI,CAAC;AAElF,SAASyC,YAAYA,CAACC,SAAiB,EAAyB;EAC9D,MAAMC,OAAO,GAAGvC,UAAU,CAACmC,gBAAgB,CAAC;EAC5C,IAAI,CAACI,OAAO,EAAE,MAAM,IAAIC,KAAK,CAAC,GAAGF,SAAS,qCAAqC,CAAC;EAChF,OAAOC,OAAO;AAChB;AAEA,SAASE,gBAAgBA,CAACH,SAAiB,EAA6B;EACtE,MAAMC,OAAO,GAAGvC,UAAU,CAACoC,oBAAoB,CAAC;EAChD,IAAI,CAACG,OAAO,EAAE,MAAM,IAAIC,KAAK,CAAC,GAAGF,SAAS,0CAA0C,CAAC;EACrF,OAAOC,OAAO;AAChB;AAgBA,MAAMG,OAAO,GAAIC,KAAoC,IACnDA,KAAK,KAAKC,SAAS,GAAG,EAAE,GAAGC,KAAK,CAACC,OAAO,CAACH,KAAK,CAAC,GAAGA,KAAK,GAAG,CAACA,KAAK,CAAC;AAEnE,MAAMI,aAAa,gBAAGlD,UAAU,CAC9B,CACE;EACEmD,SAAS;EACTpB,OAAO,GAAG,SAAS;EACnBqB,aAAa,GAAG,QAAQ;EACxBN,KAAK;EACLO,YAAY;EACZC,aAAa;EACbC,aAAa,GAAG,KAAK;EACrBC,QAAQ;EACR,GAAGC;AACL,CAAC,EACDC,GAAG,KACA;EACH,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAGvD,QAAQ,CAAW,MAAMwC,OAAO,CAACQ,YAAY,CAAC,CAAC;EAC/E,MAAMQ,YAAY,GAAGf,KAAK,KAAKC,SAAS;EACxC,MAAMe,QAAQ,GAAGD,YAAY,GAAGhB,OAAO,CAACC,KAAK,CAAC,GAAGa,QAAQ;EAEzD,MAAMI,MAAM,GAAG7D,WAAW,CACvB8D,SAAiB,IAAK;IACrB,MAAMC,MAAM,GAAGH,QAAQ,CAACI,QAAQ,CAACF,SAAS,CAAC;IAC3C,MAAMG,IAAI,GACRf,aAAa,KAAK,QAAQ,GACtBa,MAAM,GACJ,EAAE,GACF,CAACD,SAAS,CAAC,GACbC,MAAM,GACJH,QAAQ,CAACM,MAAM,CAAEC,KAAK,IAAKA,KAAK,KAAKL,SAAS,CAAC,GAC/C,CAAC,GAAGF,QAAQ,EAAEE,SAAS,CAAC;IAEhC,IAAI,CAACH,YAAY,EAAED,WAAW,CAACO,IAAI,CAAC;IACpC;IACAb,aAAa,GAAGF,aAAa,KAAK,QAAQ,GAAIe,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,GAAIA,IAAI,CAAC;EACtE,CAAC,EACD,CAACL,QAAQ,EAAEV,aAAa,EAAES,YAAY,EAAEP,aAAa,CACvD,CAAC;EAED,MAAMZ,OAAO,GAAGtC,OAAO,CACrB,OAAO;IAAE0D,QAAQ;IAAEC,MAAM;IAAEhC;EAAQ,CAAC,CAAC,EACrC,CAAC+B,QAAQ,EAAEC,MAAM,EAAEhC,OAAO,CAC5B,CAAC;EAED,MAAM;IAAET,IAAI;IAAEC;EAAU,CAAC,GAAGH,iBAAiB,CAAC;IAAEW;EAAQ,CAAC,CAAC;EAC1D,MAAMuC,KAAK,GAAGxE,QAAQ,CAAC+C,OAAO,CAACW,QAAQ,CAAC,CAACY,MAAM,CAACnE,cAAc,CAAC;EAE/D,oBACEgB,IAAA,CAACqB,gBAAgB,CAACiC,QAAQ;IAACzB,KAAK,EAAEJ,OAAQ;IAAAc,QAAA,eACxCvC,IAAA,CAACT,QAAQ,CAACD,IAAI;MACZmD,GAAG,EAAEA,GAAI;MACTc,MAAM,EAAE/D,gBAAgB,CAACgE,QAAQ,CAAC,GAAG,CAAE;MACvCtB,SAAS,EAAE7B,IAAI,CAAC;QAAE6B;MAAU,CAAC,CAAE;MAAA,GAC3BM,KAAK;MAAAD,QAAA,EAERc,KAAK,CAACI,GAAG,CAAC,CAACC,KAAK,EAAEC,KAAK,kBACtBzD,KAAA,CAACZ,IAAI;QAAAiD,QAAA,GACFmB,KAAK,EACL,CAACpB,aAAa,IAAIqB,KAAK,GAAGN,KAAK,CAACO,MAAM,GAAG,CAAC,gBACzC5D,IAAA,CAACV,IAAI;UAAC4C,SAAS,EAAE5B,SAAS,CAAC;QAAE,CAAE,CAAC,GAC9B,IAAI;MAAA,GAJCoD,KAAK,CAACG,GAAG,IAAIF,KAKlB,CACP;IAAC,CACW;EAAC,CACS,CAAC;AAEhC,CACF,CAAC;AACD1B,aAAa,CAAC6B,WAAW,GAAG,WAAW;AAUvC,MAAMC,aAAa,gBAAGhF,UAAU,CAC9B,CAAC;EAAEmD,SAAS;EAAEL,KAAK;EAAEmC,UAAU,GAAG,KAAK;EAAEzB,QAAQ;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EACrE,MAAM;IAAEI,QAAQ;IAAE/B;EAAQ,CAAC,GAAGS,YAAY,CAAC,gBAAgB,CAAC;EAC5D,MAAM0C,UAAU,GAAGpB,QAAQ,CAACI,QAAQ,CAACpB,KAAK,CAAC;EAC3C,MAAM;IAAEtB;EAAK,CAAC,GAAGJ,iBAAiB,CAAC;IAAEW;EAAQ,CAAC,CAAC;EAE/C,MAAMW,OAAO,GAAGtC,OAAO,CACrB,OAAO;IAAE0C,KAAK;IAAEoC,UAAU;IAAED;EAAW,CAAC,CAAC,EACzC,CAACnC,KAAK,EAAEoC,UAAU,EAAED,UAAU,CAChC,CAAC;EAED,oBACEhE,IAAA,CAACsB,oBAAoB,CAACgC,QAAQ;IAACzB,KAAK,EAAEJ,OAAQ;IAAAc,QAAA,eAC5CvC,IAAA,CAACT,QAAQ,CAACD,IAAI;MACZmD,GAAG,EAAEA,GAAI;MACTc,MAAM,EAAE/D,gBAAgB,CAACgE,QAAQ,CAAC,GAAG,CAAE;MACvCtB,SAAS,EAAE3B,IAAI,CAAC;QAAE2B;MAAU,CAAC,CAAE;MAAA,GAC3BM,KAAK;MAAAD,QAAA,EAERA;IAAQ,CACI;EAAC,CACa,CAAC;AAEpC,CACF,CAAC;AACDwB,aAAa,CAACD,WAAW,GAAG,gBAAgB;AAO5C;AACA,MAAMI,gBAAgB,gBAAGnF,UAAU,CACjC,CAAC;EAAEmD,SAAS;EAAEK,QAAQ;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EAC1C,MAAM;IAAEK,MAAM;IAAEhC;EAAQ,CAAC,GAAGS,YAAY,CAAC,mBAAmB,CAAC;EAC7D,MAAM;IAAEM,KAAK;IAAEoC,UAAU;IAAED;EAAW,CAAC,GAAGrC,gBAAgB,CAAC,mBAAmB,CAAC;EAC/E,MAAM;IAAEnB,OAAO;IAAEC;EAAM,CAAC,GAAGN,iBAAiB,CAAC;IAAEW;EAAQ,CAAC,CAAC;EAEzD,oBACEd,IAAA,CAACX,SAAS;IACRoD,GAAG,EAAEA,GAAI;IACT0B,iBAAiB,EAAC,QAAQ;IAC1BC,kBAAkB,EAAE;MAAEvB,QAAQ,EAAEoB,UAAU;MAAEI,QAAQ,EAAEL;IAAW,CAAE;IACnEK,QAAQ,EAAEL,UAAW;IACrBM,OAAO,EAAEA,CAAA,KAAMxB,MAAM,CAACjB,KAAK,CAAE;IAC7BK,SAAS,EAAE1B,OAAO,CAAC;MAAE0B;IAAU,CAAC,CAAE;IAAA,GAC9BM,KAAK;IAAAD,QAAA,EAER,OAAOA,QAAQ,KAAK,QAAQ,gBAC3BvC,IAAA,CAACF,IAAI;MAACoC,SAAS,EAAEzB,KAAK,CAAC,CAAE;MAAA8B,QAAA,EAAEA;IAAQ,CAAO,CAAC,GAE3CA;EACD,CACQ,CAAC;AAEhB,CACF,CAAC;AACD2B,gBAAgB,CAACJ,WAAW,GAAG,mBAAmB;AAQlD;AACA,MAAMS,kBAAkB,gBAAGxF,UAAU,CACnC,CAAC;EAAEmD,SAAS;EAAEK,QAAQ;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EAC1C,MAAM;IAAE3B;EAAQ,CAAC,GAAGS,YAAY,CAAC,qBAAqB,CAAC;EACvD,MAAM;IAAE0C;EAAW,CAAC,GAAGtC,gBAAgB,CAAC,qBAAqB,CAAC;EAC9D,MAAM;IAAEjB;EAAU,CAAC,GAAGP,iBAAiB,CAAC;IAAEW;EAAQ,CAAC,CAAC;EAEpD,MAAM0D,QAAQ,GAAG9E,eAAe,CAC9B,MAAMC,UAAU,CAACsE,UAAU,GAAG,GAAG,GAAG,CAAC,EAAE;IAAET,QAAQ,EAAE;EAAI,CAAC,CAAC,EACzD,CAACS,UAAU,CACb,CAAC;EACD,MAAMQ,KAAK,GAAGhF,gBAAgB,CAAC,OAAO;IACpCiF,SAAS,EAAE,CAAC;MAAEC,MAAM,EAAE,GAAGH,QAAQ,CAAC3C,KAAK;IAAM,CAAC;EAChD,CAAC,CAAC,CAAC;EAEH,oBACE7B,IAAA,CAACT,QAAQ,CAACD,IAAI;IAACmF,KAAK,EAAEA,KAAM;IAAAlC,QAAA,eAC1BvC,IAAA,CAACV,IAAI;MAACmD,GAAG,EAAEA,GAAI;MAACP,SAAS,EAAExB,SAAS,CAAC;QAAEwB;MAAU,CAAC,CAAE;MAAA,GAAKM,KAAK;MAAAD,QAAA,EAC3DA,QAAQ,iBAAIvC,IAAA,CAACH,eAAe;QAAC+E,IAAI,EAAE;MAAG,CAAE;IAAC,CACtC;EAAC,CACM,CAAC;AAEpB,CACF,CAAC;AACDL,kBAAkB,CAACT,WAAW,GAAG,qBAAqB;AAOtD;AACA;AACA;AACA;AACA;AACA,MAAMe,gBAAgB,gBAAG9F,UAAU,CACjC,CAAC;EAAEmD,SAAS;EAAEK,QAAQ;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EAC1C,MAAM;IAAE3B;EAAQ,CAAC,GAAGS,YAAY,CAAC,mBAAmB,CAAC;EACrD,MAAM;IAAE0C;EAAW,CAAC,GAAGtC,gBAAgB,CAAC,mBAAmB,CAAC;EAC5D,MAAM;IAAEhB,OAAO;IAAEC;EAAY,CAAC,GAAGT,iBAAiB,CAAC;IAAEW;EAAQ,CAAC,CAAC;EAE/D,IAAI,CAACmD,UAAU,EAAE,OAAO,IAAI;EAE5B,oBACEjE,IAAA,CAACV,IAAI;IAACmD,GAAG,EAAEA,GAAI;IAACP,SAAS,EAAEvB,OAAO,CAAC;MAAEuB;IAAU,CAAC,CAAE;IAAA,GAAKM,KAAK;IAAAD,QAAA,EACzD,OAAOA,QAAQ,KAAK,QAAQ,gBAC3BvC,IAAA,CAACF,IAAI;MAACoC,SAAS,EAAEtB,WAAW,CAAC,CAAE;MAAA2B,QAAA,EAAEA;IAAQ,CAAO,CAAC,GAEjDA;EACD,CACG,CAAC;AAEX,CACF,CAAC;AACDsC,gBAAgB,CAACf,WAAW,GAAG,mBAAmB;AAElD,MAAMgB,cAAc,gBAAG/F,UAAU,CAAoB,CAAC;EAAEmD,SAAS;EAAE,GAAGM;AAAM,CAAC,EAAEC,GAAG,KAAK;EACrF,MAAM;IAAE3B;EAAQ,CAAC,GAAGS,YAAY,CAAC,iBAAiB,CAAC;EACnD,MAAM;IAAEd;EAAM,CAAC,GAAGN,iBAAiB,CAAC;IAAEW;EAAQ,CAAC,CAAC;EAChD,oBAAOd,IAAA,CAACF,IAAI;IAAC2C,GAAG,EAAEA,GAAI;IAACP,SAAS,EAAEzB,KAAK,CAAC;MAAEyB;IAAU,CAAC,CAAE;IAAA,GAAKM;EAAK,CAAG,CAAC;AACvE,CAAC,CAAC;AACFsC,cAAc,CAAChB,WAAW,GAAG,iBAAiB;AAE9C,OAAO,MAAMiB,SAAS,GAAGC,MAAM,CAACC,MAAM,CAAChD,aAAa,EAAE;EACpDiD,IAAI,EAAEnB,aAAa;EACnBoB,OAAO,EAAEjB,gBAAgB;EACzBkB,KAAK,EAAEN,cAAc;EACrBO,SAAS,EAAEd,kBAAkB;EAC7Be,OAAO,EAAET;AACX,CAAC,CAAC","ignoreList":[]}
@@ -4,7 +4,8 @@ import { forwardRef, useState } from 'react';
4
4
  import { Image, View } from 'react-native';
5
5
  import { tv } from 'tailwind-variants';
6
6
  import { Text } from "../../primitives/text.js";
7
- import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { cn } from "../../utils/cn.js";
8
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
9
  const avatarVariants = tv({
9
10
  slots: {
10
11
  root: 'items-center justify-center overflow-hidden rounded-full border border-border bg-muted',
@@ -35,12 +36,13 @@ const avatarVariants = tv({
35
36
  size: 'md'
36
37
  }
37
38
  });
38
- export const Avatar = /*#__PURE__*/forwardRef(({
39
+ const AvatarRoot = /*#__PURE__*/forwardRef(({
39
40
  className,
40
41
  size,
41
42
  source,
42
43
  fallback,
43
44
  imageProps,
45
+ children,
44
46
  ...props
45
47
  }, ref) => {
46
48
  const [errored, setErrored] = useState(false);
@@ -52,23 +54,62 @@ export const Avatar = /*#__PURE__*/forwardRef(({
52
54
  size
53
55
  });
54
56
  const showImage = !!source && !errored;
55
- return /*#__PURE__*/_jsx(View, {
57
+ const face = showImage ? /*#__PURE__*/_jsx(Image, {
58
+ source: source,
59
+ onError: () => setErrored(true),
60
+ className: image(),
61
+ ...imageProps
62
+ }) : /*#__PURE__*/_jsx(Text, {
63
+ className: fallbackSlot(),
64
+ children: fallback ?? '?'
65
+ });
66
+
67
+ // The plain avatar is a single clipped node.
68
+ if (!children) {
69
+ return /*#__PURE__*/_jsx(View, {
70
+ ref: ref,
71
+ accessibilityRole: "image",
72
+ className: root({
73
+ className
74
+ }),
75
+ ...props,
76
+ children: face
77
+ });
78
+ }
79
+
80
+ // With an overlay it needs two: the face keeps overflow-hidden to round
81
+ // the image, which would otherwise cut a corner badge in half, so the
82
+ // overlay hangs off an unclipped wrapper around it.
83
+ return /*#__PURE__*/_jsxs(View, {
56
84
  ref: ref,
57
- accessibilityRole: "image",
58
- className: root({
59
- className
60
- }),
85
+ className: cn('self-start', className),
61
86
  ...props,
62
- children: showImage ? /*#__PURE__*/_jsx(Image, {
63
- source: source,
64
- onError: () => setErrored(true),
65
- className: image(),
66
- ...imageProps
67
- }) : /*#__PURE__*/_jsx(Text, {
68
- className: fallbackSlot(),
69
- children: fallback ?? '?'
70
- })
87
+ children: [/*#__PURE__*/_jsx(View, {
88
+ accessibilityRole: "image",
89
+ className: root(),
90
+ children: face
91
+ }), children]
71
92
  });
72
93
  });
73
- Avatar.displayName = 'Avatar';
94
+ AvatarRoot.displayName = 'Avatar';
95
+ /**
96
+ * Overlay pinned to the avatar's top-right — an unread count, a presence dot.
97
+ *
98
+ * The ring is `border-background` so the badge separates from the image
99
+ * whatever surface the avatar sits on.
100
+ */
101
+ const AvatarBadge = /*#__PURE__*/forwardRef(({
102
+ className,
103
+ children,
104
+ ...props
105
+ }, ref) => /*#__PURE__*/_jsx(View, {
106
+ ref: ref,
107
+ className: cn('absolute -right-1 -top-1 rounded-full border-2 border-background', className),
108
+ ...props,
109
+ children: children
110
+ }));
111
+ AvatarBadge.displayName = 'Avatar.Badge';
112
+ export const Avatar = Object.assign(AvatarRoot, {
113
+ Badge: AvatarBadge
114
+ });
74
115
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","useState","Image","View","tv","Text","jsx","_jsx","avatarVariants","slots","root","image","fallback","variants","size","sm","md","lg","xl","defaultVariants","Avatar","className","source","imageProps","props","ref","errored","setErrored","fallbackSlot","showImage","accessibilityRole","children","onError","displayName"],"sourceRoot":"../../../../src","sources":["components/avatar/index.tsx"],"mappings":";;AAAA,SAASA,UAAU,EAAEC,QAAQ,QAAQ,OAAO;AAC5C,SACEC,KAAK,EACLC,IAAI,QAIC,cAAc;AACrB,SAASC,EAAE,QAA2B,mBAAmB;AACzD,SAASC,IAAI,QAAQ,0BAAuB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAE7C,MAAMC,cAAc,GAAGJ,EAAE,CAAC;EACxBK,KAAK,EAAE;IACLC,IAAI,EAAE,wFAAwF;IAC9FC,KAAK,EAAE,gCAAgC;IACvCC,QAAQ,EAAE;EACZ,CAAC;EACDC,QAAQ,EAAE;IACRC,IAAI,EAAE;MACJC,EAAE,EAAE;QAAEL,IAAI,EAAE,SAAS;QAAEE,QAAQ,EAAE;MAAU,CAAC;MAC5CI,EAAE,EAAE;QAAEN,IAAI,EAAE,WAAW;QAAEE,QAAQ,EAAE;MAAU,CAAC;MAC9CK,EAAE,EAAE;QAAEP,IAAI,EAAE,WAAW;QAAEE,QAAQ,EAAE;MAAU,CAAC;MAC9CM,EAAE,EAAE;QAAER,IAAI,EAAE,WAAW;QAAEE,QAAQ,EAAE;MAAW;IAChD;EACF,CAAC;EACDO,eAAe,EAAE;IACfL,IAAI,EAAE;EACR;AACF,CAAC,CAAC;AAWF,OAAO,MAAMM,MAAM,gBAAGpB,UAAU,CAC9B,CAAC;EAAEqB,SAAS;EAAEP,IAAI;EAAEQ,MAAM;EAAEV,QAAQ;EAAEW,UAAU;EAAE,GAAGC;AAAM,CAAC,EAAEC,GAAG,KAAK;EACpE,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAG1B,QAAQ,CAAC,KAAK,CAAC;EAC7C,MAAM;IAAES,IAAI;IAAEC,KAAK;IAAEC,QAAQ,EAAEgB;EAAa,CAAC,GAAGpB,cAAc,CAAC;IAAEM;EAAK,CAAC,CAAC;EACxE,MAAMe,SAAS,GAAG,CAAC,CAACP,MAAM,IAAI,CAACI,OAAO;EAEtC,oBACEnB,IAAA,CAACJ,IAAI;IACHsB,GAAG,EAAEA,GAAI;IACTK,iBAAiB,EAAC,OAAO;IACzBT,SAAS,EAAEX,IAAI,CAAC;MAAEW;IAAU,CAAC,CAAE;IAAA,GAC3BG,KAAK;IAAAO,QAAA,EAERF,SAAS,gBACRtB,IAAA,CAACL,KAAK;MACJoB,MAAM,EAAEA,MAAO;MACfU,OAAO,EAAEA,CAAA,KAAML,UAAU,CAAC,IAAI,CAAE;MAChCN,SAAS,EAAEV,KAAK,CAAC,CAAE;MAAA,GACfY;IAAU,CACf,CAAC,gBAEFhB,IAAA,CAACF,IAAI;MAACgB,SAAS,EAAEO,YAAY,CAAC,CAAE;MAAAG,QAAA,EAAEnB,QAAQ,IAAI;IAAG,CAAO;EACzD,CACG,CAAC;AAEX,CACF,CAAC;AAEDQ,MAAM,CAACa,WAAW,GAAG,QAAQ","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","useState","Image","View","tv","Text","cn","jsx","_jsx","jsxs","_jsxs","avatarVariants","slots","root","image","fallback","variants","size","sm","md","lg","xl","defaultVariants","AvatarRoot","className","source","imageProps","children","props","ref","errored","setErrored","fallbackSlot","showImage","face","onError","accessibilityRole","displayName","AvatarBadge","Avatar","Object","assign","Badge"],"sourceRoot":"../../../../src","sources":["components/avatar/index.tsx"],"mappings":"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","ignoreList":[]}
@@ -11,6 +11,17 @@ const badgeVariants = tv({
11
11
  label: 'text-xs font-medium'
12
12
  },
13
13
  variants: {
14
+ shape: {
15
+ default: {},
16
+ /** A bare status dot, no label. */
17
+ dot: {
18
+ root: 'h-2 w-2 rounded-full px-0 py-0'
19
+ },
20
+ /** Circular, for a count sitting over an avatar or an icon. */
21
+ count: {
22
+ root: 'h-5 min-w-5 rounded-full px-1.5 py-0'
23
+ }
24
+ },
14
25
  variant: {
15
26
  default: {
16
27
  root: 'bg-primary',
@@ -43,34 +54,44 @@ const badgeVariants = tv({
43
54
  }
44
55
  },
45
56
  defaultVariants: {
46
- variant: 'default'
57
+ variant: 'default',
58
+ shape: 'default'
47
59
  }
48
60
  });
61
+
62
+ /** Counts past this render as "99+" so the badge keeps its shape. */
63
+ const MAX_COUNT = 99;
49
64
  export const Badge = /*#__PURE__*/forwardRef(({
50
65
  children,
51
66
  className,
52
67
  labelClassName,
53
68
  variant,
69
+ shape,
70
+ count,
54
71
  ...props
55
72
  }, ref) => {
73
+ const resolvedShape = shape ?? (count !== undefined ? 'count' : 'default');
56
74
  const {
57
75
  root,
58
76
  label
59
77
  } = badgeVariants({
60
- variant
78
+ variant,
79
+ shape: resolvedShape
61
80
  });
81
+ const content = count !== undefined ? `${Math.min(count, MAX_COUNT)}${count > MAX_COUNT ? '+' : ''}` : children;
62
82
  return /*#__PURE__*/_jsx(View, {
63
83
  ref: ref,
84
+ accessibilityLabel: count !== undefined ? `${count} unread` : undefined,
64
85
  className: root({
65
86
  className
66
87
  }),
67
88
  ...props,
68
- children: typeof children === 'string' ? /*#__PURE__*/_jsx(Text, {
89
+ children: resolvedShape === 'dot' ? null : typeof content === 'string' ? /*#__PURE__*/_jsx(Text, {
69
90
  className: label({
70
91
  className: labelClassName
71
92
  }),
72
- children: children
73
- }) : children
93
+ children: content
94
+ }) : content
74
95
  });
75
96
  });
76
97
  Badge.displayName = 'Badge';
@@ -1 +1 @@
1
- {"version":3,"names":["forwardRef","View","tv","Text","jsx","_jsx","badgeVariants","slots","root","label","variants","variant","default","secondary","outline","destructive","success","warning","info","defaultVariants","Badge","children","className","labelClassName","props","ref","displayName"],"sourceRoot":"../../../../src","sources":["components/badge/index.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAAwB,OAAO;AAClD,SAASC,IAAI,QAAwB,cAAc;AACnD,SAASC,EAAE,QAA2B,mBAAmB;AACzD,SAASC,IAAI,QAAQ,0BAAuB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAE7C,MAAMC,aAAa,GAAGJ,EAAE,CAAC;EACvBK,KAAK,EAAE;IACLC,IAAI,EAAE,wGAAwG;IAC9GC,KAAK,EAAE;EACT,CAAC;EACDC,QAAQ,EAAE;IACRC,OAAO,EAAE;MACPC,OAAO,EAAE;QAAEJ,IAAI,EAAE,YAAY;QAAEC,KAAK,EAAE;MAA0B,CAAC;MACjEI,SAAS,EAAE;QAAEL,IAAI,EAAE,cAAc;QAAEC,KAAK,EAAE;MAA4B,CAAC;MACvEK,OAAO,EAAE;QAAEN,IAAI,EAAE,8BAA8B;QAAEC,KAAK,EAAE;MAAkB,CAAC;MAC3EM,WAAW,EAAE;QAAEP,IAAI,EAAE,gBAAgB;QAAEC,KAAK,EAAE;MAAa,CAAC;MAC5DO,OAAO,EAAE;QAAER,IAAI,EAAE,mBAAmB;QAAEC,KAAK,EAAE;MAA0B,CAAC;MACxEQ,OAAO,EAAE;QAAET,IAAI,EAAE,mBAAmB;QAAEC,KAAK,EAAE;MAA0B,CAAC;MACxES,IAAI,EAAE;QAAEV,IAAI,EAAE,gBAAgB;QAAEC,KAAK,EAAE;MAAuB;IAChE;EACF,CAAC;EACDU,eAAe,EAAE;IACfR,OAAO,EAAE;EACX;AACF,CAAC,CAAC;AAUF,OAAO,MAAMS,KAAK,gBAAGpB,UAAU,CAC7B,CAAC;EAAEqB,QAAQ;EAAEC,SAAS;EAAEC,cAAc;EAAEZ,OAAO;EAAE,GAAGa;AAAM,CAAC,EAAEC,GAAG,KAAK;EACnE,MAAM;IAAEjB,IAAI;IAAEC;EAAM,CAAC,GAAGH,aAAa,CAAC;IAAEK;EAAQ,CAAC,CAAC;EAElD,oBACEN,IAAA,CAACJ,IAAI;IAACwB,GAAG,EAAEA,GAAI;IAACH,SAAS,EAAEd,IAAI,CAAC;MAAEc;IAAU,CAAC,CAAE;IAAA,GAAKE,KAAK;IAAAH,QAAA,EACtD,OAAOA,QAAQ,KAAK,QAAQ,gBAC3BhB,IAAA,CAACF,IAAI;MAACmB,SAAS,EAAEb,KAAK,CAAC;QAAEa,SAAS,EAAEC;MAAe,CAAC,CAAE;MAAAF,QAAA,EAAEA;IAAQ,CAAO,CAAC,GAExEA;EACD,CACG,CAAC;AAEX,CACF,CAAC;AAEDD,KAAK,CAACM,WAAW,GAAG,OAAO","ignoreList":[]}
1
+ {"version":3,"names":["forwardRef","View","tv","Text","jsx","_jsx","badgeVariants","slots","root","label","variants","shape","default","dot","count","variant","secondary","outline","destructive","success","warning","info","defaultVariants","MAX_COUNT","Badge","children","className","labelClassName","props","ref","resolvedShape","undefined","content","Math","min","accessibilityLabel","displayName"],"sourceRoot":"../../../../src","sources":["components/badge/index.tsx"],"mappings":";;AAAA,SAASA,UAAU,QAAwB,OAAO;AAClD,SAASC,IAAI,QAAwB,cAAc;AACnD,SAASC,EAAE,QAA2B,mBAAmB;AACzD,SAASC,IAAI,QAAQ,0BAAuB;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAE7C,MAAMC,aAAa,GAAGJ,EAAE,CAAC;EACvBK,KAAK,EAAE;IACLC,IAAI,EAAE,wGAAwG;IAC9GC,KAAK,EAAE;EACT,CAAC;EACDC,QAAQ,EAAE;IACRC,KAAK,EAAE;MACLC,OAAO,EAAE,CAAC,CAAC;MACX;MACAC,GAAG,EAAE;QAAEL,IAAI,EAAE;MAAiC,CAAC;MAC/C;MACAM,KAAK,EAAE;QAAEN,IAAI,EAAE;MAAuC;IACxD,CAAC;IACDO,OAAO,EAAE;MACPH,OAAO,EAAE;QAAEJ,IAAI,EAAE,YAAY;QAAEC,KAAK,EAAE;MAA0B,CAAC;MACjEO,SAAS,EAAE;QAAER,IAAI,EAAE,cAAc;QAAEC,KAAK,EAAE;MAA4B,CAAC;MACvEQ,OAAO,EAAE;QAAET,IAAI,EAAE,8BAA8B;QAAEC,KAAK,EAAE;MAAkB,CAAC;MAC3ES,WAAW,EAAE;QAAEV,IAAI,EAAE,gBAAgB;QAAEC,KAAK,EAAE;MAAa,CAAC;MAC5DU,OAAO,EAAE;QAAEX,IAAI,EAAE,mBAAmB;QAAEC,KAAK,EAAE;MAA0B,CAAC;MACxEW,OAAO,EAAE;QAAEZ,IAAI,EAAE,mBAAmB;QAAEC,KAAK,EAAE;MAA0B,CAAC;MACxEY,IAAI,EAAE;QAAEb,IAAI,EAAE,gBAAgB;QAAEC,KAAK,EAAE;MAAuB;IAChE;EACF,CAAC;EACDa,eAAe,EAAE;IACfP,OAAO,EAAE,SAAS;IAClBJ,KAAK,EAAE;EACT;AACF,CAAC,CAAC;;AAEF;AACA,MAAMY,SAAS,GAAG,EAAE;AAepB,OAAO,MAAMC,KAAK,gBAAGxB,UAAU,CAC7B,CAAC;EAAEyB,QAAQ;EAAEC,SAAS;EAAEC,cAAc;EAAEZ,OAAO;EAAEJ,KAAK;EAAEG,KAAK;EAAE,GAAGc;AAAM,CAAC,EAAEC,GAAG,KAAK;EACjF,MAAMC,aAAa,GAAGnB,KAAK,KAAKG,KAAK,KAAKiB,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;EAC1E,MAAM;IAAEvB,IAAI;IAAEC;EAAM,CAAC,GAAGH,aAAa,CAAC;IAAES,OAAO;IAAEJ,KAAK,EAAEmB;EAAc,CAAC,CAAC;EAExE,MAAME,OAAO,GACXlB,KAAK,KAAKiB,SAAS,GACf,GAAGE,IAAI,CAACC,GAAG,CAACpB,KAAK,EAAES,SAAS,CAAC,GAAGT,KAAK,GAAGS,SAAS,GAAG,GAAG,GAAG,EAAE,EAAE,GAC9DE,QAAQ;EAEd,oBACEpB,IAAA,CAACJ,IAAI;IACH4B,GAAG,EAAEA,GAAI;IACTM,kBAAkB,EAChBrB,KAAK,KAAKiB,SAAS,GAAG,GAAGjB,KAAK,SAAS,GAAGiB,SAC3C;IACDL,SAAS,EAAElB,IAAI,CAAC;MAAEkB;IAAU,CAAC,CAAE;IAAA,GAC3BE,KAAK;IAAAH,QAAA,EAERK,aAAa,KAAK,KAAK,GAAG,IAAI,GAAG,OAAOE,OAAO,KAAK,QAAQ,gBAC3D3B,IAAA,CAACF,IAAI;MAACuB,SAAS,EAAEjB,KAAK,CAAC;QAAEiB,SAAS,EAAEC;MAAe,CAAC,CAAE;MAAAF,QAAA,EAAEO;IAAO,CAAO,CAAC,GAEvEA;EACD,CACG,CAAC;AAEX,CACF,CAAC;AAEDR,KAAK,CAACY,WAAW,GAAG,OAAO","ignoreList":[]}