@impulse-ui-native/primitives 2.6.0 → 2.8.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.
Files changed (101) hide show
  1. package/README.md +51 -3
  2. package/dist/components/atoms/avatar.d.mts +10 -0
  3. package/dist/components/atoms/avatar.js +161 -0
  4. package/dist/components/atoms/avatar.js.map +1 -0
  5. package/dist/components/atoms/button.d.mts +1 -1
  6. package/dist/components/atoms/button.js +26 -5
  7. package/dist/components/atoms/button.js.map +1 -1
  8. package/dist/components/atoms/circular-progress.d.mts +16 -0
  9. package/dist/components/atoms/circular-progress.js +144 -0
  10. package/dist/components/atoms/circular-progress.js.map +1 -0
  11. package/dist/components/atoms/divider.d.mts +10 -0
  12. package/dist/components/atoms/divider.js +48 -0
  13. package/dist/components/atoms/divider.js.map +1 -0
  14. package/dist/components/atoms/icon-button.d.mts +1 -1
  15. package/dist/components/atoms/icon-button.js +22 -1
  16. package/dist/components/atoms/icon-button.js.map +1 -1
  17. package/dist/components/atoms/index.d.mts +11 -2
  18. package/dist/components/atoms/index.js +8 -0
  19. package/dist/components/atoms/index.js.map +1 -1
  20. package/dist/components/atoms/linear-progress.d.mts +17 -0
  21. package/dist/components/atoms/linear-progress.js +97 -0
  22. package/dist/components/atoms/linear-progress.js.map +1 -0
  23. package/dist/components/atoms/pressable.d.mts +4 -4
  24. package/dist/components/atoms/pressable.js +48 -43
  25. package/dist/components/atoms/pressable.js.map +1 -1
  26. package/dist/components/atoms/progress.d.mts +9 -0
  27. package/dist/components/atoms/progress.js +94 -0
  28. package/dist/components/atoms/progress.js.map +1 -0
  29. package/dist/components/atoms/spinner.d.mts +9 -0
  30. package/dist/components/atoms/spinner.js +74 -0
  31. package/dist/components/atoms/spinner.js.map +1 -0
  32. package/dist/components/card/card.d.mts +17 -0
  33. package/dist/components/card/card.js +18 -0
  34. package/dist/components/card/card.js.map +1 -0
  35. package/dist/components/card/content.d.mts +10 -0
  36. package/dist/components/card/content.js +27 -0
  37. package/dist/components/card/content.js.map +1 -0
  38. package/dist/components/card/footer.d.mts +10 -0
  39. package/dist/components/card/footer.js +27 -0
  40. package/dist/components/card/footer.js.map +1 -0
  41. package/dist/components/card/header.d.mts +10 -0
  42. package/dist/components/card/header.js +27 -0
  43. package/dist/components/card/header.js.map +1 -0
  44. package/dist/components/card/index.d.mts +7 -0
  45. package/dist/components/card/index.js +5 -0
  46. package/dist/components/card/index.js.map +1 -0
  47. package/dist/components/card/media.d.mts +10 -0
  48. package/dist/components/card/media.js +32 -0
  49. package/dist/components/card/media.js.map +1 -0
  50. package/dist/components/card/pressable.d.mts +10 -0
  51. package/dist/components/card/pressable.js +45 -0
  52. package/dist/components/card/pressable.js.map +1 -0
  53. package/dist/components/card/root.d.mts +10 -0
  54. package/dist/components/card/root.js +21 -0
  55. package/dist/components/card/root.js.map +1 -0
  56. package/dist/components/card/root.styles.d.mts +13 -0
  57. package/dist/components/card/root.styles.js +17 -0
  58. package/dist/components/card/root.styles.js.map +1 -0
  59. package/dist/components/controls/addon.d.mts +1 -0
  60. package/dist/components/controls/container.d.mts +1 -0
  61. package/dist/components/controls/control.d.mts +3 -2
  62. package/dist/components/controls/error.d.mts +1 -0
  63. package/dist/components/controls/index.d.mts +1 -0
  64. package/dist/components/controls/input.d.mts +1 -0
  65. package/dist/components/controls/label.d.mts +1 -0
  66. package/dist/components/controls/loader.d.mts +7 -1
  67. package/dist/components/controls/loader.js +3 -3
  68. package/dist/components/controls/loader.js.map +1 -1
  69. package/dist/components/controls/placeholder.d.mts +1 -0
  70. package/dist/components/controls/provider.d.mts +1 -0
  71. package/dist/components/controls/value.d.mts +1 -0
  72. package/dist/components/index.d.mts +13 -3
  73. package/dist/components/index.js +1 -0
  74. package/dist/components/index.js.map +1 -1
  75. package/dist/hooks/use-indeterminate-progress-animation.hook.d.mts +5 -0
  76. package/dist/hooks/use-indeterminate-progress-animation.hook.js +47 -0
  77. package/dist/hooks/use-indeterminate-progress-animation.hook.js.map +1 -0
  78. package/dist/index.d.mts +11 -1
  79. package/dist/types/avatar.types.d.mts +20 -0
  80. package/dist/types/avatar.types.js +1 -0
  81. package/dist/types/avatar.types.js.map +1 -0
  82. package/dist/types/card.types.d.mts +21 -0
  83. package/dist/types/card.types.js +1 -0
  84. package/dist/types/card.types.js.map +1 -0
  85. package/dist/types/control-components.types.d.mts +3 -2
  86. package/dist/types/divider.types.d.mts +14 -0
  87. package/dist/types/divider.types.js +1 -0
  88. package/dist/types/divider.types.js.map +1 -0
  89. package/dist/types/index.d.mts +6 -1
  90. package/dist/types/index.js +5 -0
  91. package/dist/types/index.js.map +1 -1
  92. package/dist/types/progress.types.d.mts +15 -0
  93. package/dist/types/progress.types.js +1 -0
  94. package/dist/types/progress.types.js.map +1 -0
  95. package/dist/types/spinner.types.d.mts +9 -0
  96. package/dist/types/spinner.types.js +1 -0
  97. package/dist/types/spinner.types.js.map +1 -0
  98. package/dist/utils/progress.utils.d.mts +9 -0
  99. package/dist/utils/progress.utils.js +27 -0
  100. package/dist/utils/progress.utils.js.map +1 -0
  101. package/package.json +8 -6
package/README.md CHANGED
@@ -10,10 +10,10 @@ pnpm add @impulse-ui-native/primitives
10
10
 
11
11
  Render primitives inside `ThemeProvider` from `@impulse-ui-native/theme`.
12
12
 
