@impulse-ui-native/primitives 16.0.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -146,6 +146,8 @@ appearance, but does not inject label content.
146
146
 
147
147
  Use `Badge` for compact states and metadata. It supports `filled`, `outlined`, and `soft` display variants and semantic tones. Its addons follow Input: use `PrefixIcon` or `Prefix`, `SuffixIcon` or `Suffix`, and optionally `onPressPrefix` or `onPressSuffix`. A custom component takes precedence over its corresponding icon. Use `Tag` when the whole label needs built-in press or close behavior.
148
148
 
149
+ Badge text and Tag labels stay on one line and truncate with a trailing ellipsis when constrained by available width. Their containers shrink within rows while icons and close actions retain their space. Use `style.width` or `style.maxWidth` for a specific limit; custom Badge children own their text overflow behavior.
150
+
149
151
  Badges follow their parent's `alignItems` for cross-axis alignment. For example,
150
152
  use `alignItems="center"` on a column to center badges horizontally. Use
151
153
  `alignSelf` on a badge when it needs a different alignment from its siblings.
@@ -1,19 +1,14 @@
1
1
  import * as react from 'react';
2
- import { ComponentType } from 'react';
3
- import { IconProps } from '@impulse-ui-native/icon/types';
4
- import { PressableCoreProps } from '../../../types/button.types.mjs';
2
+ import { BadgeAddonProps } from '../../../types/badge-addon.types.mjs';
3
+ import '../../../types/badge.types.mjs';
5
4
  import 'react-native';
6
5
  import '@impulse-ui-native/theme';
6
+ import '../../../types/control-components.types.mjs';
7
+ import '@impulse-ui-native/icon/types';
8
+ import '../../../types/button.types.mjs';
7
9
  import '../../../types/view.types.mjs';
10
+ import '../../../types/spinner.types.mjs';
8
11
 
9
- interface BadgeAddonProps {
10
- color: string | undefined;
11
- Content: ComponentType | undefined;
12
- hitSlop: number;
13
- iconSize: number;
14
- IconComponent: IconProps["icon"] | undefined;
15
- onPress: PressableCoreProps["onPress"] | undefined;
16
- }
17
12
  declare const BadgeAddon: react.MemoExoticComponent<({ color, Content, hitSlop, iconSize, IconComponent, onPress, }: BadgeAddonProps) => react.JSX.Element | null>;
18
13
 
19
14
  export { BadgeAddon };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/atoms/badge/addon.tsx"],"sourcesContent":["import type { ComponentType } from \"react\";\nimport { memo, useMemo } from \"react\";\n\nimport type { IconProps } from \"@impulse-ui-native/icon/types\";\nimport { Icon } from \"@impulse-ui-native/icon\";\n\nimport type { PressableCoreProps } from \"../../../types\";\nimport { Pressable } from \"../pressable\";\nimport { View } from \"../view\";\n\ninterface BadgeAddonProps {\n color: string | undefined;\n Content: ComponentType | undefined;\n hitSlop: number;\n iconSize: number;\n IconComponent: IconProps[\"icon\"] | undefined;\n onPress: PressableCoreProps[\"onPress\"] | undefined;\n}\n\nexport const BadgeAddon = memo(function BadgeAddon({\n color,\n Content,\n hitSlop,\n iconSize,\n IconComponent,\n onPress,\n}: BadgeAddonProps) {\n const Container = onPress ? Pressable : View;\n const content = useMemo(() => {\n if (Content) {\n return <Content />;\n }\n\n if (IconComponent) {\n return <Icon color={color} icon={IconComponent} size={iconSize} />;\n }\n\n return null;\n }, [color, Content, iconSize, IconComponent]);\n\n if (!content) {\n return null;\n }\n\n return (\n <Container hitSlop={hitSlop} onPress={onPress}>\n {content}\n </Container>\n );\n});\n"],"mappings":"AA8Ba;AA7Bb,SAAS,MAAM,eAAe;AAG9B,SAAS,YAAY;AAGrB,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AAWd,MAAM,aAAa,KAAK,SAASA,YAAW;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,YAAY,UAAU,YAAY;AACxC,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,SAAS;AACX,aAAO,oBAAC,WAAQ;AAAA,IAClB;AAEA,QAAI,eAAe;AACjB,aAAO,oBAAC,QAAK,OAAc,MAAM,eAAe,MAAM,UAAU;AAAA,IAClE;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,SAAS,UAAU,aAAa,CAAC;AAE5C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SACE,oBAAC,aAAU,SAAkB,SAC1B,mBACH;AAEJ,CAAC;","names":["BadgeAddon"]}
