@lmb-it/kitsconcerto-native 0.1.252 → 0.1.254
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/components/Banner/banner.cjs +16 -6
- package/components/Banner/banner.cjs.map +1 -1
- package/components/Banner/banner.js +17 -7
- package/components/Banner/banner.js.map +1 -1
- package/components/BottomTabBar/index.cjs +3 -1
- package/components/BottomTabBar/index.cjs.map +1 -1
- package/components/BottomTabBar/index.js +3 -1
- package/components/BottomTabBar/index.js.map +1 -1
- package/components/Chip/index.cjs +13 -1
- package/components/Chip/index.cjs.map +1 -1
- package/components/Chip/index.js +13 -1
- package/components/Chip/index.js.map +1 -1
- package/components/MessageComposer/index.cjs +5 -2
- package/components/MessageComposer/index.cjs.map +1 -1
- package/components/MessageComposer/index.js +5 -2
- package/components/MessageComposer/index.js.map +1 -1
- package/components/TypingIndicator/index.cjs +3 -1
- package/components/TypingIndicator/index.cjs.map +1 -1
- package/components/TypingIndicator/index.js +3 -1
- package/components/TypingIndicator/index.js.map +1 -1
- package/hooks/useSeverityColors.cjs +14 -18
- package/hooks/useSeverityColors.cjs.map +1 -1
- package/hooks/useSeverityColors.js +14 -18
- package/hooks/useSeverityColors.js.map +1 -1
- package/index.d.ts +34 -0
- package/locale/ar.json.cjs +4 -1
- package/locale/ar.json.cjs.map +1 -1
- package/locale/ar.json.js +4 -2
- package/locale/ar.json.js.map +1 -1
- package/locale/en.json.cjs +4 -1
- package/locale/en.json.cjs.map +1 -1
- package/locale/en.json.js +4 -2
- package/locale/en.json.js.map +1 -1
- package/package.json +1 -1
- package/primitives/Divider/index.cjs +3 -1
- package/primitives/Divider/index.cjs.map +1 -1
- package/primitives/Divider/index.js +3 -1
- package/primitives/Divider/index.js.map +1 -1
- package/primitives/Text/index.cjs +6 -2
- package/primitives/Text/index.cjs.map +1 -1
- package/primitives/Text/index.js +6 -2
- package/primitives/Text/index.js.map +1 -1
|
@@ -5,6 +5,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var lucideReactNative = require('lucide-react-native');
|
|
7
7
|
var useSeverityColors = require('../../hooks/useSeverityColors.cjs');
|
|
8
|
+
require('react');
|
|
9
|
+
var locale = require('../../hooks/locale.cjs');
|
|
10
|
+
require('../../contexts/DialogContext.cjs');
|
|
8
11
|
var reactNative = require('react-native');
|
|
9
12
|
var KitsThemeProvider_native = require('../../contexts/Theme/KitsThemeProvider.cjs');
|
|
10
13
|
var index_native = require('../../primitives/Icon/index.cjs');
|
|
@@ -32,16 +35,19 @@ const Banner = ({
|
|
|
32
35
|
onDismiss,
|
|
33
36
|
children,
|
|
34
37
|
className,
|
|
35
|
-
textDirection
|
|
38
|
+
textDirection
|
|
36
39
|
}) => {
|
|
37
40
|
const { theme } = KitsThemeProvider_native.useKitsTheme();
|
|
41
|
+
const { t, isRTL, isKeyExists } = locale.useLanguage();
|
|
38
42
|
const hasActions = actions.length > 0;
|
|
39
43
|
const status = statusProp ?? (hasActions ? "error" : "info");
|
|
40
44
|
const sev = useSeverityColors.useSeverityColors(statusToSeverity(status));
|
|
41
|
-
const
|
|
45
|
+
const actionRequiredLabel = isKeyExists?.("actionRequired") ? t("actionRequired") : "Action required";
|
|
46
|
+
const computedHeaderTitle = hasActions ? headerTitle ?? `${actionRequiredLabel}${actions.length > 1 ? ` (${actions.length})` : ""}` : headerTitle;
|
|
42
47
|
const hasHeader = !!computedHeaderTitle;
|
|
43
48
|
const hasBody = !!(title || description || children);
|
|
44
|
-
const
|
|
49
|
+
const resolvedDirection = textDirection ?? (isRTL ? "rtl" : "ltr");
|
|
50
|
+
const rowDirection = resolvedDirection === "rtl" ? "row-reverse" : "row";
|
|
45
51
|
const headerIconNode = (() => {
|
|
46
52
|
if (!headerIcon) return null;
|
|
47
53
|
if (status === "brand" && theme.config.logo) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: theme.config.logo });
|
|
@@ -97,7 +103,11 @@ const Banner = ({
|
|
|
97
103
|
borderRadius: 999,
|
|
98
104
|
paddingHorizontal: 12,
|
|
99
105
|
paddingVertical: 7,
|
|
100
|
-
|
|
106
|
+
// ⛔ `rowDirection`, NOT a hardcoded "row". This was the
|
|
107
|
+
// one row in the component that ignored the direction
|
|
108
|
+
// every other row obeyed, so even a caller that DID
|
|
109
|
+
// pass textDirection="rtl" got this pill backwards.
|
|
110
|
+
flexDirection: rowDirection,
|
|
101
111
|
alignItems: "center",
|
|
102
112
|
gap: 4,
|
|
103
113
|
flexShrink: 0
|
|
@@ -112,7 +122,7 @@ const Banner = ({
|
|
|
112
122
|
children: bannerAction.cta
|
|
113
123
|
}
|
|
114
124
|
),
|
|
115
|
-
/* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ArrowRight, { size: 12, color: sev.solidText })
|
|
125
|
+
resolvedDirection === "rtl" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ArrowLeft, { size: 12, color: sev.solidText }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReactNative.ArrowRight, { size: 12, color: sev.solidText })
|
|
116
126
|
]
|
|
117
127
|
}
|
|
118
128
|
)
|
|
@@ -128,7 +138,7 @@ const Banner = ({
|
|
|
128
138
|
style: {
|
|
129
139
|
borderRadius: 8,
|
|
130
140
|
overflow: "hidden",
|
|
131
|
-
writingDirection:
|
|
141
|
+
writingDirection: resolvedDirection
|
|
132
142
|
},
|
|
133
143
|
children: [
|
|
134
144
|
hasHeader && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.cjs","sources":["../../../../src/components/Banner/banner.native.tsx"],"sourcesContent":["import React from \"react\";\nimport { Flex, Text, Icon } from \"../../_compat\";\nimport {\n AlertTriangle,\n ArrowRight,\n CheckCircle2,\n Info,\n CircleX,\n X,\n} from \"lucide-react-native\";\nimport { useSeverityColors } from \"../../hooks/useSeverityColors\";\nimport { useKitsTheme } from \"../../contexts/Theme\";\nimport type { BannerAction, IBannerProps, BannerStatus } from \"@lmb-it/kitsconcerto-types\";\nimport type { Severity } from \"@lmb-it/kitsconcerto-types\";\nimport { Pressable } from \"react-native\";\n\nconst icons: Record<string, any> = {\n error: CircleX,\n success: CheckCircle2,\n warning: AlertTriangle,\n info: Info,\n};\n\nfunction statusToSeverity(status: BannerStatus): Severity {\n if (status === \"error\") return \"danger\";\n return status;\n}\n\nconst Banner: React.FC<IBannerProps> = ({\n status: statusProp,\n headerTitle,\n headerIcon = true,\n title,\n description,\n withIcon = true,\n actions = [],\n onDismiss,\n children,\n className,\n textDirection = \"ltr\",\n}) => {\n const { theme } = useKitsTheme();\n const hasActions = actions.length > 0;\n const status = statusProp ?? (hasActions ? \"error\" : \"info\");\n const sev = useSeverityColors(statusToSeverity(status));\n const computedHeaderTitle = hasActions\n ? `Action required${actions.length > 1 ? ` (${actions.length})` : \"\"}`\n : headerTitle;\n const hasHeader = !!computedHeaderTitle;\n const hasBody = !!(title || description || children);\n const rowDirection = textDirection === \"rtl\" ? \"row-reverse\" : \"row\";\n\n const headerIconNode = (() => {\n if (!headerIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n if (hasActions) return <Icon name={AlertTriangle} color={sev.solidText} size=\"sm\" />;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.solidText} size=\"sm\" /> : null;\n })();\n\n const bodyIconNode = (() => {\n if (!withIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.iconFg} size=\"sm\" /> : null;\n })();\n\n const renderActionRow = (bannerAction: BannerAction, index: number) => (\n <Flex\n key={bannerAction.id}\n flexDirection={rowDirection}\n alignItems=\"flex-start\"\n gap={10}\n style={{\n padding: 12,\n borderTopWidth: index > 0 ? 1 : 0,\n borderTopColor: sev.border,\n }}\n >\n <Flex\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 8,\n backgroundColor: \"#fff\",\n borderWidth: 1,\n borderColor: sev.border,\n flexShrink: 0,\n }}\n >\n {bannerAction.icon ?? <Icon name={AlertTriangle} color={sev.iconFg} size=\"sm\" />}\n </Flex>\n <Flex flexDirection=\"column\" gap={2} style={{ flex: 1 }}>\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {bannerAction.label}\n </Text>\n {bannerAction.detail && (\n <Text size=\"xs\" style={{ color: sev.text, lineHeight: 17 }}>\n {bannerAction.detail}\n </Text>\n )}\n </Flex>\n {bannerAction.cta && (\n <Pressable\n onPress={bannerAction.onCta}\n style={{\n backgroundColor: sev.solid,\n borderRadius: 999,\n paddingHorizontal: 12,\n paddingVertical: 7,\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 4,\n flexShrink: 0,\n }}\n >\n <Text\n fontWeight=\"bold\"\n size=\"xs\"\n style={{ color: sev.solidText }}\n >\n {bannerAction.cta}\n </Text>\n <ArrowRight size={12} color={sev.solidText} />\n </Pressable>\n )}\n </Flex>\n );\n\n return (\n <Flex\n flexDirection=\"column\"\n className={className}\n style={{\n borderRadius: 8,\n overflow: \"hidden\",\n writingDirection: textDirection,\n }}\n >\n {/* Header bar */}\n {hasHeader && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={6}\n style={{\n backgroundColor: sev.solid,\n paddingVertical: 8,\n paddingHorizontal: 12,\n }}\n >\n {headerIconNode}\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.solidText, flex: 1 }}>\n {computedHeaderTitle}\n </Text>\n {onDismiss && (\n <Pressable\n accessibilityLabel=\"Dismiss\"\n onPress={onDismiss}\n style={{\n width: 24,\n height: 24,\n borderRadius: 999,\n backgroundColor: \"rgba(255, 255, 255, 0.2)\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <X size={14} color={sev.solidText} />\n </Pressable>\n )}\n </Flex>\n )}\n\n {/* Body section */}\n {hasActions ? (\n <Flex\n flexDirection=\"column\"\n style={{\n backgroundColor: sev.bgTint,\n }}\n >\n {actions.map(renderActionRow)}\n </Flex>\n ) : hasBody && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={12}\n style={{\n backgroundColor: sev.bgTint,\n padding: 12,\n justifyContent: \"space-between\",\n }}\n >\n <Flex flexDirection=\"column\" gap={4} style={{ flex: 1 }}>\n {(withIcon || title) && (\n <Flex flexDirection={rowDirection} alignItems=\"center\" gap={6}>\n {bodyIconNode}\n {title && (\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {title}\n </Text>\n )}\n </Flex>\n )}\n {description && (\n <Text size=\"xs\" style={{ color: sev.text }}>\n {description}\n </Text>\n )}\n {children}\n </Flex>\n </Flex>\n )}\n </Flex>\n );\n};\n\nexport default Banner;\n"],"names":["CircleX","CheckCircle2","AlertTriangle","Info","useKitsTheme","useSeverityColors","jsx","Fragment","Icon","index","jsxs","Flex","Text","Pressable","ArrowRight","X"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"banner.cjs","sources":["../../../../src/components/Banner/banner.native.tsx"],"sourcesContent":["import React from \"react\";\nimport { Flex, Text, Icon } from \"../../_compat\";\nimport {\n AlertTriangle,\n ArrowLeft,\n ArrowRight,\n CheckCircle2,\n Info,\n CircleX,\n X,\n} from \"lucide-react-native\";\nimport { useSeverityColors } from \"../../hooks/useSeverityColors\";\nimport { useKitsTheme } from \"../../contexts/Theme\";\nimport { useLanguage } from \"../../hooks\";\nimport type { BannerAction, IBannerProps, BannerStatus } from \"@lmb-it/kitsconcerto-types\";\nimport type { Severity } from \"@lmb-it/kitsconcerto-types\";\nimport { Pressable } from \"react-native\";\n\nconst icons: Record<string, any> = {\n error: CircleX,\n success: CheckCircle2,\n warning: AlertTriangle,\n info: Info,\n};\n\nfunction statusToSeverity(status: BannerStatus): Severity {\n if (status === \"error\") return \"danger\";\n return status;\n}\n\nconst Banner: React.FC<IBannerProps> = ({\n status: statusProp,\n headerTitle,\n headerIcon = true,\n title,\n description,\n withIcon = true,\n actions = [],\n onDismiss,\n children,\n className,\n textDirection,\n}) => {\n const { theme } = useKitsTheme();\n const { t, isRTL, isKeyExists } = useLanguage();\n const hasActions = actions.length > 0;\n const status = statusProp ?? (hasActions ? \"error\" : \"info\");\n const sev = useSeverityColors(statusToSeverity(status));\n\n /*\n * ⛔ THE HEADING IS THE CONSUMER'S TO WRITE. This read\n * `hasActions ? \"Action required…\" : headerTitle`, so a caller that passed\n * a translated `headerTitle` AND any actions had it thrown away and an\n * ENGLISH LITERAL rendered instead — with no prop, theme value or locale\n * key able to reach it.\n *\n * ⛔ FOUND IN AN ARABIC APP, 19 September 2026: AlphaMatch's Me tab showed\n * \"Action required\" in English on an otherwise fully Arabic screen, while\n * the app's OWN translated string for it sat unused one call away. Grepping\n * the app for the English text finds only its locale file, which is exactly\n * why it reads as an app bug and is not one.\n *\n * ⚠️ THE FALLBACK IS LOCALISED, BUT ONLY WHERE A TRANSLATION EXISTS.\n * `isKeyExists` is checked first so a language without the key keeps\n * today's English rather than rendering the raw key at a user — 38 of this\n * library's 40 locale files have not been given this string, and a visible\n * `actionRequired` would be a worse defect than the one being fixed.\n *\n * ⚠️ THE COUNT SUFFIX BELONGS TO THE FALLBACK, NOT TO THE CONSUMER. A title\n * someone wrote is a complete sentence; appending \"(3)\" to it is the\n * library talking over them.\n */\n const actionRequiredLabel = isKeyExists?.(\"actionRequired\")\n ? t(\"actionRequired\")\n : \"Action required\";\n const computedHeaderTitle = hasActions\n ? headerTitle ??\n `${actionRequiredLabel}${actions.length > 1 ? ` (${actions.length})` : \"\"}`\n : headerTitle;\n\n const hasHeader = !!computedHeaderTitle;\n const hasBody = !!(title || description || children);\n\n /*\n * ⛔ THE DIRECTION DEFAULTS TO THE ACTIVE LANGUAGE, NOT TO ENGLISH. This\n * prop defaulted to `\"ltr\"`, so every caller that did not pass it — which\n * was all of them — got a left-to-right banner in an Arabic app, and none\n * of them could find out. A library shipping to an RTL product reads the\n * direction itself; the prop stays, for the caller that needs to override.\n */\n const resolvedDirection = textDirection ?? (isRTL ? \"rtl\" : \"ltr\");\n const rowDirection = resolvedDirection === \"rtl\" ? \"row-reverse\" : \"row\";\n\n const headerIconNode = (() => {\n if (!headerIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n if (hasActions) return <Icon name={AlertTriangle} color={sev.solidText} size=\"sm\" />;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.solidText} size=\"sm\" /> : null;\n })();\n\n const bodyIconNode = (() => {\n if (!withIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.iconFg} size=\"sm\" /> : null;\n })();\n\n const renderActionRow = (bannerAction: BannerAction, index: number) => (\n <Flex\n key={bannerAction.id}\n flexDirection={rowDirection}\n alignItems=\"flex-start\"\n gap={10}\n style={{\n padding: 12,\n borderTopWidth: index > 0 ? 1 : 0,\n borderTopColor: sev.border,\n }}\n >\n <Flex\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 8,\n backgroundColor: \"#fff\",\n borderWidth: 1,\n borderColor: sev.border,\n flexShrink: 0,\n }}\n >\n {bannerAction.icon ?? <Icon name={AlertTriangle} color={sev.iconFg} size=\"sm\" />}\n </Flex>\n <Flex flexDirection=\"column\" gap={2} style={{ flex: 1 }}>\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {bannerAction.label}\n </Text>\n {bannerAction.detail && (\n <Text size=\"xs\" style={{ color: sev.text, lineHeight: 17 }}>\n {bannerAction.detail}\n </Text>\n )}\n </Flex>\n {bannerAction.cta && (\n <Pressable\n onPress={bannerAction.onCta}\n style={{\n backgroundColor: sev.solid,\n borderRadius: 999,\n paddingHorizontal: 12,\n paddingVertical: 7,\n // ⛔ `rowDirection`, NOT a hardcoded \"row\". This was the\n // one row in the component that ignored the direction\n // every other row obeyed, so even a caller that DID\n // pass textDirection=\"rtl\" got this pill backwards.\n flexDirection: rowDirection,\n alignItems: \"center\",\n gap: 4,\n flexShrink: 0,\n }}\n >\n <Text\n fontWeight=\"bold\"\n size=\"xs\"\n style={{ color: sev.solidText }}\n >\n {bannerAction.cta}\n </Text>\n {/* ⛔ THE ARROW MEANS \"ONWARDS\", SO IT FOLLOWS THE READER.\n It was always ArrowRight, which in Arabic points back\n the way the eye came — on the one control the banner\n exists to get pressed. */}\n {resolvedDirection === \"rtl\" ? (\n <ArrowLeft size={12} color={sev.solidText} />\n ) : (\n <ArrowRight size={12} color={sev.solidText} />\n )}\n </Pressable>\n )}\n </Flex>\n );\n\n return (\n <Flex\n flexDirection=\"column\"\n className={className}\n style={{\n borderRadius: 8,\n overflow: \"hidden\",\n writingDirection: resolvedDirection,\n }}\n >\n {/* Header bar */}\n {hasHeader && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={6}\n style={{\n backgroundColor: sev.solid,\n paddingVertical: 8,\n paddingHorizontal: 12,\n }}\n >\n {headerIconNode}\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.solidText, flex: 1 }}>\n {computedHeaderTitle}\n </Text>\n {onDismiss && (\n <Pressable\n accessibilityLabel=\"Dismiss\"\n onPress={onDismiss}\n style={{\n width: 24,\n height: 24,\n borderRadius: 999,\n backgroundColor: \"rgba(255, 255, 255, 0.2)\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <X size={14} color={sev.solidText} />\n </Pressable>\n )}\n </Flex>\n )}\n\n {/* Body section */}\n {hasActions ? (\n <Flex\n flexDirection=\"column\"\n style={{\n backgroundColor: sev.bgTint,\n }}\n >\n {actions.map(renderActionRow)}\n </Flex>\n ) : hasBody && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={12}\n style={{\n backgroundColor: sev.bgTint,\n padding: 12,\n justifyContent: \"space-between\",\n }}\n >\n <Flex flexDirection=\"column\" gap={4} style={{ flex: 1 }}>\n {(withIcon || title) && (\n <Flex flexDirection={rowDirection} alignItems=\"center\" gap={6}>\n {bodyIconNode}\n {title && (\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {title}\n </Text>\n )}\n </Flex>\n )}\n {description && (\n <Text size=\"xs\" style={{ color: sev.text }}>\n {description}\n </Text>\n )}\n {children}\n </Flex>\n </Flex>\n )}\n </Flex>\n );\n};\n\nexport default Banner;\n"],"names":["CircleX","CheckCircle2","AlertTriangle","Info","useKitsTheme","useLanguage","useSeverityColors","jsx","Fragment","Icon","index","jsxs","Flex","Text","Pressable","ArrowLeft","ArrowRight","X"],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
2
|
-
import { AlertTriangle, Info, CheckCircle2, CircleX, X, ArrowRight } from 'lucide-react-native';
|
|
2
|
+
import { AlertTriangle, Info, CheckCircle2, CircleX, X, ArrowLeft, ArrowRight } from 'lucide-react-native';
|
|
3
3
|
import { useSeverityColors } from '../../hooks/useSeverityColors.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
import { useLanguage } from '../../hooks/locale.js';
|
|
6
|
+
import '../../contexts/DialogContext.js';
|
|
4
7
|
import { Pressable } from 'react-native';
|
|
5
8
|
import { useKitsTheme } from '../../contexts/Theme/KitsThemeProvider.js';
|
|
6
9
|
import { Icon } from '../../primitives/Icon/index.js';
|
|
@@ -28,16 +31,19 @@ const Banner = ({
|
|
|
28
31
|
onDismiss,
|
|
29
32
|
children,
|
|
30
33
|
className,
|
|
31
|
-
textDirection
|
|
34
|
+
textDirection
|
|
32
35
|
}) => {
|
|
33
36
|
const { theme } = useKitsTheme();
|
|
37
|
+
const { t, isRTL, isKeyExists } = useLanguage();
|
|
34
38
|
const hasActions = actions.length > 0;
|
|
35
39
|
const status = statusProp ?? (hasActions ? "error" : "info");
|
|
36
40
|
const sev = useSeverityColors(statusToSeverity(status));
|
|
37
|
-
const
|
|
41
|
+
const actionRequiredLabel = isKeyExists?.("actionRequired") ? t("actionRequired") : "Action required";
|
|
42
|
+
const computedHeaderTitle = hasActions ? headerTitle ?? `${actionRequiredLabel}${actions.length > 1 ? ` (${actions.length})` : ""}` : headerTitle;
|
|
38
43
|
const hasHeader = !!computedHeaderTitle;
|
|
39
44
|
const hasBody = !!(title || description || children);
|
|
40
|
-
const
|
|
45
|
+
const resolvedDirection = textDirection ?? (isRTL ? "rtl" : "ltr");
|
|
46
|
+
const rowDirection = resolvedDirection === "rtl" ? "row-reverse" : "row";
|
|
41
47
|
const headerIconNode = (() => {
|
|
42
48
|
if (!headerIcon) return null;
|
|
43
49
|
if (status === "brand" && theme.config.logo) return /* @__PURE__ */ jsx(Fragment, { children: theme.config.logo });
|
|
@@ -93,7 +99,11 @@ const Banner = ({
|
|
|
93
99
|
borderRadius: 999,
|
|
94
100
|
paddingHorizontal: 12,
|
|
95
101
|
paddingVertical: 7,
|
|
96
|
-
|
|
102
|
+
// ⛔ `rowDirection`, NOT a hardcoded "row". This was the
|
|
103
|
+
// one row in the component that ignored the direction
|
|
104
|
+
// every other row obeyed, so even a caller that DID
|
|
105
|
+
// pass textDirection="rtl" got this pill backwards.
|
|
106
|
+
flexDirection: rowDirection,
|
|
97
107
|
alignItems: "center",
|
|
98
108
|
gap: 4,
|
|
99
109
|
flexShrink: 0
|
|
@@ -108,7 +118,7 @@ const Banner = ({
|
|
|
108
118
|
children: bannerAction.cta
|
|
109
119
|
}
|
|
110
120
|
),
|
|
111
|
-
/* @__PURE__ */ jsx(ArrowRight, { size: 12, color: sev.solidText })
|
|
121
|
+
resolvedDirection === "rtl" ? /* @__PURE__ */ jsx(ArrowLeft, { size: 12, color: sev.solidText }) : /* @__PURE__ */ jsx(ArrowRight, { size: 12, color: sev.solidText })
|
|
112
122
|
]
|
|
113
123
|
}
|
|
114
124
|
)
|
|
@@ -124,7 +134,7 @@ const Banner = ({
|
|
|
124
134
|
style: {
|
|
125
135
|
borderRadius: 8,
|
|
126
136
|
overflow: "hidden",
|
|
127
|
-
writingDirection:
|
|
137
|
+
writingDirection: resolvedDirection
|
|
128
138
|
},
|
|
129
139
|
children: [
|
|
130
140
|
hasHeader && /* @__PURE__ */ jsxs(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.js","sources":["../../../../src/components/Banner/banner.native.tsx"],"sourcesContent":["import React from \"react\";\nimport { Flex, Text, Icon } from \"../../_compat\";\nimport {\n AlertTriangle,\n ArrowRight,\n CheckCircle2,\n Info,\n CircleX,\n X,\n} from \"lucide-react-native\";\nimport { useSeverityColors } from \"../../hooks/useSeverityColors\";\nimport { useKitsTheme } from \"../../contexts/Theme\";\nimport type { BannerAction, IBannerProps, BannerStatus } from \"@lmb-it/kitsconcerto-types\";\nimport type { Severity } from \"@lmb-it/kitsconcerto-types\";\nimport { Pressable } from \"react-native\";\n\nconst icons: Record<string, any> = {\n error: CircleX,\n success: CheckCircle2,\n warning: AlertTriangle,\n info: Info,\n};\n\nfunction statusToSeverity(status: BannerStatus): Severity {\n if (status === \"error\") return \"danger\";\n return status;\n}\n\nconst Banner: React.FC<IBannerProps> = ({\n status: statusProp,\n headerTitle,\n headerIcon = true,\n title,\n description,\n withIcon = true,\n actions = [],\n onDismiss,\n children,\n className,\n textDirection = \"ltr\",\n}) => {\n const { theme } = useKitsTheme();\n const hasActions = actions.length > 0;\n const status = statusProp ?? (hasActions ? \"error\" : \"info\");\n const sev = useSeverityColors(statusToSeverity(status));\n const computedHeaderTitle = hasActions\n ? `Action required${actions.length > 1 ? ` (${actions.length})` : \"\"}`\n : headerTitle;\n const hasHeader = !!computedHeaderTitle;\n const hasBody = !!(title || description || children);\n const rowDirection = textDirection === \"rtl\" ? \"row-reverse\" : \"row\";\n\n const headerIconNode = (() => {\n if (!headerIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n if (hasActions) return <Icon name={AlertTriangle} color={sev.solidText} size=\"sm\" />;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.solidText} size=\"sm\" /> : null;\n })();\n\n const bodyIconNode = (() => {\n if (!withIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.iconFg} size=\"sm\" /> : null;\n })();\n\n const renderActionRow = (bannerAction: BannerAction, index: number) => (\n <Flex\n key={bannerAction.id}\n flexDirection={rowDirection}\n alignItems=\"flex-start\"\n gap={10}\n style={{\n padding: 12,\n borderTopWidth: index > 0 ? 1 : 0,\n borderTopColor: sev.border,\n }}\n >\n <Flex\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 8,\n backgroundColor: \"#fff\",\n borderWidth: 1,\n borderColor: sev.border,\n flexShrink: 0,\n }}\n >\n {bannerAction.icon ?? <Icon name={AlertTriangle} color={sev.iconFg} size=\"sm\" />}\n </Flex>\n <Flex flexDirection=\"column\" gap={2} style={{ flex: 1 }}>\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {bannerAction.label}\n </Text>\n {bannerAction.detail && (\n <Text size=\"xs\" style={{ color: sev.text, lineHeight: 17 }}>\n {bannerAction.detail}\n </Text>\n )}\n </Flex>\n {bannerAction.cta && (\n <Pressable\n onPress={bannerAction.onCta}\n style={{\n backgroundColor: sev.solid,\n borderRadius: 999,\n paddingHorizontal: 12,\n paddingVertical: 7,\n flexDirection: \"row\",\n alignItems: \"center\",\n gap: 4,\n flexShrink: 0,\n }}\n >\n <Text\n fontWeight=\"bold\"\n size=\"xs\"\n style={{ color: sev.solidText }}\n >\n {bannerAction.cta}\n </Text>\n <ArrowRight size={12} color={sev.solidText} />\n </Pressable>\n )}\n </Flex>\n );\n\n return (\n <Flex\n flexDirection=\"column\"\n className={className}\n style={{\n borderRadius: 8,\n overflow: \"hidden\",\n writingDirection: textDirection,\n }}\n >\n {/* Header bar */}\n {hasHeader && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={6}\n style={{\n backgroundColor: sev.solid,\n paddingVertical: 8,\n paddingHorizontal: 12,\n }}\n >\n {headerIconNode}\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.solidText, flex: 1 }}>\n {computedHeaderTitle}\n </Text>\n {onDismiss && (\n <Pressable\n accessibilityLabel=\"Dismiss\"\n onPress={onDismiss}\n style={{\n width: 24,\n height: 24,\n borderRadius: 999,\n backgroundColor: \"rgba(255, 255, 255, 0.2)\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <X size={14} color={sev.solidText} />\n </Pressable>\n )}\n </Flex>\n )}\n\n {/* Body section */}\n {hasActions ? (\n <Flex\n flexDirection=\"column\"\n style={{\n backgroundColor: sev.bgTint,\n }}\n >\n {actions.map(renderActionRow)}\n </Flex>\n ) : hasBody && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={12}\n style={{\n backgroundColor: sev.bgTint,\n padding: 12,\n justifyContent: \"space-between\",\n }}\n >\n <Flex flexDirection=\"column\" gap={4} style={{ flex: 1 }}>\n {(withIcon || title) && (\n <Flex flexDirection={rowDirection} alignItems=\"center\" gap={6}>\n {bodyIconNode}\n {title && (\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {title}\n </Text>\n )}\n </Flex>\n )}\n {description && (\n <Text size=\"xs\" style={{ color: sev.text }}>\n {description}\n </Text>\n )}\n {children}\n </Flex>\n </Flex>\n )}\n </Flex>\n );\n};\n\nexport default Banner;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"banner.js","sources":["../../../../src/components/Banner/banner.native.tsx"],"sourcesContent":["import React from \"react\";\nimport { Flex, Text, Icon } from \"../../_compat\";\nimport {\n AlertTriangle,\n ArrowLeft,\n ArrowRight,\n CheckCircle2,\n Info,\n CircleX,\n X,\n} from \"lucide-react-native\";\nimport { useSeverityColors } from \"../../hooks/useSeverityColors\";\nimport { useKitsTheme } from \"../../contexts/Theme\";\nimport { useLanguage } from \"../../hooks\";\nimport type { BannerAction, IBannerProps, BannerStatus } from \"@lmb-it/kitsconcerto-types\";\nimport type { Severity } from \"@lmb-it/kitsconcerto-types\";\nimport { Pressable } from \"react-native\";\n\nconst icons: Record<string, any> = {\n error: CircleX,\n success: CheckCircle2,\n warning: AlertTriangle,\n info: Info,\n};\n\nfunction statusToSeverity(status: BannerStatus): Severity {\n if (status === \"error\") return \"danger\";\n return status;\n}\n\nconst Banner: React.FC<IBannerProps> = ({\n status: statusProp,\n headerTitle,\n headerIcon = true,\n title,\n description,\n withIcon = true,\n actions = [],\n onDismiss,\n children,\n className,\n textDirection,\n}) => {\n const { theme } = useKitsTheme();\n const { t, isRTL, isKeyExists } = useLanguage();\n const hasActions = actions.length > 0;\n const status = statusProp ?? (hasActions ? \"error\" : \"info\");\n const sev = useSeverityColors(statusToSeverity(status));\n\n /*\n * ⛔ THE HEADING IS THE CONSUMER'S TO WRITE. This read\n * `hasActions ? \"Action required…\" : headerTitle`, so a caller that passed\n * a translated `headerTitle` AND any actions had it thrown away and an\n * ENGLISH LITERAL rendered instead — with no prop, theme value or locale\n * key able to reach it.\n *\n * ⛔ FOUND IN AN ARABIC APP, 19 September 2026: AlphaMatch's Me tab showed\n * \"Action required\" in English on an otherwise fully Arabic screen, while\n * the app's OWN translated string for it sat unused one call away. Grepping\n * the app for the English text finds only its locale file, which is exactly\n * why it reads as an app bug and is not one.\n *\n * ⚠️ THE FALLBACK IS LOCALISED, BUT ONLY WHERE A TRANSLATION EXISTS.\n * `isKeyExists` is checked first so a language without the key keeps\n * today's English rather than rendering the raw key at a user — 38 of this\n * library's 40 locale files have not been given this string, and a visible\n * `actionRequired` would be a worse defect than the one being fixed.\n *\n * ⚠️ THE COUNT SUFFIX BELONGS TO THE FALLBACK, NOT TO THE CONSUMER. A title\n * someone wrote is a complete sentence; appending \"(3)\" to it is the\n * library talking over them.\n */\n const actionRequiredLabel = isKeyExists?.(\"actionRequired\")\n ? t(\"actionRequired\")\n : \"Action required\";\n const computedHeaderTitle = hasActions\n ? headerTitle ??\n `${actionRequiredLabel}${actions.length > 1 ? ` (${actions.length})` : \"\"}`\n : headerTitle;\n\n const hasHeader = !!computedHeaderTitle;\n const hasBody = !!(title || description || children);\n\n /*\n * ⛔ THE DIRECTION DEFAULTS TO THE ACTIVE LANGUAGE, NOT TO ENGLISH. This\n * prop defaulted to `\"ltr\"`, so every caller that did not pass it — which\n * was all of them — got a left-to-right banner in an Arabic app, and none\n * of them could find out. A library shipping to an RTL product reads the\n * direction itself; the prop stays, for the caller that needs to override.\n */\n const resolvedDirection = textDirection ?? (isRTL ? \"rtl\" : \"ltr\");\n const rowDirection = resolvedDirection === \"rtl\" ? \"row-reverse\" : \"row\";\n\n const headerIconNode = (() => {\n if (!headerIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n if (hasActions) return <Icon name={AlertTriangle} color={sev.solidText} size=\"sm\" />;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.solidText} size=\"sm\" /> : null;\n })();\n\n const bodyIconNode = (() => {\n if (!withIcon) return null;\n if (status === \"brand\" && theme.config.logo) return <>{theme.config.logo}</>;\n const IconComp = icons[status];\n return IconComp ? <Icon name={IconComp} color={sev.iconFg} size=\"sm\" /> : null;\n })();\n\n const renderActionRow = (bannerAction: BannerAction, index: number) => (\n <Flex\n key={bannerAction.id}\n flexDirection={rowDirection}\n alignItems=\"flex-start\"\n gap={10}\n style={{\n padding: 12,\n borderTopWidth: index > 0 ? 1 : 0,\n borderTopColor: sev.border,\n }}\n >\n <Flex\n alignItems=\"center\"\n justifyContent=\"center\"\n style={{\n width: 28,\n height: 28,\n borderRadius: 8,\n backgroundColor: \"#fff\",\n borderWidth: 1,\n borderColor: sev.border,\n flexShrink: 0,\n }}\n >\n {bannerAction.icon ?? <Icon name={AlertTriangle} color={sev.iconFg} size=\"sm\" />}\n </Flex>\n <Flex flexDirection=\"column\" gap={2} style={{ flex: 1 }}>\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {bannerAction.label}\n </Text>\n {bannerAction.detail && (\n <Text size=\"xs\" style={{ color: sev.text, lineHeight: 17 }}>\n {bannerAction.detail}\n </Text>\n )}\n </Flex>\n {bannerAction.cta && (\n <Pressable\n onPress={bannerAction.onCta}\n style={{\n backgroundColor: sev.solid,\n borderRadius: 999,\n paddingHorizontal: 12,\n paddingVertical: 7,\n // ⛔ `rowDirection`, NOT a hardcoded \"row\". This was the\n // one row in the component that ignored the direction\n // every other row obeyed, so even a caller that DID\n // pass textDirection=\"rtl\" got this pill backwards.\n flexDirection: rowDirection,\n alignItems: \"center\",\n gap: 4,\n flexShrink: 0,\n }}\n >\n <Text\n fontWeight=\"bold\"\n size=\"xs\"\n style={{ color: sev.solidText }}\n >\n {bannerAction.cta}\n </Text>\n {/* ⛔ THE ARROW MEANS \"ONWARDS\", SO IT FOLLOWS THE READER.\n It was always ArrowRight, which in Arabic points back\n the way the eye came — on the one control the banner\n exists to get pressed. */}\n {resolvedDirection === \"rtl\" ? (\n <ArrowLeft size={12} color={sev.solidText} />\n ) : (\n <ArrowRight size={12} color={sev.solidText} />\n )}\n </Pressable>\n )}\n </Flex>\n );\n\n return (\n <Flex\n flexDirection=\"column\"\n className={className}\n style={{\n borderRadius: 8,\n overflow: \"hidden\",\n writingDirection: resolvedDirection,\n }}\n >\n {/* Header bar */}\n {hasHeader && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={6}\n style={{\n backgroundColor: sev.solid,\n paddingVertical: 8,\n paddingHorizontal: 12,\n }}\n >\n {headerIconNode}\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.solidText, flex: 1 }}>\n {computedHeaderTitle}\n </Text>\n {onDismiss && (\n <Pressable\n accessibilityLabel=\"Dismiss\"\n onPress={onDismiss}\n style={{\n width: 24,\n height: 24,\n borderRadius: 999,\n backgroundColor: \"rgba(255, 255, 255, 0.2)\",\n alignItems: \"center\",\n justifyContent: \"center\",\n }}\n >\n <X size={14} color={sev.solidText} />\n </Pressable>\n )}\n </Flex>\n )}\n\n {/* Body section */}\n {hasActions ? (\n <Flex\n flexDirection=\"column\"\n style={{\n backgroundColor: sev.bgTint,\n }}\n >\n {actions.map(renderActionRow)}\n </Flex>\n ) : hasBody && (\n <Flex\n flexDirection={rowDirection}\n alignItems=\"center\"\n gap={12}\n style={{\n backgroundColor: sev.bgTint,\n padding: 12,\n justifyContent: \"space-between\",\n }}\n >\n <Flex flexDirection=\"column\" gap={4} style={{ flex: 1 }}>\n {(withIcon || title) && (\n <Flex flexDirection={rowDirection} alignItems=\"center\" gap={6}>\n {bodyIconNode}\n {title && (\n <Text fontWeight=\"bold\" size=\"sm\" style={{ color: sev.text }}>\n {title}\n </Text>\n )}\n </Flex>\n )}\n {description && (\n <Text size=\"xs\" style={{ color: sev.text }}>\n {description}\n </Text>\n )}\n {children}\n </Flex>\n </Flex>\n )}\n </Flex>\n );\n};\n\nexport default Banner;\n"],"names":[],"mappings":";;;;;;;;;;;;AAkBA,MAAM,KAAA,GAA6B;AAAA,EAC/B,KAAA,EAAO,OAAA;AAAA,EACP,OAAA,EAAS,YAAA;AAAA,EACT,OAAA,EAAS,aAAA;AAAA,EACT,IAAA,EAAM;AACV,CAAA;AAEA,SAAS,iBAAiB,MAAA,EAAgC;AACtD,EAAA,IAAI,MAAA,KAAW,SAAS,OAAO,QAAA;AAC/B,EAAA,OAAO,MAAA;AACX;AAEA,MAAM,SAAiC,CAAC;AAAA,EACpC,MAAA,EAAQ,UAAA;AAAA,EACR,WAAA;AAAA,EACA,UAAA,GAAa,IAAA;AAAA,EACb,KAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA,GAAW,IAAA;AAAA,EACX,UAAU,EAAC;AAAA,EACX,SAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA;AACJ,CAAA,KAAM;AACF,EAAA,MAAM,EAAE,KAAA,EAAM,GAAI,YAAA,EAAa;AAC/B,EAAA,MAAM,EAAE,CAAA,EAAG,KAAA,EAAO,WAAA,KAAgB,WAAA,EAAY;AAC9C,EAAA,MAAM,UAAA,GAAa,QAAQ,MAAA,GAAS,CAAA;AACpC,EAAA,MAAM,MAAA,GAAS,UAAA,KAAe,UAAA,GAAa,OAAA,GAAU,MAAA,CAAA;AACrD,EAAA,MAAM,GAAA,GAAM,iBAAA,CAAkB,gBAAA,CAAiB,MAAM,CAAC,CAAA;AAyBtD,EAAA,MAAM,sBAAsB,WAAA,GAAc,gBAAgB,CAAA,GACpD,CAAA,CAAE,gBAAgB,CAAA,GAClB,iBAAA;AACN,EAAA,MAAM,mBAAA,GAAsB,UAAA,GACtB,WAAA,IACA,CAAA,EAAG,mBAAmB,CAAA,EAAG,OAAA,CAAQ,MAAA,GAAS,CAAA,GAAI,CAAA,EAAA,EAAK,OAAA,CAAQ,MAAM,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,CAAA,GACzE,WAAA;AAEN,EAAA,MAAM,SAAA,GAAY,CAAC,CAAC,mBAAA;AACpB,EAAA,MAAM,OAAA,GAAU,CAAC,EAAE,KAAA,IAAS,WAAA,IAAe,QAAA,CAAA;AAS3C,EAAA,MAAM,iBAAA,GAAoB,aAAA,KAAkB,KAAA,GAAQ,KAAA,GAAQ,KAAA,CAAA;AAC5D,EAAA,MAAM,YAAA,GAAe,iBAAA,KAAsB,KAAA,GAAQ,aAAA,GAAgB,KAAA;AAEnE,EAAA,MAAM,kBAAkB,MAAM;AAC1B,IAAA,IAAI,CAAC,YAAY,OAAO,IAAA;AACxB,IAAA,IAAI,MAAA,KAAW,WAAW,KAAA,CAAM,MAAA,CAAO,MAAM,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,KAAA,CAAM,MAAA,CAAO,IAAA,EAAK,CAAA;AACzE,IAAA,IAAI,UAAA,EAAY,uBAAO,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,eAAe,KAAA,EAAO,GAAA,CAAI,SAAA,EAAW,IAAA,EAAK,IAAA,EAAK,CAAA;AAClF,IAAA,MAAM,QAAA,GAAW,MAAM,MAAM,CAAA;AAC7B,IAAA,OAAO,QAAA,mBAAW,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,QAAA,EAAU,OAAO,GAAA,CAAI,SAAA,EAAW,IAAA,EAAK,IAAA,EAAK,CAAA,GAAK,IAAA;AAAA,EACjF,CAAA,GAAG;AAEH,EAAA,MAAM,gBAAgB,MAAM;AACxB,IAAA,IAAI,CAAC,UAAU,OAAO,IAAA;AACtB,IAAA,IAAI,MAAA,KAAW,WAAW,KAAA,CAAM,MAAA,CAAO,MAAM,uBAAO,GAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,KAAA,CAAM,MAAA,CAAO,IAAA,EAAK,CAAA;AACzE,IAAA,MAAM,QAAA,GAAW,MAAM,MAAM,CAAA;AAC7B,IAAA,OAAO,QAAA,mBAAW,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,QAAA,EAAU,OAAO,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,CAAA,GAAK,IAAA;AAAA,EAC9E,CAAA,GAAG;AAEH,EAAA,MAAM,eAAA,GAAkB,CAAC,YAAA,EAA4B,KAAA,qBACjD,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MAEG,aAAA,EAAe,YAAA;AAAA,MACf,UAAA,EAAW,YAAA;AAAA,MACX,GAAA,EAAK,EAAA;AAAA,MACL,KAAA,EAAO;AAAA,QACH,OAAA,EAAS,EAAA;AAAA,QACT,cAAA,EAAgB,KAAA,GAAQ,CAAA,GAAI,CAAA,GAAI,CAAA;AAAA,QAChC,gBAAgB,GAAA,CAAI;AAAA,OACxB;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,UAAA,EAAW,QAAA;AAAA,YACX,cAAA,EAAe,QAAA;AAAA,YACf,KAAA,EAAO;AAAA,cACH,KAAA,EAAO,EAAA;AAAA,cACP,MAAA,EAAQ,EAAA;AAAA,cACR,YAAA,EAAc,CAAA;AAAA,cACd,eAAA,EAAiB,MAAA;AAAA,cACjB,WAAA,EAAa,CAAA;AAAA,cACb,aAAa,GAAA,CAAI,MAAA;AAAA,cACjB,UAAA,EAAY;AAAA,aAChB;AAAA,YAEC,QAAA,EAAA,YAAA,CAAa,IAAA,oBAAQ,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAM,eAAe,KAAA,EAAO,GAAA,CAAI,MAAA,EAAQ,IAAA,EAAK,IAAA,EAAK;AAAA;AAAA,SAClF;AAAA,wBACA,IAAA,CAAC,IAAA,EAAA,EAAK,aAAA,EAAc,QAAA,EAAS,GAAA,EAAK,GAAG,KAAA,EAAO,EAAE,IAAA,EAAM,CAAA,EAAE,EAClD,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,UAAA,EAAW,MAAA,EAAO,IAAA,EAAK,IAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,GAAA,CAAI,IAAA,EAAK,EACtD,QAAA,EAAA,YAAA,CAAa,KAAA,EAClB,CAAA;AAAA,UACC,YAAA,CAAa,MAAA,oBACV,GAAA,CAAC,IAAA,EAAA,EAAK,MAAK,IAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,IAAI,IAAA,EAAM,UAAA,EAAY,EAAA,EAAG,EACpD,uBAAa,MAAA,EAClB;AAAA,SAAA,EAER,CAAA;AAAA,QACC,aAAa,GAAA,oBACV,IAAA;AAAA,UAAC,SAAA;AAAA,UAAA;AAAA,YACG,SAAS,YAAA,CAAa,KAAA;AAAA,YACtB,KAAA,EAAO;AAAA,cACH,iBAAiB,GAAA,CAAI,KAAA;AAAA,cACrB,YAAA,EAAc,GAAA;AAAA,cACd,iBAAA,EAAmB,EAAA;AAAA,cACnB,eAAA,EAAiB,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAKjB,aAAA,EAAe,YAAA;AAAA,cACf,UAAA,EAAY,QAAA;AAAA,cACZ,GAAA,EAAK,CAAA;AAAA,cACL,UAAA,EAAY;AAAA,aAChB;AAAA,YAEA,QAAA,EAAA;AAAA,8BAAA,GAAA;AAAA,gBAAC,IAAA;AAAA,gBAAA;AAAA,kBACG,UAAA,EAAW,MAAA;AAAA,kBACX,IAAA,EAAK,IAAA;AAAA,kBACL,KAAA,EAAO,EAAE,KAAA,EAAO,GAAA,CAAI,SAAA,EAAU;AAAA,kBAE7B,QAAA,EAAA,YAAA,CAAa;AAAA;AAAA,eAClB;AAAA,cAKC,sBAAsB,KAAA,mBACnB,GAAA,CAAC,SAAA,EAAA,EAAU,IAAA,EAAM,IAAI,KAAA,EAAO,GAAA,CAAI,SAAA,EAAW,CAAA,uBAE1C,UAAA,EAAA,EAAW,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,IAAI,SAAA,EAAW;AAAA;AAAA;AAAA;AAEpD;AAAA,KAAA;AAAA,IArEC,YAAA,CAAa;AAAA,GAuEtB;AAGJ,EAAA,uBACI,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,aAAA,EAAc,QAAA;AAAA,MACd,SAAA;AAAA,MACA,KAAA,EAAO;AAAA,QACH,YAAA,EAAc,CAAA;AAAA,QACd,QAAA,EAAU,QAAA;AAAA,QACV,gBAAA,EAAkB;AAAA,OACtB;AAAA,MAGC,QAAA,EAAA;AAAA,QAAA,SAAA,oBACG,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAe,YAAA;AAAA,YACf,UAAA,EAAW,QAAA;AAAA,YACX,GAAA,EAAK,CAAA;AAAA,YACL,KAAA,EAAO;AAAA,cACH,iBAAiB,GAAA,CAAI,KAAA;AAAA,cACrB,eAAA,EAAiB,CAAA;AAAA,cACjB,iBAAA,EAAmB;AAAA,aACvB;AAAA,YAEC,QAAA,EAAA;AAAA,cAAA,cAAA;AAAA,8BACD,GAAA,CAAC,IAAA,EAAA,EAAK,UAAA,EAAW,MAAA,EAAO,MAAK,IAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,GAAA,CAAI,SAAA,EAAW,IAAA,EAAM,CAAA,IAClE,QAAA,EAAA,mBAAA,EACL,CAAA;AAAA,cACC,SAAA,oBACG,GAAA;AAAA,gBAAC,SAAA;AAAA,gBAAA;AAAA,kBACG,kBAAA,EAAmB,SAAA;AAAA,kBACnB,OAAA,EAAS,SAAA;AAAA,kBACT,KAAA,EAAO;AAAA,oBACH,KAAA,EAAO,EAAA;AAAA,oBACP,MAAA,EAAQ,EAAA;AAAA,oBACR,YAAA,EAAc,GAAA;AAAA,oBACd,eAAA,EAAiB,0BAAA;AAAA,oBACjB,UAAA,EAAY,QAAA;AAAA,oBACZ,cAAA,EAAgB;AAAA,mBACpB;AAAA,kBAEA,8BAAC,CAAA,EAAA,EAAE,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,IAAI,SAAA,EAAW;AAAA;AAAA;AACvC;AAAA;AAAA,SAER;AAAA,QAIH,UAAA,mBACG,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAc,QAAA;AAAA,YACd,KAAA,EAAO;AAAA,cACH,iBAAiB,GAAA,CAAI;AAAA,aACzB;AAAA,YAEC,QAAA,EAAA,OAAA,CAAQ,IAAI,eAAe;AAAA;AAAA,YAEhC,OAAA,oBACA,GAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,aAAA,EAAe,YAAA;AAAA,YACf,UAAA,EAAW,QAAA;AAAA,YACX,GAAA,EAAK,EAAA;AAAA,YACL,KAAA,EAAO;AAAA,cACH,iBAAiB,GAAA,CAAI,MAAA;AAAA,cACrB,OAAA,EAAS,EAAA;AAAA,cACT,cAAA,EAAgB;AAAA,aACpB;AAAA,YAEA,QAAA,kBAAA,IAAA,CAAC,IAAA,EAAA,EAAK,aAAA,EAAc,QAAA,EAAS,GAAA,EAAK,GAAG,KAAA,EAAO,EAAE,IAAA,EAAM,CAAA,EAAE,EAChD,QAAA,EAAA;AAAA,cAAA,CAAA,QAAA,IAAY,KAAA,0BACT,IAAA,EAAA,EAAK,aAAA,EAAe,cAAc,UAAA,EAAW,QAAA,EAAS,KAAK,CAAA,EACvD,QAAA,EAAA;AAAA,gBAAA,YAAA;AAAA,gBACA,KAAA,oBACG,GAAA,CAAC,IAAA,EAAA,EAAK,UAAA,EAAW,MAAA,EAAO,IAAA,EAAK,IAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,GAAA,CAAI,IAAA,IACjD,QAAA,EAAA,KAAA,EACL;AAAA,eAAA,EAER,CAAA;AAAA,cAEH,WAAA,oBACG,GAAA,CAAC,IAAA,EAAA,EAAK,IAAA,EAAK,IAAA,EAAK,KAAA,EAAO,EAAE,KAAA,EAAO,GAAA,CAAI,IAAA,EAAK,EACpC,QAAA,EAAA,WAAA,EACL,CAAA;AAAA,cAEH;AAAA,aAAA,EACL;AAAA;AAAA;AACJ;AAAA;AAAA,GAER;AAER;;;;"}
|
|
@@ -83,6 +83,7 @@ require('../../apps/mobile/src/Core/RadioButton/index.cjs');
|
|
|
83
83
|
require('../../apps/mobile/src/Core/Input/index.cjs');
|
|
84
84
|
require('../../apps/mobile/src/Core/Input/Field.cjs');
|
|
85
85
|
require('../../apps/mobile/src/Core/Input/Slot.cjs');
|
|
86
|
+
var useRtlLineHeight = require('../../hooks/useRtlLineHeight.cjs');
|
|
86
87
|
var index$1 = require('../../primitives/Box/index.cjs');
|
|
87
88
|
var index_native = require('../../primitives/Icon/index.cjs');
|
|
88
89
|
var index = require('../../layout/Flex/index.cjs');
|
|
@@ -148,6 +149,7 @@ function BottomTabBar(rawProps) {
|
|
|
148
149
|
showLabels = true,
|
|
149
150
|
testID
|
|
150
151
|
} = props;
|
|
152
|
+
const rtlLineHeight = useRtlLineHeight.default(void 0, 11);
|
|
151
153
|
const insets = reactNativeSafeAreaContext.useSafeAreaInsets();
|
|
152
154
|
const activeC = style.resolveThemeTokenForNative(activeColor);
|
|
153
155
|
const inactiveC = style.resolveThemeTokenForNative(inactiveColor);
|
|
@@ -231,7 +233,7 @@ function BottomTabBar(rawProps) {
|
|
|
231
233
|
/* @__PURE__ */ jsxRuntime.jsx(index_native.Icon, { name: iconName, size: 24, color }),
|
|
232
234
|
item.badge != null && item.badge !== false && /* @__PURE__ */ jsxRuntime.jsx(Badge, { badge: item.badge, barBg: bg, dangerColor: danger })
|
|
233
235
|
] }),
|
|
234
|
-
showLabels && item.label != null && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { numberOfLines: 1, style: { fontSize: 11, fontWeight: "500", color }, children: item.label })
|
|
236
|
+
showLabels && item.label != null && /* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { numberOfLines: 1, style: { fontSize: 11, fontWeight: "500", color, ...rtlLineHeight != null ? { lineHeight: rtlLineHeight } : {} }, children: item.label })
|
|
235
237
|
]
|
|
236
238
|
},
|
|
237
239
|
item.key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/BottomTabBar/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Pressable, Text, View} from \"react-native\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {resolveThemeTokenForNative} from \"@lmb-it/kitsconcertomobile\";\nimport type {IBottomTabBarProps, ITabBarItem} from \"@lmb-it/kitsconcerto-types\";\nimport {Icon} from \"../../primitives\";\nimport {Box} from \"../../primitives\";\nimport Flex from \"../../layout/Flex\";\nimport {useComponentDefaults} from \"../../hooks\";\n\n// Mirrors the app's AMTabBar geometry (App/src/components/shared/layout).\nconst BAR_MIN_HEIGHT = 60;\nconst FAB_SIZE = 56;\n\nfunction Badge({badge, barBg, dangerColor}: {badge: number | boolean; barBg: string; dangerColor: string}) {\n const isDot = badge === true || badge === 0;\n if (isDot) {\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -2,\n right: -2,\n width: 10,\n height: 10,\n borderRadius: 5,\n backgroundColor: dangerColor,\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n />\n );\n }\n const count = typeof badge === \"number\" ? (badge > 99 ? \"99+\" : String(badge)) : \"\";\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -6,\n right: -10,\n minWidth: 16,\n height: 16,\n borderRadius: 8,\n paddingHorizontal: 4,\n backgroundColor: dangerColor,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n >\n <Text style={{color: \"#FFFFFF\", fontSize: 9, fontWeight: \"700\", lineHeight: 11}}>{count}</Text>\n </Box>\n );\n}\n\n/**\n * BottomTabBar — iOS/Android bottom navigation with an elevated center FAB.\n *\n * Layout mirrors the app's working `AMTabBar`: a `row` / `space-between` bar\n * with four `flex:1` **column** slots and a content-width centre slot holding\n * the FAB. The FAB is lifted with `marginTop:-26` and ringed with a 3px\n * border so it sits above the bar plane — never absolutely positioned.\n * Presentational + controlled (router-agnostic).\n */\nexport function BottomTabBar<K extends string = string>(rawProps: IBottomTabBarProps<K>) {\n const props = useComponentDefaults<IBottomTabBarProps<K>>(\"BottomTabBar\", rawProps).mergedProps;\n const {\n items,\n value,\n onChange,\n activeColor = \"brand\",\n inactiveColor = \"text-secondary\",\n background = \"surface-card\",\n fabColor,\n showLabels = true,\n testID,\n } = props;\n\n const insets = useSafeAreaInsets();\n\n // Resolve tokens → hex with the standalone resolver (the one `Icon` uses),\n // so colors apply on raw RN elements in both app and Storybook contexts.\n const activeC = resolveThemeTokenForNative(activeColor);\n const inactiveC = resolveThemeTokenForNative(inactiveColor);\n const bg = resolveThemeTokenForNative(background);\n const border = resolveThemeTokenForNative(\"surface-border\");\n const fabBg = resolveThemeTokenForNative(fabColor ?? activeColor);\n const danger = resolveThemeTokenForNative(\"danger\");\n\n return (\n <View\n testID={testID}\n style={{\n width: \"100%\",\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n minHeight: BAR_MIN_HEIGHT,\n paddingHorizontal: 20,\n paddingTop: 10,\n paddingBottom: Math.max(insets.bottom, 12),\n backgroundColor: bg,\n borderTopWidth: 1,\n borderTopColor: border,\n }}\n >\n {items.map((item: ITabBarItem<K>) => {\n const active = item.key === value;\n\n // Centre FAB — a content-width slot (NOT flex:1) so the four\n // side slots distribute evenly; the FAB is lifted in-flow.\n if (item.fab) {\n return (\n <Flex key={item.key} style={{alignItems: \"center\", justifyContent: \"center\"}}>\n <Pressable\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n hitSlop={8}\n style={({pressed}) => [\n {\n width: FAB_SIZE,\n height: FAB_SIZE,\n borderRadius: FAB_SIZE / 2,\n marginTop: -26,\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: fabBg,\n borderWidth: 3,\n borderColor: bg,\n shadowColor: fabBg,\n shadowOffset: {width: 0, height: 6},\n shadowOpacity: 0.35,\n shadowRadius: 12,\n elevation: 8,\n },\n pressed && {opacity: 0.9},\n ]}\n >\n <Icon name={item.icon as never} size={26} color=\"#FFFFFF\" />\n </Pressable>\n </Flex>\n );\n }\n\n const color = active ? activeC : inactiveC;\n const iconName = active && item.activeIcon != null ? item.activeIcon : item.icon;\n\n return (\n <Pressable\n key={item.key}\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n style={({pressed}) => [\n {\n flex: 1,\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 4,\n paddingVertical: 6,\n paddingHorizontal: 4,\n minHeight: 44,\n },\n pressed && {opacity: 0.7},\n ]}\n >\n <View style={{alignItems: \"center\", justifyContent: \"center\", position: \"relative\"}}>\n <Icon name={iconName as never} size={24} color={color} />\n {item.badge != null && item.badge !== false && (\n <Badge badge={item.badge} barBg={bg} dangerColor={danger} />\n )}\n </View>\n {showLabels && item.label != null && (\n <Text numberOfLines={1} style={{fontSize: 11, fontWeight: \"500\", color}}>\n {item.label}\n </Text>\n )}\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nexport default BottomTabBar;\n"],"names":["jsx","Box","Text","useComponentDefaults","useSafeAreaInsets","resolveThemeTokenForNative","View","Flex","Pressable","Icon","jsxs"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/BottomTabBar/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Pressable, Text, View} from \"react-native\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {resolveThemeTokenForNative} from \"@lmb-it/kitsconcertomobile\";\nimport useRtlLineHeight from \"../../hooks/useRtlLineHeight\";\nimport type {IBottomTabBarProps, ITabBarItem} from \"@lmb-it/kitsconcerto-types\";\nimport {Icon} from \"../../primitives\";\nimport {Box} from \"../../primitives\";\nimport Flex from \"../../layout/Flex\";\nimport {useComponentDefaults} from \"../../hooks\";\n\n// Mirrors the app's AMTabBar geometry (App/src/components/shared/layout).\nconst BAR_MIN_HEIGHT = 60;\nconst FAB_SIZE = 56;\n\nfunction Badge({badge, barBg, dangerColor}: {badge: number | boolean; barBg: string; dangerColor: string}) {\n const isDot = badge === true || badge === 0;\n if (isDot) {\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -2,\n right: -2,\n width: 10,\n height: 10,\n borderRadius: 5,\n backgroundColor: dangerColor,\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n />\n );\n }\n const count = typeof badge === \"number\" ? (badge > 99 ? \"99+\" : String(badge)) : \"\";\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -6,\n right: -10,\n minWidth: 16,\n height: 16,\n borderRadius: 8,\n paddingHorizontal: 4,\n backgroundColor: dangerColor,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n >\n <Text style={{color: \"#FFFFFF\", fontSize: 9, fontWeight: \"700\", lineHeight: 11}}>{count}</Text>\n </Box>\n );\n}\n\n/**\n * BottomTabBar — iOS/Android bottom navigation with an elevated center FAB.\n *\n * Layout mirrors the app's working `AMTabBar`: a `row` / `space-between` bar\n * with four `flex:1` **column** slots and a content-width centre slot holding\n * the FAB. The FAB is lifted with `marginTop:-26` and ringed with a 3px\n * border so it sits above the bar plane — never absolutely positioned.\n * Presentational + controlled (router-agnostic).\n */\nexport function BottomTabBar<K extends string = string>(rawProps: IBottomTabBarProps<K>) {\n const props = useComponentDefaults<IBottomTabBarProps<K>>(\"BottomTabBar\", rawProps).mergedProps;\n const {\n items,\n value,\n onChange,\n activeColor = \"brand\",\n inactiveColor = \"text-secondary\",\n background = \"surface-card\",\n fabColor,\n showLabels = true,\n testID,\n } = props;\n /*\n * ⛔ ARABIC CLIPS WITHOUT AN EXPLICIT LINE BOX — a raw react-native <Text>\n * with a fontSize and no lineHeight gets the FONT'S natural box, and\n * NotoKufiArabic's is too short for its own ascenders. In an RTL script\n * that reads as a BAD TRANSLATION rather than as clipping: ش/س, غ/ع and\n * ة/ه differ only by marks above the baseline.\n * ⚠️ undefined in LTR, so no English layout moves.\n */\n const rtlLineHeight = useRtlLineHeight(undefined, 11);\n\n const insets = useSafeAreaInsets();\n\n // Resolve tokens → hex with the standalone resolver (the one `Icon` uses),\n // so colors apply on raw RN elements in both app and Storybook contexts.\n const activeC = resolveThemeTokenForNative(activeColor);\n const inactiveC = resolveThemeTokenForNative(inactiveColor);\n const bg = resolveThemeTokenForNative(background);\n const border = resolveThemeTokenForNative(\"surface-border\");\n const fabBg = resolveThemeTokenForNative(fabColor ?? activeColor);\n const danger = resolveThemeTokenForNative(\"danger\");\n\n return (\n <View\n testID={testID}\n style={{\n width: \"100%\",\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n minHeight: BAR_MIN_HEIGHT,\n paddingHorizontal: 20,\n paddingTop: 10,\n paddingBottom: Math.max(insets.bottom, 12),\n backgroundColor: bg,\n borderTopWidth: 1,\n borderTopColor: border,\n }}\n >\n {items.map((item: ITabBarItem<K>) => {\n const active = item.key === value;\n\n // Centre FAB — a content-width slot (NOT flex:1) so the four\n // side slots distribute evenly; the FAB is lifted in-flow.\n if (item.fab) {\n return (\n <Flex key={item.key} style={{alignItems: \"center\", justifyContent: \"center\"}}>\n <Pressable\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n hitSlop={8}\n style={({pressed}) => [\n {\n width: FAB_SIZE,\n height: FAB_SIZE,\n borderRadius: FAB_SIZE / 2,\n marginTop: -26,\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: fabBg,\n borderWidth: 3,\n borderColor: bg,\n shadowColor: fabBg,\n shadowOffset: {width: 0, height: 6},\n shadowOpacity: 0.35,\n shadowRadius: 12,\n elevation: 8,\n },\n pressed && {opacity: 0.9},\n ]}\n >\n <Icon name={item.icon as never} size={26} color=\"#FFFFFF\" />\n </Pressable>\n </Flex>\n );\n }\n\n const color = active ? activeC : inactiveC;\n const iconName = active && item.activeIcon != null ? item.activeIcon : item.icon;\n\n return (\n <Pressable\n key={item.key}\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n style={({pressed}) => [\n {\n flex: 1,\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 4,\n paddingVertical: 6,\n paddingHorizontal: 4,\n minHeight: 44,\n },\n pressed && {opacity: 0.7},\n ]}\n >\n <View style={{alignItems: \"center\", justifyContent: \"center\", position: \"relative\"}}>\n <Icon name={iconName as never} size={24} color={color} />\n {item.badge != null && item.badge !== false && (\n <Badge badge={item.badge} barBg={bg} dangerColor={danger} />\n )}\n </View>\n {showLabels && item.label != null && (\n <Text numberOfLines={1} style={{fontSize: 11, fontWeight: \"500\", color, ...(rtlLineHeight != null ? {lineHeight: rtlLineHeight} : {})}}>\n {item.label}\n </Text>\n )}\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nexport default BottomTabBar;\n"],"names":["jsx","Box","Text","useComponentDefaults","useRtlLineHeight","useSafeAreaInsets","resolveThemeTokenForNative","View","Flex","Pressable","Icon","jsxs"],"mappings":"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"}
|
|
@@ -81,6 +81,7 @@ import '../../apps/mobile/src/Core/RadioButton/index.js';
|
|
|
81
81
|
import '../../apps/mobile/src/Core/Input/index.js';
|
|
82
82
|
import '../../apps/mobile/src/Core/Input/Field.js';
|
|
83
83
|
import '../../apps/mobile/src/Core/Input/Slot.js';
|
|
84
|
+
import useRtlLineHeight from '../../hooks/useRtlLineHeight.js';
|
|
84
85
|
import Box from '../../primitives/Box/index.js';
|
|
85
86
|
import { Icon } from '../../primitives/Icon/index.js';
|
|
86
87
|
import Flex from '../../layout/Flex/index.js';
|
|
@@ -146,6 +147,7 @@ function BottomTabBar(rawProps) {
|
|
|
146
147
|
showLabels = true,
|
|
147
148
|
testID
|
|
148
149
|
} = props;
|
|
150
|
+
const rtlLineHeight = useRtlLineHeight(void 0, 11);
|
|
149
151
|
const insets = useSafeAreaInsets();
|
|
150
152
|
const activeC = resolveThemeTokenForNative(activeColor);
|
|
151
153
|
const inactiveC = resolveThemeTokenForNative(inactiveColor);
|
|
@@ -229,7 +231,7 @@ function BottomTabBar(rawProps) {
|
|
|
229
231
|
/* @__PURE__ */ jsx(Icon, { name: iconName, size: 24, color }),
|
|
230
232
|
item.badge != null && item.badge !== false && /* @__PURE__ */ jsx(Badge, { badge: item.badge, barBg: bg, dangerColor: danger })
|
|
231
233
|
] }),
|
|
232
|
-
showLabels && item.label != null && /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: { fontSize: 11, fontWeight: "500", color }, children: item.label })
|
|
234
|
+
showLabels && item.label != null && /* @__PURE__ */ jsx(Text, { numberOfLines: 1, style: { fontSize: 11, fontWeight: "500", color, ...rtlLineHeight != null ? { lineHeight: rtlLineHeight } : {} }, children: item.label })
|
|
233
235
|
]
|
|
234
236
|
},
|
|
235
237
|
item.key
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/BottomTabBar/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Pressable, Text, View} from \"react-native\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {resolveThemeTokenForNative} from \"@lmb-it/kitsconcertomobile\";\nimport type {IBottomTabBarProps, ITabBarItem} from \"@lmb-it/kitsconcerto-types\";\nimport {Icon} from \"../../primitives\";\nimport {Box} from \"../../primitives\";\nimport Flex from \"../../layout/Flex\";\nimport {useComponentDefaults} from \"../../hooks\";\n\n// Mirrors the app's AMTabBar geometry (App/src/components/shared/layout).\nconst BAR_MIN_HEIGHT = 60;\nconst FAB_SIZE = 56;\n\nfunction Badge({badge, barBg, dangerColor}: {badge: number | boolean; barBg: string; dangerColor: string}) {\n const isDot = badge === true || badge === 0;\n if (isDot) {\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -2,\n right: -2,\n width: 10,\n height: 10,\n borderRadius: 5,\n backgroundColor: dangerColor,\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n />\n );\n }\n const count = typeof badge === \"number\" ? (badge > 99 ? \"99+\" : String(badge)) : \"\";\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -6,\n right: -10,\n minWidth: 16,\n height: 16,\n borderRadius: 8,\n paddingHorizontal: 4,\n backgroundColor: dangerColor,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n >\n <Text style={{color: \"#FFFFFF\", fontSize: 9, fontWeight: \"700\", lineHeight: 11}}>{count}</Text>\n </Box>\n );\n}\n\n/**\n * BottomTabBar — iOS/Android bottom navigation with an elevated center FAB.\n *\n * Layout mirrors the app's working `AMTabBar`: a `row` / `space-between` bar\n * with four `flex:1` **column** slots and a content-width centre slot holding\n * the FAB. The FAB is lifted with `marginTop:-26` and ringed with a 3px\n * border so it sits above the bar plane — never absolutely positioned.\n * Presentational + controlled (router-agnostic).\n */\nexport function BottomTabBar<K extends string = string>(rawProps: IBottomTabBarProps<K>) {\n const props = useComponentDefaults<IBottomTabBarProps<K>>(\"BottomTabBar\", rawProps).mergedProps;\n const {\n items,\n value,\n onChange,\n activeColor = \"brand\",\n inactiveColor = \"text-secondary\",\n background = \"surface-card\",\n fabColor,\n showLabels = true,\n testID,\n } = props;\n\n const insets = useSafeAreaInsets();\n\n // Resolve tokens → hex with the standalone resolver (the one `Icon` uses),\n // so colors apply on raw RN elements in both app and Storybook contexts.\n const activeC = resolveThemeTokenForNative(activeColor);\n const inactiveC = resolveThemeTokenForNative(inactiveColor);\n const bg = resolveThemeTokenForNative(background);\n const border = resolveThemeTokenForNative(\"surface-border\");\n const fabBg = resolveThemeTokenForNative(fabColor ?? activeColor);\n const danger = resolveThemeTokenForNative(\"danger\");\n\n return (\n <View\n testID={testID}\n style={{\n width: \"100%\",\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n minHeight: BAR_MIN_HEIGHT,\n paddingHorizontal: 20,\n paddingTop: 10,\n paddingBottom: Math.max(insets.bottom, 12),\n backgroundColor: bg,\n borderTopWidth: 1,\n borderTopColor: border,\n }}\n >\n {items.map((item: ITabBarItem<K>) => {\n const active = item.key === value;\n\n // Centre FAB — a content-width slot (NOT flex:1) so the four\n // side slots distribute evenly; the FAB is lifted in-flow.\n if (item.fab) {\n return (\n <Flex key={item.key} style={{alignItems: \"center\", justifyContent: \"center\"}}>\n <Pressable\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n hitSlop={8}\n style={({pressed}) => [\n {\n width: FAB_SIZE,\n height: FAB_SIZE,\n borderRadius: FAB_SIZE / 2,\n marginTop: -26,\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: fabBg,\n borderWidth: 3,\n borderColor: bg,\n shadowColor: fabBg,\n shadowOffset: {width: 0, height: 6},\n shadowOpacity: 0.35,\n shadowRadius: 12,\n elevation: 8,\n },\n pressed && {opacity: 0.9},\n ]}\n >\n <Icon name={item.icon as never} size={26} color=\"#FFFFFF\" />\n </Pressable>\n </Flex>\n );\n }\n\n const color = active ? activeC : inactiveC;\n const iconName = active && item.activeIcon != null ? item.activeIcon : item.icon;\n\n return (\n <Pressable\n key={item.key}\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n style={({pressed}) => [\n {\n flex: 1,\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 4,\n paddingVertical: 6,\n paddingHorizontal: 4,\n minHeight: 44,\n },\n pressed && {opacity: 0.7},\n ]}\n >\n <View style={{alignItems: \"center\", justifyContent: \"center\", position: \"relative\"}}>\n <Icon name={iconName as never} size={24} color={color} />\n {item.badge != null && item.badge !== false && (\n <Badge badge={item.badge} barBg={bg} dangerColor={danger} />\n )}\n </View>\n {showLabels && item.label != null && (\n <Text numberOfLines={1} style={{fontSize: 11, fontWeight: \"500\", color}}>\n {item.label}\n </Text>\n )}\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nexport default BottomTabBar;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/BottomTabBar/index.native.tsx"],"sourcesContent":["import React from \"react\";\nimport {Pressable, Text, View} from \"react-native\";\nimport {useSafeAreaInsets} from \"react-native-safe-area-context\";\nimport {resolveThemeTokenForNative} from \"@lmb-it/kitsconcertomobile\";\nimport useRtlLineHeight from \"../../hooks/useRtlLineHeight\";\nimport type {IBottomTabBarProps, ITabBarItem} from \"@lmb-it/kitsconcerto-types\";\nimport {Icon} from \"../../primitives\";\nimport {Box} from \"../../primitives\";\nimport Flex from \"../../layout/Flex\";\nimport {useComponentDefaults} from \"../../hooks\";\n\n// Mirrors the app's AMTabBar geometry (App/src/components/shared/layout).\nconst BAR_MIN_HEIGHT = 60;\nconst FAB_SIZE = 56;\n\nfunction Badge({badge, barBg, dangerColor}: {badge: number | boolean; barBg: string; dangerColor: string}) {\n const isDot = badge === true || badge === 0;\n if (isDot) {\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -2,\n right: -2,\n width: 10,\n height: 10,\n borderRadius: 5,\n backgroundColor: dangerColor,\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n />\n );\n }\n const count = typeof badge === \"number\" ? (badge > 99 ? \"99+\" : String(badge)) : \"\";\n return (\n <Box\n style={{\n position: \"absolute\",\n top: -6,\n right: -10,\n minWidth: 16,\n height: 16,\n borderRadius: 8,\n paddingHorizontal: 4,\n backgroundColor: dangerColor,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderWidth: 1.5,\n borderColor: barBg,\n zIndex: 10,\n }}\n >\n <Text style={{color: \"#FFFFFF\", fontSize: 9, fontWeight: \"700\", lineHeight: 11}}>{count}</Text>\n </Box>\n );\n}\n\n/**\n * BottomTabBar — iOS/Android bottom navigation with an elevated center FAB.\n *\n * Layout mirrors the app's working `AMTabBar`: a `row` / `space-between` bar\n * with four `flex:1` **column** slots and a content-width centre slot holding\n * the FAB. The FAB is lifted with `marginTop:-26` and ringed with a 3px\n * border so it sits above the bar plane — never absolutely positioned.\n * Presentational + controlled (router-agnostic).\n */\nexport function BottomTabBar<K extends string = string>(rawProps: IBottomTabBarProps<K>) {\n const props = useComponentDefaults<IBottomTabBarProps<K>>(\"BottomTabBar\", rawProps).mergedProps;\n const {\n items,\n value,\n onChange,\n activeColor = \"brand\",\n inactiveColor = \"text-secondary\",\n background = \"surface-card\",\n fabColor,\n showLabels = true,\n testID,\n } = props;\n /*\n * ⛔ ARABIC CLIPS WITHOUT AN EXPLICIT LINE BOX — a raw react-native <Text>\n * with a fontSize and no lineHeight gets the FONT'S natural box, and\n * NotoKufiArabic's is too short for its own ascenders. In an RTL script\n * that reads as a BAD TRANSLATION rather than as clipping: ش/س, غ/ع and\n * ة/ه differ only by marks above the baseline.\n * ⚠️ undefined in LTR, so no English layout moves.\n */\n const rtlLineHeight = useRtlLineHeight(undefined, 11);\n\n const insets = useSafeAreaInsets();\n\n // Resolve tokens → hex with the standalone resolver (the one `Icon` uses),\n // so colors apply on raw RN elements in both app and Storybook contexts.\n const activeC = resolveThemeTokenForNative(activeColor);\n const inactiveC = resolveThemeTokenForNative(inactiveColor);\n const bg = resolveThemeTokenForNative(background);\n const border = resolveThemeTokenForNative(\"surface-border\");\n const fabBg = resolveThemeTokenForNative(fabColor ?? activeColor);\n const danger = resolveThemeTokenForNative(\"danger\");\n\n return (\n <View\n testID={testID}\n style={{\n width: \"100%\",\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n minHeight: BAR_MIN_HEIGHT,\n paddingHorizontal: 20,\n paddingTop: 10,\n paddingBottom: Math.max(insets.bottom, 12),\n backgroundColor: bg,\n borderTopWidth: 1,\n borderTopColor: border,\n }}\n >\n {items.map((item: ITabBarItem<K>) => {\n const active = item.key === value;\n\n // Centre FAB — a content-width slot (NOT flex:1) so the four\n // side slots distribute evenly; the FAB is lifted in-flow.\n if (item.fab) {\n return (\n <Flex key={item.key} style={{alignItems: \"center\", justifyContent: \"center\"}}>\n <Pressable\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n hitSlop={8}\n style={({pressed}) => [\n {\n width: FAB_SIZE,\n height: FAB_SIZE,\n borderRadius: FAB_SIZE / 2,\n marginTop: -26,\n alignItems: \"center\",\n justifyContent: \"center\",\n backgroundColor: fabBg,\n borderWidth: 3,\n borderColor: bg,\n shadowColor: fabBg,\n shadowOffset: {width: 0, height: 6},\n shadowOpacity: 0.35,\n shadowRadius: 12,\n elevation: 8,\n },\n pressed && {opacity: 0.9},\n ]}\n >\n <Icon name={item.icon as never} size={26} color=\"#FFFFFF\" />\n </Pressable>\n </Flex>\n );\n }\n\n const color = active ? activeC : inactiveC;\n const iconName = active && item.activeIcon != null ? item.activeIcon : item.icon;\n\n return (\n <Pressable\n key={item.key}\n onPress={() => onChange(item.key)}\n accessibilityRole=\"button\"\n accessibilityState={{selected: active}}\n style={({pressed}) => [\n {\n flex: 1,\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: 4,\n paddingVertical: 6,\n paddingHorizontal: 4,\n minHeight: 44,\n },\n pressed && {opacity: 0.7},\n ]}\n >\n <View style={{alignItems: \"center\", justifyContent: \"center\", position: \"relative\"}}>\n <Icon name={iconName as never} size={24} color={color} />\n {item.badge != null && item.badge !== false && (\n <Badge badge={item.badge} barBg={bg} dangerColor={danger} />\n )}\n </View>\n {showLabels && item.label != null && (\n <Text numberOfLines={1} style={{fontSize: 11, fontWeight: \"500\", color, ...(rtlLineHeight != null ? {lineHeight: rtlLineHeight} : {})}}>\n {item.label}\n </Text>\n )}\n </Pressable>\n );\n })}\n </View>\n );\n}\n\nexport default BottomTabBar;\n"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ var index_native = require('../../assets/Icons/index.cjs');
|
|
|
7
7
|
var useSeverityColors = require('../../hooks/useSeverityColors.cjs');
|
|
8
8
|
require('../../contexts/DialogContext.cjs');
|
|
9
9
|
var useResolvedStyle = require('../../hooks/useResolvedStyle.cjs');
|
|
10
|
+
var useRtlLineHeight = require('../../hooks/useRtlLineHeight.cjs');
|
|
10
11
|
|
|
11
12
|
const SIZE_MAP = {
|
|
12
13
|
sm: { fontSize: 12, px: 8, py: 4, gap: 6, iconSize: 12, height: 24, removeSize: 12 },
|
|
@@ -55,6 +56,7 @@ function Chip(props) {
|
|
|
55
56
|
const sizeStr = String(rawSize ?? "md");
|
|
56
57
|
const size = sizeStr === "sm" || sizeStr === "lg" ? sizeStr : "md";
|
|
57
58
|
const sizeConfig = SIZE_MAP[size];
|
|
59
|
+
const rtlLineHeight = useRtlLineHeight.default(size, sizeConfig.fontSize);
|
|
58
60
|
const sevColors = useSeverityColors.useSeverityColors(severity);
|
|
59
61
|
const visual = React.useMemo(() => {
|
|
60
62
|
if (selected && !outlined) {
|
|
@@ -105,7 +107,17 @@ function Chip(props) {
|
|
|
105
107
|
style: {
|
|
106
108
|
fontSize: sizeConfig.fontSize,
|
|
107
109
|
fontWeight: "500",
|
|
108
|
-
color: visual.textColor
|
|
110
|
+
color: visual.textColor,
|
|
111
|
+
/* ⛔ ARABIC CLIPS WITHOUT AN EXPLICIT LINE BOX, AND THE
|
|
112
|
+
CHIP'S OWN HEIGHT DOES NOT SAVE IT. Every SIZE_MAP
|
|
113
|
+
row is already tall enough — 24/32/40 against font
|
|
114
|
+
sizes 12/14/16, all above the 1.5x this script needs.
|
|
115
|
+
The container was never the problem: React Native
|
|
116
|
+
gives this raw <Text> the FONT'S natural line box,
|
|
117
|
+
and NotoKufiArabic's is too short for its own
|
|
118
|
+
ascenders, so the glyph is cut inside a box with room
|
|
119
|
+
to spare. undefined in LTR — English is unchanged. */
|
|
120
|
+
...rtlLineHeight != null ? { lineHeight: rtlLineHeight } : {}
|
|
109
121
|
},
|
|
110
122
|
numberOfLines: 1,
|
|
111
123
|
children: content
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/Chip/index.native.tsx"],"sourcesContent":["import React, {useMemo} from \"react\";\nimport {Pressable, Text, View, StyleSheet} from \"react-native\";\nimport type {IChipProps, IconName} from \"@lmb-it/kitsconcerto-types\";\nimport {IconMap} from \"../../assets/Icons\";\nimport {useSeverityColors} from \"../../hooks/useSeverityColors\";\nimport {useResolvedStyle} from \"../../hooks\";\n\nconst SIZE_MAP = {\n sm: {fontSize: 12, px: 8, py: 4, gap: 6, iconSize: 12, height: 24, removeSize: 12},\n md: {fontSize: 14, px: 12, py: 6, gap: 6, iconSize: 14, height: 32, removeSize: 14},\n lg: {fontSize: 16, px: 14, py: 8, gap: 8, iconSize: 16, height: 40, removeSize: 16},\n} as const;\n\nfunction resolveIcon(icon: unknown, color: string, iconSize: number): React.ReactNode {\n if (!icon) return null;\n if (icon === \"dot\") {\n return (\n <View\n style={{\n width: 6,\n height: 6,\n borderRadius: 3,\n backgroundColor: color,\n }}\n />\n );\n }\n if (React.isValidElement(icon)) return icon;\n if (typeof icon !== \"string\") return null;\n const Component = IconMap[icon as IconName];\n if (Component) return <Component size={iconSize} color={color}/>;\n return null;\n}\n\nexport function Chip(props: IChipProps) {\n const {\n label,\n children,\n icon,\n selected = false,\n onPress,\n disabled = false,\n onRemove,\n severity = \"secondary\",\n size: rawSize,\n outlined,\n testID,\n style,\n // LEGIT-PLATFORM-ONLY (web): className is a CSS class hook with no\n // native equivalent — use `style` for cross-platform overrides.\n } = props;\n const resolvedStyle = useResolvedStyle(style || {});\n\n const sizeStr = String(rawSize ?? \"md\");\n const size: \"sm\" | \"md\" | \"lg\" = sizeStr === \"sm\" || sizeStr === \"lg\" ? sizeStr : \"md\";\n const sizeConfig = SIZE_MAP[size];\n\n const sevColors = useSeverityColors(severity as any);\n\n const visual = useMemo(() => {\n if (selected && !outlined) {\n return {\n backgroundColor: sevColors.solid,\n textColor: sevColors.solidText,\n borderColor: sevColors.border || sevColors.solid,\n };\n }\n if (outlined) {\n return {\n backgroundColor: \"transparent\",\n textColor: sevColors.solid,\n borderColor: sevColors.solid,\n };\n }\n return {\n backgroundColor: sevColors.bgTint,\n textColor: sevColors.text,\n borderColor: sevColors.border,\n };\n }, [selected, outlined, sevColors]);\n\n const resolvedIcon = resolveIcon(icon, visual.textColor, sizeConfig.iconSize);\n const content = label ?? children;\n const isInteractive = !!onPress && !disabled;\n\n const containerStyle = {\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n gap: sizeConfig.gap,\n height: sizeConfig.height,\n paddingHorizontal: sizeConfig.px,\n paddingRight: onRemove ? sizeConfig.gap : sizeConfig.px,\n borderRadius: 9999,\n borderWidth: 1,\n borderStyle: \"solid\" as const,\n backgroundColor: visual.backgroundColor,\n borderColor: visual.borderColor,\n opacity: disabled ? 0.5 : 1,\n // Consumer `style` wins last — mirrors web's computedCss merge order.\n ...(resolvedStyle as object),\n };\n\n const inner = (\n <>\n {resolvedIcon}\n {content != null && (\n <Text\n style={{\n fontSize: sizeConfig.fontSize,\n fontWeight: \"500\",\n color: visual.textColor,\n }}\n numberOfLines={1}\n >\n {content}\n </Text>\n )}\n {onRemove && (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel=\"Remove\"\n onPress={(e) => {\n e.stopPropagation?.();\n if (!disabled) onRemove();\n }}\n hitSlop={6}\n style={{\n marginLeft: 2,\n width: sizeConfig.removeSize + 4,\n height: sizeConfig.removeSize + 4,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: (sizeConfig.removeSize + 4) / 2,\n }}\n >\n <Text style={{fontSize: sizeConfig.removeSize, color: visual.textColor, lineHeight: sizeConfig.removeSize + 2}}>×</Text>\n </Pressable>\n )}\n </>\n );\n\n if (isInteractive) {\n return (\n <Pressable\n onPress={onPress}\n disabled={disabled}\n accessibilityRole=\"button\"\n accessibilityState={{selected, disabled}}\n testID={testID}\n style={({pressed}) => [containerStyle, pressed && styles.pressed]}\n >\n {inner}\n </Pressable>\n );\n }\n\n return (\n <View style={containerStyle} testID={testID}>\n {inner}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n pressed: {\n opacity: 0.7,\n },\n});\n\nexport default Chip;\n"],"names":["jsx","View","IconMap","useResolvedStyle","useSeverityColors","useMemo","jsxs","Fragment","Text","Pressable","StyleSheet"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/Chip/index.native.tsx"],"sourcesContent":["import React, {useMemo} from \"react\";\nimport {Pressable, Text, View, StyleSheet} from \"react-native\";\nimport type {IChipProps, IconName} from \"@lmb-it/kitsconcerto-types\";\nimport {IconMap} from \"../../assets/Icons\";\nimport {useSeverityColors} from \"../../hooks/useSeverityColors\";\nimport {useResolvedStyle} from \"../../hooks\";\nimport useRtlLineHeight from \"../../hooks/useRtlLineHeight\";\n\nconst SIZE_MAP = {\n sm: {fontSize: 12, px: 8, py: 4, gap: 6, iconSize: 12, height: 24, removeSize: 12},\n md: {fontSize: 14, px: 12, py: 6, gap: 6, iconSize: 14, height: 32, removeSize: 14},\n lg: {fontSize: 16, px: 14, py: 8, gap: 8, iconSize: 16, height: 40, removeSize: 16},\n} as const;\n\nfunction resolveIcon(icon: unknown, color: string, iconSize: number): React.ReactNode {\n if (!icon) return null;\n if (icon === \"dot\") {\n return (\n <View\n style={{\n width: 6,\n height: 6,\n borderRadius: 3,\n backgroundColor: color,\n }}\n />\n );\n }\n if (React.isValidElement(icon)) return icon;\n if (typeof icon !== \"string\") return null;\n const Component = IconMap[icon as IconName];\n if (Component) return <Component size={iconSize} color={color}/>;\n return null;\n}\n\nexport function Chip(props: IChipProps) {\n const {\n label,\n children,\n icon,\n selected = false,\n onPress,\n disabled = false,\n onRemove,\n severity = \"secondary\",\n size: rawSize,\n outlined,\n testID,\n style,\n // LEGIT-PLATFORM-ONLY (web): className is a CSS class hook with no\n // native equivalent — use `style` for cross-platform overrides.\n } = props;\n const resolvedStyle = useResolvedStyle(style || {});\n\n const sizeStr = String(rawSize ?? \"md\");\n const size: \"sm\" | \"md\" | \"lg\" = sizeStr === \"sm\" || sizeStr === \"lg\" ? sizeStr : \"md\";\n const sizeConfig = SIZE_MAP[size];\n\n // RTL only: NotoKufiArabic needs a taller line box than its own metrics\n // give it. `undefined` in LTR, so English chips are byte-identical.\n const rtlLineHeight = useRtlLineHeight(size as string, sizeConfig.fontSize);\n\n const sevColors = useSeverityColors(severity as any);\n\n const visual = useMemo(() => {\n if (selected && !outlined) {\n return {\n backgroundColor: sevColors.solid,\n textColor: sevColors.solidText,\n borderColor: sevColors.border || sevColors.solid,\n };\n }\n if (outlined) {\n return {\n backgroundColor: \"transparent\",\n textColor: sevColors.solid,\n borderColor: sevColors.solid,\n };\n }\n return {\n backgroundColor: sevColors.bgTint,\n textColor: sevColors.text,\n borderColor: sevColors.border,\n };\n }, [selected, outlined, sevColors]);\n\n const resolvedIcon = resolveIcon(icon, visual.textColor, sizeConfig.iconSize);\n const content = label ?? children;\n const isInteractive = !!onPress && !disabled;\n\n const containerStyle = {\n flexDirection: \"row\" as const,\n alignItems: \"center\" as const,\n justifyContent: \"center\" as const,\n gap: sizeConfig.gap,\n height: sizeConfig.height,\n paddingHorizontal: sizeConfig.px,\n paddingRight: onRemove ? sizeConfig.gap : sizeConfig.px,\n borderRadius: 9999,\n borderWidth: 1,\n borderStyle: \"solid\" as const,\n backgroundColor: visual.backgroundColor,\n borderColor: visual.borderColor,\n opacity: disabled ? 0.5 : 1,\n // Consumer `style` wins last — mirrors web's computedCss merge order.\n ...(resolvedStyle as object),\n };\n\n const inner = (\n <>\n {resolvedIcon}\n {content != null && (\n <Text\n style={{\n fontSize: sizeConfig.fontSize,\n fontWeight: \"500\",\n color: visual.textColor,\n /* ⛔ ARABIC CLIPS WITHOUT AN EXPLICIT LINE BOX, AND THE\n CHIP'S OWN HEIGHT DOES NOT SAVE IT. Every SIZE_MAP\n row is already tall enough — 24/32/40 against font\n sizes 12/14/16, all above the 1.5x this script needs.\n The container was never the problem: React Native\n gives this raw <Text> the FONT'S natural line box,\n and NotoKufiArabic's is too short for its own\n ascenders, so the glyph is cut inside a box with room\n to spare. undefined in LTR — English is unchanged. */\n ...(rtlLineHeight != null ? {lineHeight: rtlLineHeight} : {}),\n }}\n numberOfLines={1}\n >\n {content}\n </Text>\n )}\n {onRemove && (\n <Pressable\n accessibilityRole=\"button\"\n accessibilityLabel=\"Remove\"\n onPress={(e) => {\n e.stopPropagation?.();\n if (!disabled) onRemove();\n }}\n hitSlop={6}\n style={{\n marginLeft: 2,\n width: sizeConfig.removeSize + 4,\n height: sizeConfig.removeSize + 4,\n alignItems: \"center\",\n justifyContent: \"center\",\n borderRadius: (sizeConfig.removeSize + 4) / 2,\n }}\n >\n <Text style={{fontSize: sizeConfig.removeSize, color: visual.textColor, lineHeight: sizeConfig.removeSize + 2}}>×</Text>\n </Pressable>\n )}\n </>\n );\n\n if (isInteractive) {\n return (\n <Pressable\n onPress={onPress}\n disabled={disabled}\n accessibilityRole=\"button\"\n accessibilityState={{selected, disabled}}\n testID={testID}\n style={({pressed}) => [containerStyle, pressed && styles.pressed]}\n >\n {inner}\n </Pressable>\n );\n }\n\n return (\n <View style={containerStyle} testID={testID}>\n {inner}\n </View>\n );\n}\n\nconst styles = StyleSheet.create({\n pressed: {\n opacity: 0.7,\n },\n});\n\nexport default Chip;\n"],"names":["jsx","View","IconMap","useResolvedStyle","useRtlLineHeight","useSeverityColors","useMemo","jsxs","Fragment","Text","Pressable","StyleSheet"],"mappings":"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"}
|