13
- `SafeAreaView` additionally requires `react-native-safe-area-context` and a `SafeAreaProvider` near the application root:
13
+ `SafeAreaView` additionally requires `react-native-safe-area-context` and a `SafeAreaProvider` near the application root. Circular `Progress` requires `react-native-svg`:
14
14
 
15
15
  ```sh
16
- pnpm add react-native-safe-area-context
16
+ pnpm add react-native-safe-area-context react-native-svg
17
17
  ```
18
18
 
19
19
  ## Main exports
@@ -22,6 +22,11 @@ pnpm add react-native-safe-area-context
22
22
  - `SafeAreaView` maps safe-area edges to the theme spacing scale.
23
23
  - `Typography` exposes named text presets such as `DisplayLarge`, `Title1`, `Body`, `Caption`, and `Code`.
24
24
  - `Button`, `IconButton`, `Pressable`, and `Tag` provide themed interaction primitives.
25
+ - `Spinner` provides token-aware sizes and semantic colors for indeterminate loading states.
26
+ - `Progress` provides accessible linear and circular determinate or indeterminate progress.
27
+ - `Card` provides compound `Root`, `Pressable`, `Header`, `Content`, `Footer`, and `Media` surfaces.
28
+ - `Divider` separates content horizontally or vertically with logical insets and semantic colors.
29
+ - `Avatar` represents identity with shared visual variants, images, initials, custom fallbacks, and semantic presence status.
25
30
  - `Control` is a compound control system with `Provider`, `Root`, `Label`, `Container`, `Addon`, `Input`, `Placeholder`, `Value`, `Loader`, and `Error` parts.
26
31
  - `createPreset` creates reusable themed typography presets.
27
32
  - Public prop types describe every primitive and control part.
@@ -29,13 +34,44 @@ pnpm add react-native-safe-area-context
29
34
  ## Example
30
35
 
31
36
  ```tsx
32
- import { Button, Tag, Typography, View } from "@impulse-ui-native/primitives";
37
+ import {
38
+ Avatar,
39
+ Button,
40
+ Card,
41
+ Divider,
42
+ Progress,
43
+ Spinner,
44
+ Tag,
45
+ Typography,
46
+ View,
47
+ } from "@impulse-ui-native/primitives";
33
48
 
34
49
  export function ProfileSummary() {
35
50
  return (
36
51
  <View gap="md" padding="lg">
37
52
  <Typography.Title3>Profile</Typography.Title3>
53
+ <Avatar
54
+ initials="AK"
55
+ status="online"
56
+ variant="soft"
57
+ accessibilityLabel="Alex Kim, online"
58
+ />
38
59
  <Tag label="Active" color="success" />
60
+ <Spinner
61
+ size="small"
62
+ tone="secondary"
63
+ accessibilityLabel="Loading profile"
64
+ />
65
+ <Progress value={65} accessibilityLabel="Profile completion" />
66
+ <Card.Root>
67
+ <Card.Header>
68
+ <Typography.Title4>Account activity</Typography.Title4>
69
+ </Card.Header>
70
+ <Card.Content>
71
+ <Typography.Body>Three new updates are available.</Typography.Body>
72
+ </Card.Content>
73
+ </Card.Root>
74
+ <Divider inset="both" />
39
75
  <Button variant="filled" onPress={() => {}}>
40
76
  Continue
41
77
  </Button>
@@ -45,3 +81,15 @@ export function ProfileSummary() {
45
81
  ```
46
82
 
47
83
  Use the compound `Control` when building a custom field that should share the same label, addon, error, size, and variant behavior as `Input` and `Select`.