1
+ {"version":3,"sources":["../../../../src/components/atoms/badge/addon.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\r\n\r\nimport { Icon } from \"@impulse-ui-native/icon\";\r\n\r\nimport type { BadgeAddonProps } from \"../../../types/badge-addon.types\";\r\nimport { Pressable } from \"../pressable\";\r\nimport { View } from \"../view\";\r\n\r\nexport const BadgeAddon = memo(function BadgeAddon({\r\n color,\r\n Content,\r\n hitSlop,\r\n iconSize,\r\n IconComponent,\r\n onPress,\r\n}: BadgeAddonProps) {\r\n const Container = onPress ? Pressable : View;\r\n const content = useMemo(() => {\r\n if (Content) {\r\n return <Content />;\r\n }\r\n\r\n if (IconComponent) {\r\n return <Icon color={color} icon={IconComponent} size={iconSize} />;\r\n }\r\n\r\n return null;\r\n }, [color, Content, iconSize, IconComponent]);\r\n\r\n if (!content) {\r\n return null;\r\n }\r\n\r\n return (\r\n <Container hitSlop={hitSlop} onPress={onPress}>\r\n {content}\r\n </Container>\r\n );\r\n});\r\n"],"mappings":"AAmBa;AAnBb,SAAS,MAAM,eAAe;AAE9B,SAAS,YAAY;AAGrB,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AAEd,MAAM,aAAa,KAAK,SAASA,YAAW;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAoB;AAClB,QAAM,YAAY,UAAU,YAAY;AACxC,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,SAAS;AACX,aAAO,oBAAC,WAAQ;AAAA,IAClB;AAEA,QAAI,eAAe;AACjB,aAAO,oBAAC,QAAK,OAAc,MAAM,eAAe,MAAM,UAAU;AAAA,IAClE;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,SAAS,UAAU,aAAa,CAAC;AAE5C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAEA,SACE,oBAAC,aAAU,SAAkB,SAC1B,mBACH;AAEJ,CAAC;","names":["BadgeAddon"]}
@@ -51,7 +51,7 @@ const BadgeRoot = memo(function BadgeRoot2({
51
51
  onPress: onPressPrefix
52
52
  }
53
53
  ),
54
- isTextChild ? /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: styles.label, children }) : children,
54
+ isTextChild ? /* @__PURE__ */ jsx(Text, { numberOfLines: 1, ellipsizeMode: "tail", style: styles.label, children }) : children,
55
55
  /* @__PURE__ */ jsx(
56
56
  BadgeAddon,
57
57
  {
@@ -74,7 +74,8 @@ function themedStyles(theme, props) {
74
74
  container: {
75
75
  alignItems: "center",
76
76
  flexDirection: "row",
77
- flexShrink: 0,
77
+ flexShrink: 1,
78
+ maxWidth: "100%",
78
79
  justifyContent: "center",
79
80
  borderRadius: badgeTokens.borderRadius,
80
81
  borderWidth: badgeTokens.borderWidth,
@@ -86,6 +87,8 @@ function themedStyles(theme, props) {
86
87
  borderColor: variantTokens.borderColor
87
88
  },
88
89
  label: {
90
+ flexShrink: 1,
91
+ minWidth: 0,
89
92
  textAlign: "center",
90
93
  fontFamily: badgeTokens.fontFamily,
91
94
  fontSize: sizeTokens.fontSize,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/atoms/badge/root.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\r\nimport { StyleSheet, Text } from \"react-native\";\r\n\r\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\r\nimport {\r\n useComponentsTokens,\r\n useStyleProps,\r\n useThemedStyles,\r\n} from \"@impulse-ui-native/theme\";\r\n\r\nimport type { BadgeProps, BadgeThemeProps } from \"../../../types\";\r\nimport { View } from \"../view\";\r\nimport { BadgeAddon } from \"./addon\";\r\n\r\nexport const BadgeRoot = memo(function BadgeRoot({\r\n backgroundColor,\r\n children,\r\n color,\r\n Prefix,\r\n PrefixIcon,\r\n onPressPrefix,\r\n onPressSuffix,\r\n size = \"medium\",\r\n style,\r\n Suffix,\r\n SuffixIcon,\r\n tone = \"primary\",\r\n variant = \"filled\",\r\n ...props\r\n}: BadgeProps) {\r\n const tokens = useComponentsTokens();\r\n\r\n const badgeTokens = tokens.badge;\r\n const sizeTokens = badgeTokens.sizes[size];\r\n\r\n const extractedStyleProps = useStyleProps(props);\r\n const styles = useThemedStyles(\r\n themedStyles,\r\n { backgroundColor, color, size, tone, variant },\r\n [backgroundColor, color, size, tone, variant],\r\n );\r\n\r\n const containerStyle = useMemo(\r\n () => [styles.container, extractedStyleProps, style],\r\n [extractedStyleProps, style, styles.container],\r\n );\r\n\r\n const affixColor =\r\n typeof styles.label.color === \"string\" ? styles.label.color : undefined;\r\n\r\n const isTextChild =\r\n typeof children === \"string\" || typeof children === \"number\";\r\n\r\n return (\r\n <View {...props} style={containerStyle}>\r\n <BadgeAddon\r\n Content={Prefix}\r\n IconComponent={PrefixIcon}\r\n color={affixColor}\r\n hitSlop={badgeTokens.addonHitSlop}\r\n iconSize={sizeTokens.iconSize}\r\n onPress={onPressPrefix}\r\n />\r\n\r\n {isTextChild ? (\r\n <Text numberOfLines={1} style={styles.label}>\r\n {children}\r\n </Text>\r\n ) : (\r\n children\r\n )}\r\n\r\n <BadgeAddon\r\n Content={Suffix}\r\n IconComponent={SuffixIcon}\r\n color={affixColor}\r\n hitSlop={badgeTokens.addonHitSlop}\r\n iconSize={sizeTokens.iconSize}\r\n onPress={onPressSuffix}\r\n />\r\n </View>\r\n );\r\n});\r\n\r\nfunction themedStyles(theme: AppTheme, props: BadgeThemeProps) {\r\n const { backgroundColor, color, size, tone, variant } = props;\r\n\r\n const badgeTokens = theme.components.badge;\r\n const sizeTokens = badgeTokens.sizes[size];\r\n const variantTokens = badgeTokens.colors[tone][variant];\r\n\r\n return StyleSheet.create({\r\n container: {\r\n alignItems: \"center\",\r\n flexDirection: \"row\",\r\n flexShrink: 0,\r\n justifyContent: \"center\",\r\n\r\n borderRadius: badgeTokens.borderRadius,\r\n borderWidth: badgeTokens.borderWidth,\r\n gap: badgeTokens.gap,\r\n height: sizeTokens.height,\r\n minWidth: sizeTokens.minWidth,\r\n paddingHorizontal: sizeTokens.paddingHorizontal,\r\n\r\n backgroundColor: backgroundColor ?? variantTokens.backgroundColor,\r\n borderColor: variantTokens.borderColor,\r\n },\r\n\r\n label: {\r\n textAlign: \"center\",\r\n\r\n fontFamily: badgeTokens.fontFamily,\r\n fontSize: sizeTokens.fontSize,\r\n lineHeight: sizeTokens.lineHeight,\r\n\r\n color: color ?? variantTokens.color,\r\n },\r\n });\r\n}\r\n"],"mappings":"AAsDI,SACE,KADF;AAtDJ,SAAS,MAAM,eAAe;AAC9B,SAAS,YAAY,YAAY;AAGjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAEpB,MAAM,YAAY,KAAK,SAASA,WAAU;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL,GAAe;AACb,QAAM,SAAS,oBAAoB;AAEnC,QAAM,cAAc,OAAO;AAC3B,QAAM,aAAa,YAAY,MAAM,IAAI;AAEzC,QAAM,sBAAsB,cAAc,KAAK;AAC/C,QAAM,SAAS;AAAA,IACb;AAAA,IACA,EAAE,iBAAiB,OAAO,MAAM,MAAM,QAAQ;AAAA,IAC9C,CAAC,iBAAiB,OAAO,MAAM,MAAM,OAAO;AAAA,EAC9C;AAEA,QAAM,iBAAiB;AAAA,IACrB,MAAM,CAAC,OAAO,WAAW,qBAAqB,KAAK;AAAA,IACnD,CAAC,qBAAqB,OAAO,OAAO,SAAS;AAAA,EAC/C;AAEA,QAAM,aACJ,OAAO,OAAO,MAAM,UAAU,WAAW,OAAO,MAAM,QAAQ;AAEhE,QAAM,cACJ,OAAO,aAAa,YAAY,OAAO,aAAa;AAEtD,SACE,qBAAC,QAAM,GAAG,OAAO,OAAO,gBACtB;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO;AAAA,QACP,SAAS,YAAY;AAAA,QACrB,UAAU,WAAW;AAAA,QACrB,SAAS;AAAA;AAAA,IACX;AAAA,IAEC,cACC,oBAAC,QAAK,eAAe,GAAG,OAAO,OAAO,OACnC,UACH,IAEA;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO;AAAA,QACP,SAAS,YAAY;AAAA,QACrB,UAAU,WAAW;AAAA,QACrB,SAAS;AAAA;AAAA,IACX;AAAA,KACF;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB,OAAwB;AAC7D,QAAM,EAAE,iBAAiB,OAAO,MAAM,MAAM,QAAQ,IAAI;AAExD,QAAM,cAAc,MAAM,WAAW;AACrC,QAAM,aAAa,YAAY,MAAM,IAAI;AACzC,QAAM,gBAAgB,YAAY,OAAO,IAAI,EAAE,OAAO;AAEtD,SAAO,WAAW,OAAO;AAAA,IACvB,WAAW;AAAA,MACT,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAEhB,cAAc,YAAY;AAAA,MAC1B,aAAa,YAAY;AAAA,MACzB,KAAK,YAAY;AAAA,MACjB,QAAQ,WAAW;AAAA,MACnB,UAAU,WAAW;AAAA,MACrB,mBAAmB,WAAW;AAAA,MAE9B,iBAAiB,mBAAmB,cAAc;AAAA,MAClD,aAAa,cAAc;AAAA,IAC7B;AAAA,IAEA,OAAO;AAAA,MACL,WAAW;AAAA,MAEX,YAAY,YAAY;AAAA,MACxB,UAAU,WAAW;AAAA,MACrB,YAAY,WAAW;AAAA,MAEvB,OAAO,SAAS,cAAc;AAAA,IAChC;AAAA,EACF,CAAC;AACH;","names":["BadgeRoot"]}
1
+ {"version":3,"sources":["../../../../src/components/atoms/badge/root.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\r\nimport { StyleSheet, Text } from \"react-native\";\r\n\r\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\r\nimport {\r\n useComponentsTokens,\r\n useStyleProps,\r\n useThemedStyles,\r\n} from \"@impulse-ui-native/theme\";\r\n\r\nimport type { BadgeProps, BadgeThemeProps } from \"../../../types\";\r\nimport { View } from \"../view\";\r\nimport { BadgeAddon } from \"./addon\";\r\n\r\nexport const BadgeRoot = memo(function BadgeRoot({\r\n backgroundColor,\r\n children,\r\n color,\r\n Prefix,\r\n PrefixIcon,\r\n onPressPrefix,\r\n onPressSuffix,\r\n size = \"medium\",\r\n style,\r\n Suffix,\r\n SuffixIcon,\r\n tone = \"primary\",\r\n variant = \"filled\",\r\n ...props\r\n}: BadgeProps) {\r\n const tokens = useComponentsTokens();\r\n\r\n const badgeTokens = tokens.badge;\r\n const sizeTokens = badgeTokens.sizes[size];\r\n\r\n const extractedStyleProps = useStyleProps(props);\r\n const styles = useThemedStyles(\r\n themedStyles,\r\n { backgroundColor, color, size, tone, variant },\r\n [backgroundColor, color, size, tone, variant],\r\n );\r\n\r\n const containerStyle = useMemo(\r\n () => [styles.container, extractedStyleProps, style],\r\n [extractedStyleProps, style, styles.container],\r\n );\r\n\r\n const affixColor =\r\n typeof styles.label.color === \"string\" ? styles.label.color : undefined;\r\n\r\n const isTextChild =\r\n typeof children === \"string\" || typeof children === \"number\";\r\n\r\n return (\r\n <View {...props} style={containerStyle}>\r\n <BadgeAddon\r\n Content={Prefix}\r\n IconComponent={PrefixIcon}\r\n color={affixColor}\r\n hitSlop={badgeTokens.addonHitSlop}\r\n iconSize={sizeTokens.iconSize}\r\n onPress={onPressPrefix}\r\n />\r\n\r\n {isTextChild ? (\r\n <Text numberOfLines={1} ellipsizeMode=\"tail\" style={styles.label}>\r\n {children}\r\n </Text>\r\n ) : (\r\n children\r\n )}\r\n\r\n <BadgeAddon\r\n Content={Suffix}\r\n IconComponent={SuffixIcon}\r\n color={affixColor}\r\n hitSlop={badgeTokens.addonHitSlop}\r\n iconSize={sizeTokens.iconSize}\r\n onPress={onPressSuffix}\r\n />\r\n </View>\r\n );\r\n});\r\n\r\nfunction themedStyles(theme: AppTheme, props: BadgeThemeProps) {\r\n const { backgroundColor, color, size, tone, variant } = props;\r\n\r\n const badgeTokens = theme.components.badge;\r\n const sizeTokens = badgeTokens.sizes[size];\r\n const variantTokens = badgeTokens.colors[tone][variant];\r\n\r\n return StyleSheet.create({\r\n container: {\r\n alignItems: \"center\",\r\n flexDirection: \"row\",\r\n flexShrink: 1,\r\n maxWidth: \"100%\",\r\n justifyContent: \"center\",\r\n\r\n borderRadius: badgeTokens.borderRadius,\r\n borderWidth: badgeTokens.borderWidth,\r\n gap: badgeTokens.gap,\r\n height: sizeTokens.height,\r\n minWidth: sizeTokens.minWidth,\r\n paddingHorizontal: sizeTokens.paddingHorizontal,\r\n\r\n backgroundColor: backgroundColor ?? variantTokens.backgroundColor,\r\n borderColor: variantTokens.borderColor,\r\n },\r\n\r\n label: {\r\n flexShrink: 1,\r\n minWidth: 0,\r\n textAlign: \"center\",\r\n\r\n fontFamily: badgeTokens.fontFamily,\r\n fontSize: sizeTokens.fontSize,\r\n lineHeight: sizeTokens.lineHeight,\r\n\r\n color: color ?? variantTokens.color,\r\n },\r\n });\r\n}\r\n"],"mappings":"AAsDI,SACE,KADF;AAtDJ,SAAS,MAAM,eAAe;AAC9B,SAAS,YAAY,YAAY;AAGjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,YAAY;AACrB,SAAS,kBAAkB;AAEpB,MAAM,YAAY,KAAK,SAASA,WAAU;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,GAAG;AACL,GAAe;AACb,QAAM,SAAS,oBAAoB;AAEnC,QAAM,cAAc,OAAO;AAC3B,QAAM,aAAa,YAAY,MAAM,IAAI;AAEzC,QAAM,sBAAsB,cAAc,KAAK;AAC/C,QAAM,SAAS;AAAA,IACb;AAAA,IACA,EAAE,iBAAiB,OAAO,MAAM,MAAM,QAAQ;AAAA,IAC9C,CAAC,iBAAiB,OAAO,MAAM,MAAM,OAAO;AAAA,EAC9C;AAEA,QAAM,iBAAiB;AAAA,IACrB,MAAM,CAAC,OAAO,WAAW,qBAAqB,KAAK;AAAA,IACnD,CAAC,qBAAqB,OAAO,OAAO,SAAS;AAAA,EAC/C;AAEA,QAAM,aACJ,OAAO,OAAO,MAAM,UAAU,WAAW,OAAO,MAAM,QAAQ;AAEhE,QAAM,cACJ,OAAO,aAAa,YAAY,OAAO,aAAa;AAEtD,SACE,qBAAC,QAAM,GAAG,OAAO,OAAO,gBACtB;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO;AAAA,QACP,SAAS,YAAY;AAAA,QACrB,UAAU,WAAW;AAAA,QACrB,SAAS;AAAA;AAAA,IACX;AAAA,IAEC,cACC,oBAAC,QAAK,eAAe,GAAG,eAAc,QAAO,OAAO,OAAO,OACxD,UACH,IAEA;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,eAAe;AAAA,QACf,OAAO;AAAA,QACP,SAAS,YAAY;AAAA,QACrB,UAAU,WAAW;AAAA,QACrB,SAAS;AAAA;AAAA,IACX;AAAA,KACF;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB,OAAwB;AAC7D,QAAM,EAAE,iBAAiB,OAAO,MAAM,MAAM,QAAQ,IAAI;AAExD,QAAM,cAAc,MAAM,WAAW;AACrC,QAAM,aAAa,YAAY,MAAM,IAAI;AACzC,QAAM,gBAAgB,YAAY,OAAO,IAAI,EAAE,OAAO;AAEtD,SAAO,WAAW,OAAO;AAAA,IACvB,WAAW;AAAA,MACT,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,gBAAgB;AAAA,MAEhB,cAAc,YAAY;AAAA,MAC1B,aAAa,YAAY;AAAA,MACzB,KAAK,YAAY;AAAA,MACjB,QAAQ,WAAW;AAAA,MACnB,UAAU,WAAW;AAAA,MACrB,mBAAmB,WAAW;AAAA,MAE9B,iBAAiB,mBAAmB,cAAc;AAAA,MAClD,aAAa,cAAc;AAAA,IAC7B;AAAA,IAEA,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,WAAW;AAAA,MAEX,YAAY,YAAY;AAAA,MACxB,UAAU,WAAW;AAAA,MACrB,YAAY,WAAW;AAAA,MAEvB,OAAO,SAAS,cAAc;AAAA,IAChC;AAAA,EACF,CAAC;AACH;","names":["BadgeRoot"]}
@@ -3,6 +3,6 @@ import { TagProps } from '../../types/tag.types.mjs';
3
3
  import 'react-native';
4
4
  import '@impulse-ui-native/theme';
5
5
 
6
- declare const Tag: react.MemoExoticComponent<({ label, size, variant, tone, closable, disabled, onClose, onPress, }: TagProps) => react.JSX.Element>;
6
+ declare const Tag: react.MemoExoticComponent<({ label, style, size, variant, tone, closable, disabled, onClose, onPress, }: TagProps) => react.JSX.Element>;
7
7
 
8
8
  export { Tag };
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { memo } from "react";
2
+ import { memo, useMemo } from "react";
3
3
  import { StyleSheet, View } from "react-native";
4
4
  import { Icon } from "@impulse-ui-native/icon";
5
5
  import { XCircleIcon } from "@impulse-ui-native/icon/icons/x-circle";
@@ -12,6 +12,7 @@ import { Pressable } from "./pressable";
12
12
  import { Typography } from "./typography";
13
13
  const Tag = memo(function Tag2({
14
14
  label,
15
+ style,
15
16
  size = "medium",
16
17
  variant = "filled",
17
18
  tone = "primary",
@@ -32,10 +33,22 @@ const Tag = memo(function Tag2({
32
33
  },
33
34
  [size, variant, disabled, tone]
34
35
  );
36
+ const containerStyle = useMemo(
37
+ () => [styles.container, style],
38
+ [styles.container, style]
39
+ );
35
40
  const Container = onPress ? Pressable : View;
36
41
  const showClose = closable && !disabled && onClose;
37
- return /* @__PURE__ */ jsxs(Container, { onPress, disabled, style: styles.container, children: [
38
- /* @__PURE__ */ jsx(Typography.Caption, { style: styles.label, children: label }),
42
+ return /* @__PURE__ */ jsxs(Container, { onPress, disabled, style: containerStyle, children: [
43
+ /* @__PURE__ */ jsx(
44
+ Typography.Caption,
45
+ {
46
+ numberOfLines: 1,
47
+ ellipsizeMode: "tail",
48
+ style: styles.label,
49
+ children: label
50
+ }
51
+ ),
39
52
  showClose ? /* @__PURE__ */ jsx(Pressable, { onPress: onClose, hitSlop: tagTokens.closeHitSlop, children: /* @__PURE__ */ jsx(
40
53
  Icon,
41
54
  {
@@ -61,6 +74,8 @@ function themedStyles(theme, props) {
61
74
  alignItems: "center",
62
75
  justifyContent: "center",
63
76
  alignSelf: "flex-start",
77
+ flexShrink: 1,
78
+ maxWidth: "100%",
64
79
  height: sizeTokens.height,
65
80
  paddingHorizontal: sizeTokens.paddingHorizontal,
66
81
  minWidth: sizeTokens.minWidth,
@@ -71,6 +86,8 @@ function themedStyles(theme, props) {
71
86
  backgroundColor: appearanceTokens.backgroundColor
72
87
  },
73
88
  label: {
89
+ flexShrink: 1,
90
+ minWidth: 0,
74
91
  fontSize: sizeTokens.fontSize,
75
92
  color: appearanceTokens.color
76
93
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/atoms/tag.tsx"],"sourcesContent":["import { memo } from \"react\";\r\nimport { StyleSheet, View } from \"react-native\";\r\n\r\nimport { Icon } from \"@impulse-ui-native/icon\";\r\nimport { XCircleIcon } from \"@impulse-ui-native/icon/icons/x-circle\";\r\nimport {\r\n AppTheme,\r\n getAvailabilityStateTokens,\r\n useComponentsTokens,\r\n useThemedStyles,\r\n} from \"@impulse-ui-native/theme\";\r\n\r\nimport { TagProps, TagThemeProps } from \"../../types\";\r\nimport { Pressable } from \"./pressable\";\r\nimport { Typography } from \"./typography\";\r\n\r\nexport const Tag = memo(function Tag({\r\n label,\r\n size = \"medium\",\r\n variant = \"filled\",\r\n tone = \"primary\",\r\n closable,\r\n disabled,\r\n onClose,\r\n onPress,\r\n}: TagProps) {\r\n const tokens = useComponentsTokens();\r\n\r\n const tagTokens = tokens.tag;\r\n\r\n const styles = useThemedStyles(\r\n themedStyles,\r\n {\r\n size,\r\n variant,\r\n disabled,\r\n tone,\r\n },\r\n [size, variant, disabled, tone],\r\n );\r\n\r\n const Container = onPress ? Pressable : View;\r\n\r\n const showClose = closable && !disabled && onClose;\r\n\r\n return (\r\n <Container onPress={onPress} disabled={disabled} style={styles.container}>\r\n <Typography.Caption style={styles.label}>{label}</Typography.Caption>\r\n\r\n {showClose ? (\r\n <Pressable onPress={onClose} hitSlop={tagTokens.closeHitSlop}>\r\n <Icon\r\n icon={XCircleIcon}\r\n size=\"small\"\r\n color={styles.icon.color}\r\n style={styles.icon}\r\n />\r\n </Pressable>\r\n ) : null}\r\n </Container>\r\n );\r\n});\r\n\r\nfunction themedStyles(theme: AppTheme, props: TagThemeProps) {\r\n const { size, variant, tone, disabled } = props;\r\n\r\n const tagTokens = theme.components.tag;\r\n const sizeTokens = tagTokens.sizes[size];\r\n const appearanceTokens = getAvailabilityStateTokens(\r\n tagTokens.colors[tone][variant],\r\n { disabled },\r\n );\r\n\r\n return StyleSheet.create({\r\n container: {\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n alignSelf: \"flex-start\",\r\n\r\n height: sizeTokens.height,\r\n paddingHorizontal: sizeTokens.paddingHorizontal,\r\n minWidth: sizeTokens.minWidth,\r\n\r\n borderRadius: tagTokens.borderRadius,\r\n gap: tagTokens.gap,\r\n borderWidth: tagTokens.borderWidth,\r\n\r\n borderColor: appearanceTokens.borderColor,\r\n backgroundColor: appearanceTokens.backgroundColor,\r\n },\r\n\r\n label: {\r\n fontSize: sizeTokens.fontSize,\r\n color: appearanceTokens.color,\r\n },\r\n\r\n icon: {\r\n marginLeft: tagTokens.iconMarginLeft,\r\n color: appearanceTokens.color,\r\n },\r\n });\r\n}\r\n"],"mappings":"AA8CI,SACE,KADF;AA9CJ,SAAS,YAAY;AACrB,SAAS,YAAY,YAAY;AAEjC,SAAS,YAAY;AACrB,SAAS,mBAAmB;AAC5B;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAEpB,MAAM,MAAM,KAAK,SAASA,KAAI;AAAA,EACnC;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAa;AACX,QAAM,SAAS,oBAAoB;AAEnC,QAAM,YAAY,OAAO;AAEzB,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,MAAM,SAAS,UAAU,IAAI;AAAA,EAChC;AAEA,QAAM,YAAY,UAAU,YAAY;AAExC,QAAM,YAAY,YAAY,CAAC,YAAY;AAE3C,SACE,qBAAC,aAAU,SAAkB,UAAoB,OAAO,OAAO,WAC7D;AAAA,wBAAC,WAAW,SAAX,EAAmB,OAAO,OAAO,OAAQ,iBAAM;AAAA,IAE/C,YACC,oBAAC,aAAU,SAAS,SAAS,SAAS,UAAU,cAC9C;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,MAAK;AAAA,QACL,OAAO,OAAO,KAAK;AAAA,QACnB,OAAO,OAAO;AAAA;AAAA,IAChB,GACF,IACE;AAAA,KACN;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB,OAAsB;AAC3D,QAAM,EAAE,MAAM,SAAS,MAAM,SAAS,IAAI;AAE1C,QAAM,YAAY,MAAM,WAAW;AACnC,QAAM,aAAa,UAAU,MAAM,IAAI;AACvC,QAAM,mBAAmB;AAAA,IACvB,UAAU,OAAO,IAAI,EAAE,OAAO;AAAA,IAC9B,EAAE,SAAS;AAAA,EACb;AAEA,SAAO,WAAW,OAAO;AAAA,IACvB,WAAW;AAAA,MACT,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,WAAW;AAAA,MAEX,QAAQ,WAAW;AAAA,MACnB,mBAAmB,WAAW;AAAA,MAC9B,UAAU,WAAW;AAAA,MAErB,cAAc,UAAU;AAAA,MACxB,KAAK,UAAU;AAAA,MACf,aAAa,UAAU;AAAA,MAEvB,aAAa,iBAAiB;AAAA,MAC9B,iBAAiB,iBAAiB;AAAA,IACpC;AAAA,IAEA,OAAO;AAAA,MACL,UAAU,WAAW;AAAA,MACrB,OAAO,iBAAiB;AAAA,IAC1B;AAAA,IAEA,MAAM;AAAA,MACJ,YAAY,UAAU;AAAA,MACtB,OAAO,iBAAiB;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;","names":["Tag"]}
1
+ {"version":3,"sources":["../../../src/components/atoms/tag.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\r\nimport { StyleSheet, View } from \"react-native\";\r\n\r\nimport type { AppTheme } from \"@impulse-ui-native/theme\";\r\nimport { Icon } from \"@impulse-ui-native/icon\";\r\nimport { XCircleIcon } from \"@impulse-ui-native/icon/icons/x-circle\";\r\nimport {\r\n getAvailabilityStateTokens,\r\n useComponentsTokens,\r\n useThemedStyles,\r\n} from \"@impulse-ui-native/theme\";\r\n\r\nimport type { TagProps, TagThemeProps } from \"../../types\";\r\nimport { Pressable } from \"./pressable\";\r\nimport { Typography } from \"./typography\";\r\n\r\nexport const Tag = memo(function Tag({\r\n label,\r\n style,\r\n size = \"medium\",\r\n variant = \"filled\",\r\n tone = \"primary\",\r\n closable,\r\n disabled,\r\n onClose,\r\n onPress,\r\n}: TagProps) {\r\n const tokens = useComponentsTokens();\r\n\r\n const tagTokens = tokens.tag;\r\n\r\n const styles = useThemedStyles(\r\n themedStyles,\r\n {\r\n size,\r\n variant,\r\n disabled,\r\n tone,\r\n },\r\n [size, variant, disabled, tone],\r\n );\r\n\r\n const containerStyle = useMemo(\r\n () => [styles.container, style],\r\n [styles.container, style],\r\n );\r\n const Container = onPress ? Pressable : View;\r\n\r\n const showClose = closable && !disabled && onClose;\r\n\r\n return (\r\n <Container onPress={onPress} disabled={disabled} style={containerStyle}>\r\n <Typography.Caption\r\n numberOfLines={1}\r\n ellipsizeMode=\"tail\"\r\n style={styles.label}\r\n >\r\n {label}\r\n </Typography.Caption>\r\n\r\n {showClose ? (\r\n <Pressable onPress={onClose} hitSlop={tagTokens.closeHitSlop}>\r\n <Icon\r\n icon={XCircleIcon}\r\n size=\"small\"\r\n color={styles.icon.color}\r\n style={styles.icon}\r\n />\r\n </Pressable>\r\n ) : null}\r\n </Container>\r\n );\r\n});\r\n\r\nfunction themedStyles(theme: AppTheme, props: TagThemeProps) {\r\n const { size, variant, tone, disabled } = props;\r\n\r\n const tagTokens = theme.components.tag;\r\n const sizeTokens = tagTokens.sizes[size];\r\n const appearanceTokens = getAvailabilityStateTokens(\r\n tagTokens.colors[tone][variant],\r\n { disabled },\r\n );\r\n\r\n return StyleSheet.create({\r\n container: {\r\n flexDirection: \"row\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n alignSelf: \"flex-start\",\r\n flexShrink: 1,\r\n maxWidth: \"100%\",\r\n\r\n height: sizeTokens.height,\r\n paddingHorizontal: sizeTokens.paddingHorizontal,\r\n minWidth: sizeTokens.minWidth,\r\n\r\n borderRadius: tagTokens.borderRadius,\r\n gap: tagTokens.gap,\r\n borderWidth: tagTokens.borderWidth,\r\n\r\n borderColor: appearanceTokens.borderColor,\r\n backgroundColor: appearanceTokens.backgroundColor,\r\n },\r\n\r\n label: {\r\n flexShrink: 1,\r\n minWidth: 0,\r\n fontSize: sizeTokens.fontSize,\r\n color: appearanceTokens.color,\r\n },\r\n\r\n icon: {\r\n marginLeft: tagTokens.iconMarginLeft,\r\n color: appearanceTokens.color,\r\n },\r\n });\r\n}\r\n"],"mappings":"AAmDI,SACE,KADF;AAnDJ,SAAS,MAAM,eAAe;AAC9B,SAAS,YAAY,YAAY;AAGjC,SAAS,YAAY;AACrB,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAGP,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAEpB,MAAM,MAAM,KAAK,SAASA,KAAI;AAAA,EACnC;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAa;AACX,QAAM,SAAS,oBAAoB;AAEnC,QAAM,YAAY,OAAO;AAEzB,QAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA,CAAC,MAAM,SAAS,UAAU,IAAI;AAAA,EAChC;AAEA,QAAM,iBAAiB;AAAA,IACrB,MAAM,CAAC,OAAO,WAAW,KAAK;AAAA,IAC9B,CAAC,OAAO,WAAW,KAAK;AAAA,EAC1B;AACA,QAAM,YAAY,UAAU,YAAY;AAExC,QAAM,YAAY,YAAY,CAAC,YAAY;AAE3C,SACE,qBAAC,aAAU,SAAkB,UAAoB,OAAO,gBACtD;AAAA;AAAA,MAAC,WAAW;AAAA,MAAX;AAAA,QACC,eAAe;AAAA,QACf,eAAc;AAAA,QACd,OAAO,OAAO;AAAA,QAEb;AAAA;AAAA,IACH;AAAA,IAEC,YACC,oBAAC,aAAU,SAAS,SAAS,SAAS,UAAU,cAC9C;AAAA,MAAC;AAAA;AAAA,QACC,MAAM;AAAA,QACN,MAAK;AAAA,QACL,OAAO,OAAO,KAAK;AAAA,QACnB,OAAO,OAAO;AAAA;AAAA,IAChB,GACF,IACE;AAAA,KACN;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB,OAAsB;AAC3D,QAAM,EAAE,MAAM,SAAS,MAAM,SAAS,IAAI;AAE1C,QAAM,YAAY,MAAM,WAAW;AACnC,QAAM,aAAa,UAAU,MAAM,IAAI;AACvC,QAAM,mBAAmB;AAAA,IACvB,UAAU,OAAO,IAAI,EAAE,OAAO;AAAA,IAC9B,EAAE,SAAS;AAAA,EACb;AAEA,SAAO,WAAW,OAAO;AAAA,IACvB,WAAW;AAAA,MACT,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,UAAU;AAAA,MAEV,QAAQ,WAAW;AAAA,MACnB,mBAAmB,WAAW;AAAA,MAC9B,UAAU,WAAW;AAAA,MAErB,cAAc,UAAU;AAAA,MACxB,KAAK,UAAU;AAAA,MACf,aAAa,UAAU;AAAA,MAEvB,aAAa,iBAAiB;AAAA,MAC9B,iBAAiB,iBAAiB;AAAA,IACpC;AAAA,IAEA,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,UAAU,WAAW;AAAA,MACrB,OAAO,iBAAiB;AAAA,IAC1B;AAAA,IAEA,MAAM;AAAA,MACJ,YAAY,UAAU;AAAA,MACtB,OAAO,iBAAiB;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;","names":["Tag"]}
@@ -0,0 +1,20 @@
1
+ import { BadgeProps } from './badge.types.mjs';
2
+ import 'react';
3
+ import 'react-native';
4
+ import '@impulse-ui-native/theme';
5
+ import './control-components.types.mjs';
6
+ import '@impulse-ui-native/icon/types';
7
+ import './button.types.mjs';
8
+ import './view.types.mjs';
9
+ import './spinner.types.mjs';
10
+
11
+ interface BadgeAddonProps {
12
+ color: string | undefined;
13
+ Content: BadgeProps["Prefix"];
14
+ hitSlop: number;
15
+ iconSize: number;
16
+ IconComponent: BadgeProps["PrefixIcon"];
17
+ onPress: BadgeProps["onPressPrefix"];
18
+ }
19
+
20
+ export type { BadgeAddonProps };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=badge-addon.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impulse-ui-native/primitives",
3
- "version": "16.0.0",
3
+ "version": "17.0.0",
4
4
  "description": "Foundational UI primitives for building ImpulseUI Native components.",
5
5
  "keywords": [
6
6
  "react-native",
@@ -28,9 +28,9 @@
28
28
  ],
29
29
  "sideEffects": false,
30
30
  "dependencies": {
31
- "@impulse-ui-native/theme": "16.0.0",
32
- "@impulse-ui-native/icon": "16.0.0",
33
- "@impulse-ui-native/core": "16.0.0"
31
+ "@impulse-ui-native/theme": "17.0.0",
32
+ "@impulse-ui-native/icon": "17.0.0",
33
+ "@impulse-ui-native/core": "17.0.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "@impulse-ui-native/eslint-config": "1.0.0",