84
+
85
+ `Button` and `IconButton` replace their content with a loading indicator when `loading` is true. Loading controls block interaction and expose their busy state to assistive technologies. Provide an `accessibilityLabel` for every `IconButton` because its icon does not supply an accessible name.
86
+
87
+ `Spinner` defaults to the primary theme tone and medium size. Use `tone="inverse"` on inverse surfaces, or provide `color` when the indicator must match contextual content. Give standalone spinners an `accessibilityLabel` that describes what is loading.
88
+
89
+ `Progress` defaults to a medium linear indicator. Provide `value` for determinate progress or omit it for an indeterminate animation. Values are clamped between `min` and `max`, defaulting to `0` and `100`. Indeterminate animation respects the platform reduced-motion preference. Give each progress indicator an `accessibilityLabel` describing the operation.
90
+
91
+ Use `Card.Root` for a static surface and `Card.Pressable` when the whole card has one action. Pressable cards default to the `button` accessibility role; override it when another role such as `link` is more accurate and provide an accessible label. Avoid placing independently pressable controls inside `Card.Pressable`; use `Card.Root` with actions in `Card.Footer` instead.
92
+
93
+ `Divider` defaults to a subtle horizontal separator and exposes `role="separator"`. Use logical start/end insets to preserve RTL alignment, switch to vertical orientation inside a container with a defined height, and use `color` only when the semantic tones do not fit the surrounding surface.
94
+
95
+ `Avatar` supports the same `filled`, `outlined`, `soft`, `ghost`, and `plain` variants as the control family. It renders fallback content below its image so initials or a custom fallback remain visible while the image loads or when it fails. Provide an `accessibilityLabel` when the represented identity is meaningful, and include presence status in that label when `status` conveys useful information. Avatar grouping and overflow counts are intentionally handled separately.
@@ -0,0 +1,10 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { AvatarProps } from '../../types/avatar.types.mjs';
4
+ import 'react-native';
5
+ import '@impulse-ui-native/theme';
6
+ import '../../types/view.types.mjs';
7
+
8
+ declare const Avatar: react.MemoExoticComponent<({ accessibilityLabel, accessible, fallback, imageProps, initials, role, size, source, status, statusColor, style, variant, ...props }: AvatarProps) => react_jsx_runtime.JSX.Element>;
9
+
10
+ export { Avatar };
@@ -0,0 +1,161 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo, useCallback, useMemo, useState } from "react";
3
+ import { Image, StyleSheet, Text } from "react-native";
4
+ import { useComponentsTokens, useStyleProps } from "@impulse-ui-native/theme";
5
+ import { View } from "./view";
6
+ const Avatar = memo(function Avatar2({
7
+ accessibilityLabel,
8
+ accessible,
9
+ fallback,
10
+ imageProps,
11
+ initials,
12
+ role,
13
+ size = "medium",
14
+ source,
15
+ status,
16
+ statusColor,
17
+ style,
18
+ variant = "filled",
19
+ ...props
20
+ }) {
21
+ const tokens = useComponentsTokens().avatar;
22
+ const extractedStyleProps = useStyleProps(props);
23
+ const sizeTokens = tokens.sizes[size];
24
+ const variantTokens = tokens.variants[variant];
25
+ const resolvedAccessible = accessible ?? Boolean(accessibilityLabel);
26
+ const resolvedRole = role ?? (resolvedAccessible ? "img" : "none");
27
+ const sourceKey = useMemo(() => JSON.stringify(source), [source]);
28
+ const containerStyle = useMemo(
29
+ () => [
30
+ styles.container,
31
+ { height: sizeTokens.size, width: sizeTokens.size },
32
+ extractedStyleProps,
33
+ style
34
+ ],
35
+ [extractedStyleProps, sizeTokens.size, style]
36
+ );
37
+ const contentStyle = useMemo(
38
+ () => [
39
+ styles.content,
40
+ {
41
+ backgroundColor: variantTokens.backgroundColor,
42
+ borderColor: variantTokens.borderColor,
43
+ borderRadius: sizeTokens.size / 2,
44
+ borderWidth: tokens.borderWidth
45
+ }
46
+ ],
47
+ [sizeTokens.size, tokens.borderWidth, variantTokens]
48
+ );
49
+ const initialsStyle = useMemo(
50
+ () => [
51
+ styles.initials,
52
+ {
53
+ color: variantTokens.color,
54
+ fontFamily: tokens.fontFamily,
55
+ fontSize: sizeTokens.fontSize
56
+ }
57
+ ],
58
+ [sizeTokens.fontSize, tokens.fontFamily, variantTokens.color]
59
+ );
60
+ const statusStyle = useMemo(
61
+ () => [
62
+ styles.status,
63
+ {
64
+ backgroundColor: statusColor ?? (status ? tokens.statusColors[status] : void 0),
65
+ borderColor: tokens.statusBorderColor,
66
+ borderRadius: sizeTokens.statusSize / 2,
67
+ borderWidth: sizeTokens.statusBorderWidth,
68
+ height: sizeTokens.statusSize,
69
+ width: sizeTokens.statusSize
70
+ }
71
+ ],
72
+ [sizeTokens, status, statusColor, tokens]
73
+ );
74
+ return /* @__PURE__ */ jsxs(
75
+ View,
76
+ {
77
+ ...props,
78
+ accessibilityLabel,
79
+ accessible: resolvedAccessible,
80
+ role: resolvedRole,
81
+ style: containerStyle,
82
+ children: [
83
+ /* @__PURE__ */ jsxs(View, { style: contentStyle, children: [
84
+ fallback ?? (initials ? /* @__PURE__ */ jsx(Text, { style: initialsStyle, children: initials }) : null),
85
+ source ? /* @__PURE__ */ jsx(
86
+ AvatarImageLayer,
87
+ {
88
+ imageProps,
89
+ source
90
+ },
91
+ sourceKey
92
+ ) : null
93
+ ] }),
94
+ status ? /* @__PURE__ */ jsx(View, { accessible: false, style: statusStyle }) : null
95
+ ]
96
+ }
97
+ );
98
+ });
99
+ const AvatarImageLayer = memo(function AvatarImageLayer2({
100
+ imageProps,
101
+ source
102
+ }) {
103
+ const [hasError, setHasError] = useState(false);
104
+ const handleError = useCallback(
105
+ (event) => {
106
+ setHasError(true);
107
+ imageProps?.onError?.(event);
108
+ },
109
+ [imageProps]
110
+ );
111
+ const imageStyle = useMemo(
112
+ () => [styles.image, imageProps?.style],
113
+ [imageProps?.style]
114
+ );
115
+ if (hasError) return null;
116
+ return /* @__PURE__ */ jsx(
117
+ Image,
118
+ {
119
+ resizeMode: "cover",
120
+ ...imageProps,
121
+ accessible: false,
122
+ onError: handleError,
123
+ source,
124
+ style: imageStyle
125
+ }
126
+ );
127
+ });
128
+ const styles = StyleSheet.create({
129
+ container: {
130
+ flexShrink: 0,
131
+ position: "relative"
132
+ },
133
+ content: {
134
+ alignItems: "center",
135
+ height: "100%",
136
+ justifyContent: "center",
137
+ overflow: "hidden",
138
+ width: "100%"
139
+ },
140
+ image: {
141
+ bottom: 0,
142
+ height: "100%",
143
+ left: 0,
144
+ position: "absolute",
145
+ right: 0,
146
+ top: 0,
147
+ width: "100%"
148
+ },
149
+ initials: {
150
+ textAlign: "center"
151
+ },
152
+ status: {
153
+ bottom: 0,
154
+ position: "absolute",
155
+ right: 0
156
+ }
157
+ });
158
+ export {
159
+ Avatar
160
+ };
161
+ //# sourceMappingURL=avatar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/atoms/avatar.tsx"],"sourcesContent":["import type { ImageProps } from \"react-native\";\nimport { memo, useCallback, useMemo, useState } from \"react\";\nimport { Image, StyleSheet, Text } from \"react-native\";\n\nimport { useComponentsTokens, useStyleProps } from \"@impulse-ui-native/theme\";\n\nimport type { AvatarProps } from \"../../types\";\nimport { View } from \"./view\";\n\nexport const Avatar = memo(function Avatar({\n accessibilityLabel,\n accessible,\n fallback,\n imageProps,\n initials,\n role,\n size = \"medium\",\n source,\n status,\n statusColor,\n style,\n variant = \"filled\",\n ...props\n}: AvatarProps) {\n const tokens = useComponentsTokens().avatar;\n const extractedStyleProps = useStyleProps(props);\n const sizeTokens = tokens.sizes[size];\n const variantTokens = tokens.variants[variant];\n const resolvedAccessible = accessible ?? Boolean(accessibilityLabel);\n const resolvedRole = role ?? (resolvedAccessible ? \"img\" : \"none\");\n const sourceKey = useMemo(() => JSON.stringify(source), [source]);\n\n const containerStyle = useMemo(\n () => [\n styles.container,\n { height: sizeTokens.size, width: sizeTokens.size },\n extractedStyleProps,\n style,\n ],\n [extractedStyleProps, sizeTokens.size, style],\n );\n\n const contentStyle = useMemo(\n () => [\n styles.content,\n {\n backgroundColor: variantTokens.backgroundColor,\n borderColor: variantTokens.borderColor,\n borderRadius: sizeTokens.size / 2,\n borderWidth: tokens.borderWidth,\n },\n ],\n [sizeTokens.size, tokens.borderWidth, variantTokens],\n );\n\n const initialsStyle = useMemo(\n () => [\n styles.initials,\n {\n color: variantTokens.color,\n fontFamily: tokens.fontFamily,\n fontSize: sizeTokens.fontSize,\n },\n ],\n [sizeTokens.fontSize, tokens.fontFamily, variantTokens.color],\n );\n\n const statusStyle = useMemo(\n () => [\n styles.status,\n {\n backgroundColor:\n statusColor ?? (status ? tokens.statusColors[status] : undefined),\n borderColor: tokens.statusBorderColor,\n borderRadius: sizeTokens.statusSize / 2,\n borderWidth: sizeTokens.statusBorderWidth,\n height: sizeTokens.statusSize,\n width: sizeTokens.statusSize,\n },\n ],\n [sizeTokens, status, statusColor, tokens],\n );\n\n return (\n <View\n {...props}\n accessibilityLabel={accessibilityLabel}\n accessible={resolvedAccessible}\n role={resolvedRole}\n style={containerStyle}\n >\n <View style={contentStyle}>\n {fallback ??\n (initials ? <Text style={initialsStyle}>{initials}</Text> : null)}\n\n {source ? (\n <AvatarImageLayer\n key={sourceKey}\n imageProps={imageProps}\n source={source}\n />\n ) : null}\n </View>\n\n {status ? <View accessible={false} style={statusStyle} /> : null}\n </View>\n );\n});\n\ninterface AvatarImageLayerProps {\n imageProps: AvatarProps[\"imageProps\"];\n source: NonNullable<AvatarProps[\"source\"]>;\n}\n\nconst AvatarImageLayer = memo(function AvatarImageLayer({\n imageProps,\n source,\n}: AvatarImageLayerProps) {\n const [hasError, setHasError] = useState(false);\n\n const handleError = useCallback<NonNullable<ImageProps[\"onError\"]>>(\n (event) => {\n setHasError(true);\n imageProps?.onError?.(event);\n },\n [imageProps],\n );\n\n const imageStyle = useMemo(\n () => [styles.image, imageProps?.style],\n [imageProps?.style],\n );\n\n if (hasError) return null;\n\n return (\n <Image\n resizeMode=\"cover\"\n {...imageProps}\n accessible={false}\n onError={handleError}\n source={source}\n style={imageStyle}\n />\n );\n});\n\nconst styles = StyleSheet.create({\n container: {\n flexShrink: 0,\n position: \"relative\",\n },\n content: {\n alignItems: \"center\",\n height: \"100%\",\n justifyContent: \"center\",\n overflow: \"hidden\",\n width: \"100%\",\n },\n image: {\n bottom: 0,\n height: \"100%\",\n left: 0,\n position: \"absolute\",\n right: 0,\n top: 0,\n width: \"100%\",\n },\n initials: {\n textAlign: \"center\",\n },\n status: {\n bottom: 0,\n position: \"absolute\",\n right: 0,\n },\n});\n"],"mappings":"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","names":["Avatar","AvatarImageLayer"]}
@@ -5,6 +5,6 @@ import { ButtonProps } from '../../types/button.types.mjs';
5
5
  import 'react-native';
6
6
  import '@impulse-ui-native/theme';
7
7
 
8
- declare const Button: react.MemoExoticComponent<({ size, variant, disabled, children, style, ...props }: PropsWithChildren<ButtonProps>) => react_jsx_runtime.JSX.Element>;
8
+ declare const Button: react.MemoExoticComponent<({ accessibilityState, size, variant, disabled, loading, children, style, ...props }: PropsWithChildren<ButtonProps>) => react_jsx_runtime.JSX.Element>;
9
9
 
10
10
  export { Button };
@@ -1,13 +1,16 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { memo, useMemo } from "react";
3
- import { ActivityIndicator, StyleSheet } from "react-native";
3
+ import { StyleSheet } from "react-native";
4
4
  import { useThemedStyles } from "@impulse-ui-native/theme";
5
5
  import { Pressable } from "./pressable";
6
+ import { Spinner } from "./spinner";
6
7
  import { Typography } from "./typography";
7
8
  const Button = memo(function Button2({
9
+ accessibilityState,
8
10
  size = "medium",
9
11
  variant = "filled",
10
12
  disabled,
13
+ loading = false,
11
14
  children,
12
15
  style,
13
16
  ...props
@@ -17,17 +20,35 @@ const Button = memo(function Button2({
17
20
  variant,
18
21
  disabled
19
22
  ]);
23
+ const interactionDisabled = disabled === true || loading;
24
+ const resolvedAccessibilityState = useMemo(
25
+ () => ({
26
+ ...accessibilityState,
27
+ busy: loading,
28
+ disabled: interactionDisabled
29
+ }),
30
+ [accessibilityState, interactionDisabled, loading]
31
+ );
20
32
  const buttonStyles = useMemo(
21
33
  () => [styles.button, style],
22
34
  [styles.button, style]
23
35
  );
24
36
  const content = useMemo(() => {
25
- if (props.loading) {
26
- return /* @__PURE__ */ jsx(ActivityIndicator, { color: styles.text.color });
37
+ if (loading) {
38
+ return /* @__PURE__ */ jsx(Spinner, { accessible: false, color: styles.text.color, size });
27
39
  }
28
40
  return typeof children === "string" ? /* @__PURE__ */ jsx(Typography.Master, { style: styles.text, children }) : children;
29
- }, [children, props.loading, styles.text]);
30
- return /* @__PURE__ */ jsx(Pressable, { style: buttonStyles, disabled, ...props, children: content });
41
+ }, [children, loading, size, styles.text]);
42
+ return /* @__PURE__ */ jsx(
43
+ Pressable,
44
+ {
45
+ ...props,
46
+ accessibilityState: resolvedAccessibilityState,
47
+ disabled: interactionDisabled,
48
+ style: buttonStyles,
49
+ children: content
50
+ }
51
+ );
31
52
  });
32
53
  function themedStyles(theme, props) {
33
54
  const { size, variant, disabled } = props;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/atoms/button.tsx"],"sourcesContent":["import { memo, PropsWithChildren, useMemo } from \"react\";\nimport { ActivityIndicator, StyleSheet } from \"react-native\";\n\nimport { AppTheme, useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport { ButtonProps, ButtonThemeProps } from \"../../types\";\nimport { Pressable } from \"./pressable\";\nimport { Typography } from \"./typography\";\n\nexport const Button = memo(function Button({\n size = \"medium\",\n variant = \"filled\",\n disabled,\n children,\n style,\n ...props\n}: PropsWithChildren<ButtonProps>) {\n const styles = useThemedStyles(themedStyles, { size, variant, disabled }, [\n size,\n variant,\n disabled,\n ]);\n\n const buttonStyles = useMemo(\n () => [styles.button, style],\n [styles.button, style],\n );\n\n const content = useMemo(() => {\n if (props.loading) {\n return <ActivityIndicator color={styles.text.color} />;\n }\n\n return typeof children === \"string\" ? (\n <Typography.Master style={styles.text}>{children}</Typography.Master>\n ) : (\n children\n );\n }, [children, props.loading, styles.text]);\n\n return (\n <Pressable style={buttonStyles} disabled={disabled} {...props}>\n {content}\n </Pressable>\n );\n});\n\nfunction themedStyles(theme: AppTheme, props: ButtonThemeProps) {\n const { size, variant, disabled } = props;\n\n const buttonTokens = theme.components.button;\n const sizeTokens = buttonTokens.sizes[size];\n const variantTokens = buttonTokens.variants[variant];\n\n return StyleSheet.create({\n button: {\n alignItems: \"center\",\n justifyContent: \"center\",\n\n height: sizeTokens.height,\n paddingVertical: sizeTokens.paddingVertical,\n paddingHorizontal: sizeTokens.paddingHorizontal,\n\n borderWidth: buttonTokens.borderWidth,\n borderRadius: buttonTokens.borderRadius,\n\n borderColor: disabled\n ? variantTokens.disabledBorderColor\n : variantTokens.borderColor,\n\n backgroundColor: disabled\n ? variantTokens.disabledBackgroundColor\n : variantTokens.backgroundColor,\n },\n\n text: {\n width: \"100%\",\n textAlign: \"center\",\n\n fontSize: sizeTokens.fontSize,\n\n color: disabled ? variantTokens.disabledColor : variantTokens.color,\n },\n });\n}\n"],"mappings":"AA8Ba;AA9Bb,SAAS,MAAyB,eAAe;AACjD,SAAS,mBAAmB,kBAAkB;AAE9C,SAAmB,uBAAuB;AAG1C,SAAS,iBAAiB;AAC1B,SAAS,kBAAkB;AAEpB,MAAM,SAAS,KAAK,SAASA,QAAO;AAAA,EACzC,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAmC;AACjC,QAAM,SAAS,gBAAgB,cAAc,EAAE,MAAM,SAAS,SAAS,GAAG;AAAA,IACxE;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,eAAe;AAAA,IACnB,MAAM,CAAC,OAAO,QAAQ,KAAK;AAAA,IAC3B,CAAC,OAAO,QAAQ,KAAK;AAAA,EACvB;AAEA,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,MAAM,SAAS;AACjB,aAAO,oBAAC,qBAAkB,OAAO,OAAO,KAAK,OAAO;AAAA,IACtD;AAEA,WAAO,OAAO,aAAa,WACzB,oBAAC,WAAW,QAAX,EAAkB,OAAO,OAAO,MAAO,UAAS,IAEjD;AAAA,EAEJ,GAAG,CAAC,UAAU,MAAM,SAAS,OAAO,IAAI,CAAC;AAEzC,SACE,oBAAC,aAAU,OAAO,cAAc,UAAqB,GAAG,OACrD,mBACH;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB,OAAyB;AAC9D,QAAM,EAAE,MAAM,SAAS,SAAS,IAAI;AAEpC,QAAM,eAAe,MAAM,WAAW;AACtC,QAAM,aAAa,aAAa,MAAM,IAAI;AAC1C,QAAM,gBAAgB,aAAa,SAAS,OAAO;AAEnD,SAAO,WAAW,OAAO;AAAA,IACvB,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAEhB,QAAQ,WAAW;AAAA,MACnB,iBAAiB,WAAW;AAAA,MAC5B,mBAAmB,WAAW;AAAA,MAE9B,aAAa,aAAa;AAAA,MAC1B,cAAc,aAAa;AAAA,MAE3B,aAAa,WACT,cAAc,sBACd,cAAc;AAAA,MAElB,iBAAiB,WACb,cAAc,0BACd,cAAc;AAAA,IACpB;AAAA,IAEA,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,WAAW;AAAA,MAEX,UAAU,WAAW;AAAA,MAErB,OAAO,WAAW,cAAc,gBAAgB,cAAc;AAAA,IAChE;AAAA,EACF,CAAC;AACH;","names":["Button"]}
1
+ {"version":3,"sources":["../../../src/components/atoms/button.tsx"],"sourcesContent":["import type { AccessibilityState } from \"react-native\";\nimport { memo, PropsWithChildren, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport { AppTheme, useThemedStyles } from \"@impulse-ui-native/theme\";\n\nimport { ButtonProps, ButtonThemeProps } from \"../../types\";\nimport { Pressable } from \"./pressable\";\nimport { Spinner } from \"./spinner\";\nimport { Typography } from \"./typography\";\n\nexport const Button = memo(function Button({\n accessibilityState,\n size = \"medium\",\n variant = \"filled\",\n disabled,\n loading = false,\n children,\n style,\n ...props\n}: PropsWithChildren<ButtonProps>) {\n const styles = useThemedStyles(themedStyles, { size, variant, disabled }, [\n size,\n variant,\n disabled,\n ]);\n\n const interactionDisabled = disabled === true || loading;\n\n const resolvedAccessibilityState = useMemo<AccessibilityState>(\n () => ({\n ...accessibilityState,\n busy: loading,\n disabled: interactionDisabled,\n }),\n [accessibilityState, interactionDisabled, loading],\n );\n\n const buttonStyles = useMemo(\n () => [styles.button, style],\n [styles.button, style],\n );\n\n const content = useMemo(() => {\n if (loading) {\n return (\n <Spinner accessible={false} color={styles.text.color} size={size} />\n );\n }\n\n return typeof children === \"string\" ? (\n <Typography.Master style={styles.text}>{children}</Typography.Master>\n ) : (\n children\n );\n }, [children, loading, size, styles.text]);\n\n return (\n <Pressable\n {...props}\n accessibilityState={resolvedAccessibilityState}\n disabled={interactionDisabled}\n style={buttonStyles}\n >\n {content}\n </Pressable>\n );\n});\n\nfunction themedStyles(theme: AppTheme, props: ButtonThemeProps) {\n const { size, variant, disabled } = props;\n\n const buttonTokens = theme.components.button;\n const sizeTokens = buttonTokens.sizes[size];\n const variantTokens = buttonTokens.variants[variant];\n\n return StyleSheet.create({\n button: {\n alignItems: \"center\",\n justifyContent: \"center\",\n\n height: sizeTokens.height,\n paddingVertical: sizeTokens.paddingVertical,\n paddingHorizontal: sizeTokens.paddingHorizontal,\n\n borderWidth: buttonTokens.borderWidth,\n borderRadius: buttonTokens.borderRadius,\n\n borderColor: disabled\n ? variantTokens.disabledBorderColor\n : variantTokens.borderColor,\n\n backgroundColor: disabled\n ? variantTokens.disabledBackgroundColor\n : variantTokens.backgroundColor,\n },\n\n text: {\n width: \"100%\",\n textAlign: \"center\",\n\n fontSize: sizeTokens.fontSize,\n\n color: disabled ? variantTokens.disabledColor : variantTokens.color,\n },\n });\n}\n"],"mappings":"AA8CQ;AA7CR,SAAS,MAAyB,eAAe;AACjD,SAAS,kBAAkB;AAE3B,SAAmB,uBAAuB;AAG1C,SAAS,iBAAiB;AAC1B,SAAS,eAAe;AACxB,SAAS,kBAAkB;AAEpB,MAAM,SAAS,KAAK,SAASA,QAAO;AAAA,EACzC;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAmC;AACjC,QAAM,SAAS,gBAAgB,cAAc,EAAE,MAAM,SAAS,SAAS,GAAG;AAAA,IACxE;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,sBAAsB,aAAa,QAAQ;AAEjD,QAAM,6BAA6B;AAAA,IACjC,OAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,CAAC,oBAAoB,qBAAqB,OAAO;AAAA,EACnD;AAEA,QAAM,eAAe;AAAA,IACnB,MAAM,CAAC,OAAO,QAAQ,KAAK;AAAA,IAC3B,CAAC,OAAO,QAAQ,KAAK;AAAA,EACvB;AAEA,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,SAAS;AACX,aACE,oBAAC,WAAQ,YAAY,OAAO,OAAO,OAAO,KAAK,OAAO,MAAY;AAAA,IAEtE;AAEA,WAAO,OAAO,aAAa,WACzB,oBAAC,WAAW,QAAX,EAAkB,OAAO,OAAO,MAAO,UAAS,IAEjD;AAAA,EAEJ,GAAG,CAAC,UAAU,SAAS,MAAM,OAAO,IAAI,CAAC;AAEzC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,oBAAoB;AAAA,MACpB,UAAU;AAAA,MACV,OAAO;AAAA,MAEN;AAAA;AAAA,EACH;AAEJ,CAAC;AAED,SAAS,aAAa,OAAiB,OAAyB;AAC9D,QAAM,EAAE,MAAM,SAAS,SAAS,IAAI;AAEpC,QAAM,eAAe,MAAM,WAAW;AACtC,QAAM,aAAa,aAAa,MAAM,IAAI;AAC1C,QAAM,gBAAgB,aAAa,SAAS,OAAO;AAEnD,SAAO,WAAW,OAAO;AAAA,IACvB,QAAQ;AAAA,MACN,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAEhB,QAAQ,WAAW;AAAA,MACnB,iBAAiB,WAAW;AAAA,MAC5B,mBAAmB,WAAW;AAAA,MAE9B,aAAa,aAAa;AAAA,MAC1B,cAAc,aAAa;AAAA,MAE3B,aAAa,WACT,cAAc,sBACd,cAAc;AAAA,MAElB,iBAAiB,WACb,cAAc,0BACd,cAAc;AAAA,IACpB;AAAA,IAEA,MAAM;AAAA,MACJ,OAAO;AAAA,MACP,WAAW;AAAA,MAEX,UAAU,WAAW;AAAA,MAErB,OAAO,WAAW,cAAc,gBAAgB,cAAc;AAAA,IAChE;AAAA,EACF,CAAC;AACH;","names":["Button"]}
@@ -0,0 +1,16 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { ViewProps, ColorValue } from 'react-native';
4
+
5
+ interface CircularProgressProps extends ViewProps {
6
+ animationDuration: number;
7
+ fraction: number;
8
+ indicatorColor: ColorValue;
9
+ indeterminate: boolean;
10
+ strokeWidth: number;
11
+ trackColor: ColorValue;
12
+ width: number;
13
+ }
14
+ declare const CircularProgress: react.MemoExoticComponent<({ animationDuration, fraction, indicatorColor, indeterminate, strokeWidth, style, trackColor, width, ...props }: CircularProgressProps) => react_jsx_runtime.JSX.Element>;
15
+
16
+ export { CircularProgress };
@@ -0,0 +1,144 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { memo, useMemo } from "react";
3
+ import { Animated, StyleSheet, View } from "react-native";
4
+ import Svg, { Circle, G } from "react-native-svg";
5
+ import { useIndeterminateProgressAnimation } from "../../hooks/use-indeterminate-progress-animation.hook";
6
+ const CircularProgress = memo(function CircularProgress2({
7
+ animationDuration,
8
+ fraction,
9
+ indicatorColor,
10
+ indeterminate,
11
+ strokeWidth,
12
+ style,
13
+ trackColor,
14
+ width,
15
+ ...props
16
+ }) {
17
+ const rootStyle = useMemo(
18
+ () => [styles.root, { height: width, width }, style],
19
+ [style, width]
20
+ );
21
+ return /* @__PURE__ */ jsx(View, { ...props, style: rootStyle, children: indeterminate ? /* @__PURE__ */ jsx(
22
+ CircularIndeterminateIndicator,
23
+ {
24
+ animationDuration,
25
+ color: indicatorColor,
26
+ strokeWidth,
27
+ trackColor,
28
+ width
29
+ }
30
+ ) : /* @__PURE__ */ jsx(
31
+ ProgressCircle,
32
+ {
33
+ color: indicatorColor,
34
+ fraction,
35
+ strokeWidth,
36
+ trackColor,
37
+ width
38
+ }
39
+ ) });
40
+ });
41
+ const ProgressCircle = memo(function ProgressCircle2({
42
+ color,
43
+ fraction,
44
+ strokeWidth,
45
+ trackColor,
46
+ width
47
+ }) {
48
+ const center = width / 2;
49
+ const radius = (width - strokeWidth) / 2;
50
+ const circumference = 2 * Math.PI * radius;
51
+ const strokeDasharray = useMemo(
52
+ () => [circumference, circumference],
53
+ [circumference]
54
+ );
55
+ return /* @__PURE__ */ jsxs(Svg, { accessible: false, height: width, width, children: [
56
+ /* @__PURE__ */ jsx(
57
+ Circle,
58
+ {
59
+ cx: center,
60
+ cy: center,
61
+ fill: "none",
62
+ r: radius,
63
+ stroke: trackColor,
64
+ strokeWidth
65
+ }
66
+ ),
67
+ /* @__PURE__ */ jsx(G, { origin: `${center}, ${center}`, rotation: -90, children: /* @__PURE__ */ jsx(
68
+ Circle,
69
+ {
70
+ cx: center,
71
+ cy: center,
72
+ fill: "none",
73
+ r: radius,
74
+ stroke: color,
75
+ strokeDasharray,
76
+ strokeDashoffset: circumference * (1 - fraction),
77
+ strokeLinecap: fraction === 0 ? "butt" : "round",
78
+ strokeWidth
79
+ }
80
+ ) })
81
+ ] });
82
+ });
83
+ const CircularIndeterminateIndicator = memo(
84
+ function CircularIndeterminateIndicator2({
85
+ animationDuration,
86
+ color,
87
+ strokeWidth,
88
+ trackColor,
89
+ width
90
+ }) {
91
+ const progress = useIndeterminateProgressAnimation(animationDuration);
92
+ const rotation = progress.interpolate({
93
+ inputRange: [0, 1],
94
+ outputRange: ["0deg", "360deg"]
95
+ });
96
+ const center = width / 2;
97
+ const radius = (width - strokeWidth) / 2;
98
+ const circumference = 2 * Math.PI * radius;
99
+ const animatedStyle = useMemo(
100
+ () => ({ transform: [{ rotate: rotation }] }),
101
+ [rotation]
102
+ );
103
+ const strokeDasharray = useMemo(
104
+ () => [circumference * 0.25, circumference * 0.75],
105
+ [circumference]
106
+ );
107
+ return /* @__PURE__ */ jsx(Animated.View, { style: animatedStyle, children: /* @__PURE__ */ jsxs(Svg, { accessible: false, height: width, width, children: [
108
+ /* @__PURE__ */ jsx(
109
+ Circle,
110
+ {
111
+ cx: center,
112
+ cy: center,
113
+ fill: "none",
114
+ r: radius,
115
+ stroke: trackColor,
116
+ strokeWidth
117
+ }
118
+ ),
119
+ /* @__PURE__ */ jsx(
120
+ Circle,
121
+ {
122
+ cx: center,
123
+ cy: center,
124
+ fill: "none",
125
+ r: radius,
126
+ stroke: color,
127
+ strokeDasharray,
128
+ strokeLinecap: "round",
129
+ strokeWidth
130
+ }
131
+ )
132
+ ] }) });
133
+ }
134
+ );
135
+ const styles = StyleSheet.create({
136
+ root: {
137
+ alignItems: "center",
138
+ justifyContent: "center"
139
+ }
140
+ });
141
+ export {
142
+ CircularProgress
143
+ };
144
+ //# sourceMappingURL=circular-progress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/atoms/circular-progress.tsx"],"sourcesContent":["import type { ColorValue, ViewProps } from \"react-native\";\nimport { memo, useMemo } from \"react\";\nimport { Animated, StyleSheet, View } from \"react-native\";\nimport Svg, { Circle, G } from \"react-native-svg\";\n\nimport { useIndeterminateProgressAnimation } from \"../../hooks/use-indeterminate-progress-animation.hook\";\n\ninterface CircularProgressProps extends ViewProps {\n animationDuration: number;\n fraction: number;\n indicatorColor: ColorValue;\n indeterminate: boolean;\n strokeWidth: number;\n trackColor: ColorValue;\n width: number;\n}\n\nexport const CircularProgress = memo(function CircularProgress({\n animationDuration,\n fraction,\n indicatorColor,\n indeterminate,\n strokeWidth,\n style,\n trackColor,\n width,\n ...props\n}: CircularProgressProps) {\n const rootStyle = useMemo(\n () => [styles.root, { height: width, width }, style],\n [style, width],\n );\n\n return (\n <View {...props} style={rootStyle}>\n {indeterminate ? (\n <CircularIndeterminateIndicator\n animationDuration={animationDuration}\n color={indicatorColor}\n strokeWidth={strokeWidth}\n trackColor={trackColor}\n width={width}\n />\n ) : (\n <ProgressCircle\n color={indicatorColor}\n fraction={fraction}\n strokeWidth={strokeWidth}\n trackColor={trackColor}\n width={width}\n />\n )}\n </View>\n );\n});\n\ninterface ProgressCircleProps {\n color: ColorValue;\n fraction: number;\n strokeWidth: number;\n trackColor: ColorValue;\n width: number;\n}\n\nconst ProgressCircle = memo(function ProgressCircle({\n color,\n fraction,\n strokeWidth,\n trackColor,\n width,\n}: ProgressCircleProps) {\n const center = width / 2;\n const radius = (width - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n const strokeDasharray = useMemo(\n () => [circumference, circumference],\n [circumference],\n );\n\n return (\n <Svg accessible={false} height={width} width={width}>\n <Circle\n cx={center}\n cy={center}\n fill=\"none\"\n r={radius}\n stroke={trackColor}\n strokeWidth={strokeWidth}\n />\n <G origin={`${center}, ${center}`} rotation={-90}>\n <Circle\n cx={center}\n cy={center}\n fill=\"none\"\n r={radius}\n stroke={color}\n strokeDasharray={strokeDasharray}\n strokeDashoffset={circumference * (1 - fraction)}\n strokeLinecap={fraction === 0 ? \"butt\" : \"round\"}\n strokeWidth={strokeWidth}\n />\n </G>\n </Svg>\n );\n});\n\ninterface CircularIndeterminateIndicatorProps {\n animationDuration: number;\n color: ColorValue;\n strokeWidth: number;\n trackColor: ColorValue;\n width: number;\n}\n\nconst CircularIndeterminateIndicator = memo(\n function CircularIndeterminateIndicator({\n animationDuration,\n color,\n strokeWidth,\n trackColor,\n width,\n }: CircularIndeterminateIndicatorProps) {\n const progress = useIndeterminateProgressAnimation(animationDuration);\n const rotation = progress.interpolate({\n inputRange: [0, 1],\n outputRange: [\"0deg\", \"360deg\"],\n });\n const center = width / 2;\n const radius = (width - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n const animatedStyle = useMemo(\n () => ({ transform: [{ rotate: rotation }] }),\n [rotation],\n );\n const strokeDasharray = useMemo(\n () => [circumference * 0.25, circumference * 0.75],\n [circumference],\n );\n\n return (\n <Animated.View style={animatedStyle}>\n <Svg accessible={false} height={width} width={width}>\n <Circle\n cx={center}\n cy={center}\n fill=\"none\"\n r={radius}\n stroke={trackColor}\n strokeWidth={strokeWidth}\n />\n <Circle\n cx={center}\n cy={center}\n fill=\"none\"\n r={radius}\n stroke={color}\n strokeDasharray={strokeDasharray}\n strokeLinecap=\"round\"\n strokeWidth={strokeWidth}\n />\n </Svg>\n </Animated.View>\n );\n },\n);\n\nconst styles = StyleSheet.create({\n root: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n});\n"],"mappings":"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","names":["CircularProgress","ProgressCircle","CircularIndeterminateIndicator"]}
@@ -0,0 +1,10 @@
1
+ import * as react from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+ import { DividerProps } from '../../types/divider.types.mjs';
4
+ import 'react-native';
5
+ import '@impulse-ui-native/theme';
6
+ import '../../types/view.types.mjs';
7
+
8
+ declare const Divider: react.MemoExoticComponent<({ accessible, color, inset, orientation, role, style, tone, ...props }: DividerProps) => react_jsx_runtime.JSX.Element>;
9
+
10
+ export { Divider };
@@ -0,0 +1,48 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { memo, useMemo } from "react";
3
+ import { StyleSheet } from "react-native";
4
+ import { useComponentsTokens, useStyleProps } from "@impulse-ui-native/theme";
5
+ import { View } from "./view";
6
+ const Divider = memo(function Divider2({
7
+ accessible = true,
8
+ color,
9
+ inset = "none",
10
+ orientation = "horizontal",
11
+ role = "separator",
12
+ style,
13
+ tone = "subtle",
14
+ ...props
15
+ }) {
16
+ const tokens = useComponentsTokens().divider;
17
+ const extractedStyleProps = useStyleProps(props);
18
+ const dividerStyle = useMemo(() => {
19
+ const insetStart = inset === "start" || inset === "both";
20
+ const insetEnd = inset === "end" || inset === "both";
21
+ return StyleSheet.flatten([
22
+ styles.base,
23
+ orientation === "horizontal" ? {
24
+ height: tokens.thickness,
25
+ marginEnd: insetEnd ? tokens.inset : 0,
26
+ marginStart: insetStart ? tokens.inset : 0
27
+ } : {
28
+ marginBottom: insetEnd ? tokens.inset : 0,
29
+ marginTop: insetStart ? tokens.inset : 0,
30
+ width: tokens.thickness
31
+ },
32
+ { backgroundColor: color ?? tokens.colors[tone] },
33
+ extractedStyleProps,
34
+ style
35
+ ]);
36
+ }, [color, extractedStyleProps, inset, orientation, style, tone, tokens]);
37
+ return /* @__PURE__ */ jsx(View, { ...props, accessible, role, style: dividerStyle });
38
+ });
39
+ const styles = StyleSheet.create({
40
+ base: {
41
+ alignSelf: "stretch",
42
+ flexShrink: 0
43
+ }
44
+ });
45
+ export {
46
+ Divider
47
+ };
48
+ //# sourceMappingURL=divider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/atoms/divider.tsx"],"sourcesContent":["import { memo, useMemo } from \"react\";\nimport { StyleSheet } from \"react-native\";\n\nimport { useComponentsTokens, useStyleProps } from \"@impulse-ui-native/theme\";\n\nimport type { DividerProps } from \"../../types\";\nimport { View } from \"./view\";\n\nexport const Divider = memo(function Divider({\n accessible = true,\n color,\n inset = \"none\",\n orientation = \"horizontal\",\n role = \"separator\",\n style,\n tone = \"subtle\",\n ...props\n}: DividerProps) {\n const tokens = useComponentsTokens().divider;\n const extractedStyleProps = useStyleProps(props);\n\n const dividerStyle = useMemo(() => {\n const insetStart = inset === \"start\" || inset === \"both\";\n const insetEnd = inset === \"end\" || inset === \"both\";\n\n return StyleSheet.flatten([\n styles.base,\n orientation === \"horizontal\"\n ? {\n height: tokens.thickness,\n marginEnd: insetEnd ? tokens.inset : 0,\n marginStart: insetStart ? tokens.inset : 0,\n }\n : {\n marginBottom: insetEnd ? tokens.inset : 0,\n marginTop: insetStart ? tokens.inset : 0,\n width: tokens.thickness,\n },\n { backgroundColor: color ?? tokens.colors[tone] },\n extractedStyleProps,\n style,\n ]);\n }, [color, extractedStyleProps, inset, orientation, style, tone, tokens]);\n\n return (\n <View {...props} accessible={accessible} role={role} style={dividerStyle} />\n );\n});\n\nconst styles = StyleSheet.create({\n base: {\n alignSelf: \"stretch\",\n flexShrink: 0,\n },\n});\n"],"mappings":"AA6CI;AA7CJ,SAAS,MAAM,eAAe;AAC9B,SAAS,kBAAkB;AAE3B,SAAS,qBAAqB,qBAAqB;AAGnD,SAAS,YAAY;AAEd,MAAM,UAAU,KAAK,SAASA,SAAQ;AAAA,EAC3C,aAAa;AAAA,EACb;AAAA,EACA,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,OAAO;AAAA,EACP;AAAA,EACA,OAAO;AAAA,EACP,GAAG;AACL,GAAiB;AACf,QAAM,SAAS,oBAAoB,EAAE;AACrC,QAAM,sBAAsB,cAAc,KAAK;AAE/C,QAAM,eAAe,QAAQ,MAAM;AACjC,UAAM,aAAa,UAAU,WAAW,UAAU;AAClD,UAAM,WAAW,UAAU,SAAS,UAAU;AAE9C,WAAO,WAAW,QAAQ;AAAA,MACxB,OAAO;AAAA,MACP,gBAAgB,eACZ;AAAA,QACE,QAAQ,OAAO;AAAA,QACf,WAAW,WAAW,OAAO,QAAQ;AAAA,QACrC,aAAa,aAAa,OAAO,QAAQ;AAAA,MAC3C,IACA;AAAA,QACE,cAAc,WAAW,OAAO,QAAQ;AAAA,QACxC,WAAW,aAAa,OAAO,QAAQ;AAAA,QACvC,OAAO,OAAO;AAAA,MAChB;AAAA,MACJ,EAAE,iBAAiB,SAAS,OAAO,OAAO,IAAI,EAAE;AAAA,MAChD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,OAAO,qBAAqB,OAAO,aAAa,OAAO,MAAM,MAAM,CAAC;AAExE,SACE,oBAAC,QAAM,GAAG,OAAO,YAAwB,MAAY,OAAO,cAAc;AAE9E,CAAC;AAED,MAAM,SAAS,WAAW,OAAO;AAAA,EAC/B,MAAM;AAAA,IACJ,WAAW;AAAA,IACX,YAAY;AAAA,EACd;AACF,CAAC;","names":["Divider"]}
@@ -7,6 +7,6 @@ import '@impulse-ui-native/theme';
7
7
  import '../../types/button.types.mjs';
8
8
  import 'react-native';
9
9
 
10
- declare const IconButton: react.MemoExoticComponent<({ size, variant, disabled, style, icon, ...props }: PropsWithChildren<IconButtonProps>) => react_jsx_runtime.JSX.Element>;
10
+ declare const IconButton: react.MemoExoticComponent<({ accessibilityState, size, variant, disabled, loading, style, icon, ...props }: PropsWithChildren<IconButtonProps>) => react_jsx_runtime.JSX.Element>;
11
11
 
12
12
  export { IconButton };