@hjmds/react-native 1.17.2 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/dist/actions.d.ts +3 -23
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +8 -11
- package/dist/actions.js.map +1 -1
- package/dist/activity-chip.d.ts +29 -0
- package/dist/activity-chip.d.ts.map +1 -0
- package/dist/activity-chip.js +54 -0
- package/dist/activity-chip.js.map +1 -0
- package/dist/agreement.d.ts +1 -7
- package/dist/agreement.d.ts.map +1 -1
- package/dist/agreement.js +21 -15
- package/dist/agreement.js.map +1 -1
- package/dist/asset.d.ts +2 -13
- package/dist/asset.d.ts.map +1 -1
- package/dist/asset.js +4 -7
- package/dist/asset.js.map +1 -1
- package/dist/bottom-info.d.ts +1 -7
- package/dist/bottom-info.d.ts.map +1 -1
- package/dist/bottom-info.js +2 -4
- package/dist/bottom-info.js.map +1 -1
- package/dist/carousel-motion.d.ts +1 -0
- package/dist/carousel-motion.d.ts.map +1 -1
- package/dist/carousel-motion.js +5 -3
- package/dist/carousel-motion.js.map +1 -1
- package/dist/carousel.d.ts +1 -7
- package/dist/carousel.d.ts.map +1 -1
- package/dist/carousel.js +14 -6
- package/dist/carousel.js.map +1 -1
- package/dist/collapsible.d.ts +1 -7
- package/dist/collapsible.d.ts.map +1 -1
- package/dist/collapsible.js +4 -4
- package/dist/collapsible.js.map +1 -1
- package/dist/content-transition.d.ts +2 -1
- package/dist/content-transition.d.ts.map +1 -1
- package/dist/content-transition.js +3 -3
- package/dist/content-transition.js.map +1 -1
- package/dist/data-display.d.ts +23 -154
- package/dist/data-display.d.ts.map +1 -1
- package/dist/data-display.js +86 -92
- package/dist/data-display.js.map +1 -1
- package/dist/date-entry.d.ts +1 -0
- package/dist/date-entry.d.ts.map +1 -1
- package/dist/date-entry.js +22 -20
- package/dist/date-entry.js.map +1 -1
- package/dist/date-picker.d.ts +1 -7
- package/dist/date-picker.d.ts.map +1 -1
- package/dist/date-picker.js +19 -11
- package/dist/date-picker.js.map +1 -1
- package/dist/duration-field.d.ts +1 -1
- package/dist/duration-field.d.ts.map +1 -1
- package/dist/duration-field.js +11 -9
- package/dist/duration-field.js.map +1 -1
- package/dist/evidence.d.ts +1 -1
- package/dist/evidence.js +1 -1
- package/dist/feedback.d.ts +9 -88
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +124 -81
- package/dist/feedback.js.map +1 -1
- package/dist/field-group.d.ts +3 -2
- package/dist/field-group.d.ts.map +1 -1
- package/dist/field-group.js +7 -4
- package/dist/field-group.js.map +1 -1
- package/dist/file-picker.d.ts +1 -7
- package/dist/file-picker.d.ts.map +1 -1
- package/dist/file-picker.js +21 -11
- package/dist/file-picker.js.map +1 -1
- package/dist/forms.d.ts +6 -21
- package/dist/forms.d.ts.map +1 -1
- package/dist/forms.js +29 -35
- package/dist/forms.js.map +1 -1
- package/dist/gravity-letters.d.ts.map +1 -1
- package/dist/gravity-letters.js +13 -5
- package/dist/gravity-letters.js.map +1 -1
- package/dist/grid-reveal.d.ts.map +1 -1
- package/dist/grid-reveal.js +10 -2
- package/dist/grid-reveal.js.map +1 -1
- package/dist/heading.d.ts +1 -7
- package/dist/heading.d.ts.map +1 -1
- package/dist/heading.js +1 -4
- package/dist/heading.js.map +1 -1
- package/dist/image-viewer.d.ts.map +1 -1
- package/dist/image-viewer.js +2 -1
- package/dist/image-viewer.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/inline-confirm.d.ts.map +1 -1
- package/dist/inline-confirm.js +5 -1
- package/dist/inline-confirm.js.map +1 -1
- package/dist/inputs.d.ts +4 -71
- package/dist/inputs.d.ts.map +1 -1
- package/dist/inputs.js +52 -67
- package/dist/inputs.js.map +1 -1
- package/dist/internal/accessible-focus.d.ts +3 -0
- package/dist/internal/accessible-focus.d.ts.map +1 -0
- package/dist/internal/accessible-focus.js +15 -0
- package/dist/internal/accessible-focus.js.map +1 -0
- package/dist/internal/diagnostics.d.ts +7 -0
- package/dist/internal/diagnostics.d.ts.map +1 -0
- package/dist/internal/diagnostics.js +20 -0
- package/dist/internal/diagnostics.js.map +1 -0
- package/dist/internal/document-resource.d.ts.map +1 -1
- package/dist/internal/document-resource.js +2 -2
- package/dist/internal/document-resource.js.map +1 -1
- package/dist/internal/recipe-button.js +1 -1
- package/dist/internal/recipe-button.js.map +1 -1
- package/dist/internal/spinner.d.ts +1 -7
- package/dist/internal/spinner.d.ts.map +1 -1
- package/dist/internal/spinner.js +2 -4
- package/dist/internal/spinner.js.map +1 -1
- package/dist/masonry.d.ts.map +1 -1
- package/dist/masonry.js +2 -1
- package/dist/masonry.js.map +1 -1
- package/dist/mentions.d.ts +1 -7
- package/dist/mentions.d.ts.map +1 -1
- package/dist/mentions.js +11 -7
- package/dist/mentions.js.map +1 -1
- package/dist/navigation.d.ts +4 -74
- package/dist/navigation.d.ts.map +1 -1
- package/dist/navigation.js +86 -45
- package/dist/navigation.js.map +1 -1
- package/dist/number-field.d.ts +1 -21
- package/dist/number-field.d.ts.map +1 -1
- package/dist/number-field.js +6 -5
- package/dist/number-field.js.map +1 -1
- package/dist/overlays.d.ts +7 -16
- package/dist/overlays.d.ts.map +1 -1
- package/dist/overlays.js +220 -213
- package/dist/overlays.js.map +1 -1
- package/dist/primitives.d.ts +3 -18
- package/dist/primitives.d.ts.map +1 -1
- package/dist/primitives.js +8 -10
- package/dist/primitives.js.map +1 -1
- package/dist/provider-button.d.ts +1 -7
- package/dist/provider-button.d.ts.map +1 -1
- package/dist/provider-button.js +1 -4
- package/dist/provider-button.js.map +1 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +9 -1
- package/dist/provider.js.map +1 -1
- package/dist/saved-items.d.ts.map +1 -1
- package/dist/saved-items.js +6 -1
- package/dist/saved-items.js.map +1 -1
- package/dist/screen-flows.d.ts +1 -2
- package/dist/screen-flows.d.ts.map +1 -1
- package/dist/screen-flows.js +60 -16
- package/dist/screen-flows.js.map +1 -1
- package/dist/screens.d.ts +1 -1
- package/dist/screens.d.ts.map +1 -1
- package/dist/screens.js +32 -15
- package/dist/screens.js.map +1 -1
- package/dist/sheet-gesture.d.ts.map +1 -1
- package/dist/sheet-gesture.js +6 -3
- package/dist/sheet-gesture.js.map +1 -1
- package/dist/slider.d.ts +1 -21
- package/dist/slider.d.ts.map +1 -1
- package/dist/slider.js +3 -5
- package/dist/slider.js.map +1 -1
- package/dist/sortable.d.ts.map +1 -1
- package/dist/sortable.js +2 -1
- package/dist/sortable.js.map +1 -1
- package/dist/status-text.d.ts +17 -0
- package/dist/status-text.d.ts.map +1 -0
- package/dist/status-text.js +18 -0
- package/dist/status-text.js.map +1 -0
- package/dist/steps.d.ts +1 -7
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +2 -4
- package/dist/steps.js.map +1 -1
- package/dist/swipe-actions.d.ts.map +1 -1
- package/dist/swipe-actions.js +13 -2
- package/dist/swipe-actions.js.map +1 -1
- package/dist/tags-input.d.ts +1 -7
- package/dist/tags-input.d.ts.map +1 -1
- package/dist/tags-input.js +2 -4
- package/dist/tags-input.js.map +1 -1
- package/dist/toggle-group.d.ts +1 -7
- package/dist/toggle-group.d.ts.map +1 -1
- package/dist/toggle-group.js +10 -5
- package/dist/toggle-group.js.map +1 -1
- package/dist/top.d.ts +1 -7
- package/dist/top.d.ts.map +1 -1
- package/dist/top.js +1 -4
- package/dist/top.js.map +1 -1
- package/dist/transfer-list.d.ts +2 -8
- package/dist/transfer-list.d.ts.map +1 -1
- package/dist/transfer-list.js +30 -11
- package/dist/transfer-list.js.map +1 -1
- package/dist/upload-item.d.ts +1 -7
- package/dist/upload-item.d.ts.map +1 -1
- package/dist/upload-item.js +2 -4
- package/dist/upload-item.js.map +1 -1
- package/dist/virtual-list.d.ts.map +1 -1
- package/dist/virtual-list.js +2 -1
- package/dist/virtual-list.js.map +1 -1
- package/docs/liquid-toast.md +20 -0
- package/package.json +17 -4
- package/dist/internal/deprecated-style.d.ts +0 -8
- package/dist/internal/deprecated-style.d.ts.map +0 -1
- package/dist/internal/deprecated-style.js +0 -34
- package/dist/internal/deprecated-style.js.map +0 -1
package/dist/data-display.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { assertNoRemovedStyleProps } from "./internal/diagnostics.js";
|
|
2
3
|
import { resolveAvatarInitials } from "@hjmds/design-contracts/avatar-fallback";
|
|
3
4
|
import { resolveColorReference } from "@hjmds/design-contracts/color-references";
|
|
4
5
|
import { fontWeight, glyph, radius, spacing } from "@hjmds/design-contracts/foundations";
|
|
5
6
|
import { resolveDescriptionListColumnCount, resolveDescriptionListDescriptor, } from "@hjmds/design-contracts/components/description-list";
|
|
6
7
|
import { resolveStatisticDescriptor, validateStatisticGroup, } from "@hjmds/design-contracts/components/statistic";
|
|
7
8
|
import { resolveTagDescriptor, resolveTagPresentation, tagRecipe, } from "@hjmds/design-contracts/components/tag";
|
|
8
|
-
import { warnDeprecatedStyleProps } from "./internal/deprecated-style.js";
|
|
9
9
|
import { cardRecipe } from "@hjmds/design-contracts/components/card";
|
|
10
10
|
import { imageRecipe, nativeResizeModes, resolveImageAspectRatio, resolveImageDescriptor, resolveImageFallbackAccessibilityLabel, } from "@hjmds/design-contracts/components/image";
|
|
11
11
|
import { resolveTimelineDescriptor, timelineRecipe, } from "@hjmds/design-contracts/components/timeline";
|
|
12
12
|
import { surfaceDefaults, surfaceGeometry } from "@hjmds/design-contracts/recipes/base";
|
|
13
13
|
import { accordionRecipe, counterBadgeRecipe, badgeRecipe, listRecipe, formatCounterBadgeCount, listRowRecipe, statisticRecipe, } from "@hjmds/design-contracts/recipes";
|
|
14
|
-
import { Children, isValidElement, useEffect, useMemo, useRef, useState, } from "react";
|
|
14
|
+
import { Children, isValidElement, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
|
|
15
15
|
import { Image as NativeImage, LayoutAnimation, Pressable, StyleSheet, View, useWindowDimensions, } from "react-native";
|
|
16
16
|
import { useControllableState } from "./internal/state.js";
|
|
17
17
|
import { minimumTargetStyle } from "./internal/styles.js";
|
|
18
18
|
import { webDisclosureProps, webOnly } from "./internal/web-a11y.js";
|
|
19
19
|
import { Surface, Text, } from "./primitives.js";
|
|
20
20
|
import { useHjmNativeTheme } from "./provider.js";
|
|
21
|
-
export function Badge({ label, tone = badgeRecipe.defaults.tone, size = badgeRecipe.defaults.size, variant = badgeRecipe.defaults.variant, leading, accessibilityLabel,
|
|
22
|
-
|
|
21
|
+
export function Badge({ label, tone = badgeRecipe.defaults.tone, size = badgeRecipe.defaults.size, variant = badgeRecipe.defaults.variant, leading, accessibilityLabel, layoutStyle, ...props }) {
|
|
22
|
+
assertNoRemovedStyleProps("Badge", props, ["style", "labelStyle"]);
|
|
23
23
|
const theme = useHjmNativeTheme();
|
|
24
24
|
const presentation = badgeRecipe.tones[tone];
|
|
25
25
|
const metrics = badgeRecipe.sizes[size];
|
|
@@ -49,17 +49,15 @@ export function Badge({ label, tone = badgeRecipe.defaults.tone, size = badgeRec
|
|
|
49
49
|
minHeight: metrics.minHeight,
|
|
50
50
|
paddingHorizontal: metrics.paddingHorizontal,
|
|
51
51
|
},
|
|
52
|
-
style,
|
|
53
52
|
layoutStyle,
|
|
54
53
|
], children: [leading === undefined ? null : (_jsx(View, { accessibilityElementsHidden: true, accessible: false, importantForAccessibility: "no-hide-descendants", children: leading })), _jsx(Text, { accessible: false, align: "center", emphasis: "strong", style: [
|
|
55
54
|
{
|
|
56
55
|
color: resolveColorReference(outlined ? presentation.outlineContent : presentation.content, theme.palette),
|
|
57
56
|
},
|
|
58
|
-
labelStyle,
|
|
59
57
|
], variant: metrics.textVariant, children: label })] }));
|
|
60
58
|
}
|
|
61
|
-
export function Tag({ children, tone, accessibilityLabel, layoutStyle,
|
|
62
|
-
|
|
59
|
+
export function Tag({ children, tone, accessibilityLabel, layoutStyle, ...props }) {
|
|
60
|
+
assertNoRemovedStyleProps("Tag", props, ["style", "labelStyle"]);
|
|
63
61
|
const theme = useHjmNativeTheme();
|
|
64
62
|
const resolvedLabel = children;
|
|
65
63
|
if (resolvedLabel === undefined) {
|
|
@@ -84,15 +82,17 @@ export function Tag({ children, tone, accessibilityLabel, layoutStyle, style, la
|
|
|
84
82
|
minHeight: tagRecipe.size.minHeight,
|
|
85
83
|
paddingHorizontal: tagRecipe.size.paddingHorizontal,
|
|
86
84
|
},
|
|
87
|
-
style,
|
|
88
85
|
layoutStyle,
|
|
89
|
-
], children: _jsx(Text, { align: "center", emphasis: "medium", style: [{ color: presentation.content }
|
|
86
|
+
], children: _jsx(Text, { align: "center", emphasis: "medium", style: [{ color: presentation.content }], variant: tagRecipe.size.textVariant, children: descriptor.label }) }));
|
|
90
87
|
}
|
|
91
|
-
export function Card({ children, title, description, leading, media, actions, selected = cardRecipe.defaults.selected, tone = cardRecipe.defaults.tone, bordered = cardRecipe.defaults.bordered, padding = cardRecipe.defaults.padding, layoutStyle, radius: cornerRadius = surfaceDefaults.radius, ...props }) {
|
|
88
|
+
export function Card({ children, title, description, leading, media, actions, selected = cardRecipe.defaults.selected, onActivate, disabled = false, accessibilityLabel, accessibilityHint, tone = cardRecipe.defaults.tone, bordered = cardRecipe.defaults.bordered, padding = cardRecipe.defaults.padding, layoutStyle, radius: cornerRadius = surfaceDefaults.radius, ...props }) {
|
|
92
89
|
const { environment, tokens } = useHjmNativeTheme();
|
|
90
|
+
if (onActivate && (!accessibilityLabel?.trim() || actions !== undefined)) {
|
|
91
|
+
throw new TypeError("Interactive Card requires accessibilityLabel and no actions");
|
|
92
|
+
}
|
|
93
93
|
const bodyPadding = surfaceGeometry.paddings[padding];
|
|
94
94
|
const hasHeader = leading !== undefined || title !== undefined || description !== undefined;
|
|
95
|
-
|
|
95
|
+
const frame = (_jsx(Surface, { ...props, bordered: bordered, padding: "none", radius: cornerRadius, ...(onActivate ? {} : { accessibilityLabel, accessibilityHint }), ...(layoutStyle === undefined || onActivate ? {} : { layoutStyle }), tone: selected ? cardRecipe.selectedTone : tone, children: _jsxs(View, { style: {
|
|
96
96
|
overflow: "hidden",
|
|
97
97
|
borderRadius: tokens.radius[cornerRadius],
|
|
98
98
|
}, children: [media === undefined ? null : _jsx(View, { children: media }), _jsxs(View, { style: { gap: cardRecipe.body.gap, padding: bodyPadding }, children: [hasHeader ? (_jsxs(View, { style: {
|
|
@@ -108,10 +108,18 @@ export function Card({ children, title, description, leading, media, actions, se
|
|
|
108
108
|
paddingBottom: cardRecipe.actions.paddingBottom,
|
|
109
109
|
paddingHorizontal: cardRecipe.actions.paddingHorizontal,
|
|
110
110
|
}, children: actions }))] }) }));
|
|
111
|
+
if (!onActivate)
|
|
112
|
+
return frame;
|
|
113
|
+
// Keep Surface's material/clip inside one native action host. App-owned wrappers
|
|
114
|
+
// previously had to reinvent disabled/selected naming and press feedback.
|
|
115
|
+
return _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: accessibilityLabel, accessibilityHint: accessibilityHint, accessibilityState: { selected, disabled }, disabled: disabled, onPress: () => { if (!disabled)
|
|
116
|
+
onActivate(); }, style: ({ pressed }) => [minimumTargetStyle, {
|
|
117
|
+
opacity: disabled ? cardRecipe.interaction.disabledOpacity : pressed ? cardRecipe.interaction.pressedOpacity : 1,
|
|
118
|
+
}, layoutStyle], children: frame });
|
|
111
119
|
}
|
|
112
|
-
export function ListRow({ title, description, leading, trailing, titleMetadata, trailingAction, trailingText, metadataLabel, trailingLabel, onPress, accessibilityLabel, accessibilityHint, disabled = false, density = listRowRecipe.defaults.density, selected: selectedProp, leadingShape = "square", layoutStyle, leadingStyle, contentStyle,
|
|
120
|
+
export function ListRow({ title, tone = listRowRecipe.defaults.tone, description, leading, trailing, titleMetadata, trailingAction, trailingText, metadataLabel, trailingLabel, onPress, accessibilityLabel, accessibilityHint, disabled = false, density = listRowRecipe.defaults.density, loading = false, loadingLabel, selected: selectedProp, leadingShape = "square", layoutStyle, leadingStyle, contentStyle, titleRowStyle, trailingStyle, trailingActionStyle, containerProps, accessibilityState, ...forwarded }) {
|
|
121
|
+
assertNoRemovedStyleProps("ListRow", forwarded, ["titleStyle", "descriptionStyle"]);
|
|
113
122
|
const { hjmTitleEmphasis, ...props } = forwarded;
|
|
114
|
-
warnDeprecatedStyleProps("ListRow", { titleStyle, descriptionStyle }, "density/selected and the listRowRecipe typography for appearance");
|
|
115
123
|
const theme = useHjmNativeTheme();
|
|
116
124
|
const metrics = listRowRecipe.density[density];
|
|
117
125
|
const interactive = onPress !== undefined;
|
|
@@ -144,6 +152,15 @@ export function ListRow({ title, description, leading, trailing, titleMetadata,
|
|
|
144
152
|
width: listRowRecipe.leadingSize,
|
|
145
153
|
...(leadingRadius === null ? {} : { borderRadius: theme.tokens.radius[leadingRadius] }),
|
|
146
154
|
};
|
|
155
|
+
if (loading) {
|
|
156
|
+
// Search and other collections share ListRow geometry instead of approximating it with
|
|
157
|
+
// loose Skeletons. Never mount placeholder actions or forward touch handlers while loading.
|
|
158
|
+
const placeholder = { backgroundColor: theme.colors.surfaceAlt, borderRadius: theme.tokens.radius.sm };
|
|
159
|
+
return _jsxs(View, { testID: props.testID, onLayout: props.onLayout, accessible: Boolean(loadingLabel), accessibilityRole: "progressbar", accessibilityLabel: loadingLabel, accessibilityState: { busy: true }, importantForAccessibility: loadingLabel ? "yes" : "no-hide-descendants", style: [{ alignItems: "center", flexDirection: "row", direction: theme.environment.direction,
|
|
160
|
+
gap: listRowRecipe.gap, minHeight: visualState.minHeight,
|
|
161
|
+
paddingHorizontal: metrics.paddingHorizontal, paddingVertical: metrics.paddingVertical,
|
|
162
|
+
borderWidth: 1, borderColor: "transparent" }, layoutStyle], children: [leading ? _jsx(View, { style: [placeholder, leadingFrameStyle] }) : null, _jsxs(View, { style: { flex: 1, minWidth: 0, gap: spacing.xxs }, children: [_jsx(View, { style: [placeholder, { width: `${listRowRecipe.loading.titleWidthPercent}%`, height: theme.tokens.typography[listRowRecipe.title.textVariant].lineHeight }] }), description ? _jsx(View, { style: [placeholder, { width: `${listRowRecipe.loading.descriptionWidthPercent}%`, height: theme.tokens.typography[listRowRecipe.description.textVariant].lineHeight }] }) : null] }), trailing || trailingText ? _jsx(View, { style: [placeholder, { width: listRowRecipe.loading.trailingWidth, height: theme.tokens.typography[listRowRecipe.trailing.textVariant].lineHeight }] }) : null] });
|
|
163
|
+
}
|
|
147
164
|
const rowContent = (_jsxs(_Fragment, { children: [leading ? (_jsx(View, { accessible: interactive ? false : undefined, importantForAccessibility: interactive ? "no-hide-descendants" : "auto", style: [leadingFrameStyle, leadingStyle], children: leading })) : null, _jsxs(View, { style: [{ flex: 1, gap: spacing.xxs, minWidth: 0 }, contentStyle], children: [_jsxs(View, { style: [
|
|
148
165
|
{
|
|
149
166
|
alignItems: "center",
|
|
@@ -155,14 +172,12 @@ export function ListRow({ title, description, leading, trailing, titleMetadata,
|
|
|
155
172
|
titleRowStyle,
|
|
156
173
|
], children: [_jsx(Text, { style: [
|
|
157
174
|
{
|
|
158
|
-
color: resolveColorReference(listRowRecipe.
|
|
175
|
+
color: resolveColorReference(listRowRecipe.tones[tone].titleColor, theme.palette),
|
|
159
176
|
flexShrink: 1,
|
|
160
177
|
fontWeight: hjmTitleEmphasis === "regular" ? fontWeight.regular : listRowRecipe.title.fontWeight,
|
|
161
178
|
},
|
|
162
|
-
titleStyle,
|
|
163
179
|
], variant: listRowRecipe.title.textVariant, children: title }), resolvedMetadata === undefined ? null : (_jsx(View, { accessible: interactive ? false : undefined, importantForAccessibility: interactive ? "no-hide-descendants" : "auto", children: resolvedMetadata }))] }), description ? (_jsx(Text, { style: [
|
|
164
180
|
{ color: resolveColorReference(listRowRecipe.description.color, theme.palette) },
|
|
165
|
-
descriptionStyle,
|
|
166
181
|
], variant: listRowRecipe.description.textVariant, children: description })) : null] }), trailingText || trailing ? (_jsx(View, { accessible: interactive ? false : undefined, importantForAccessibility: interactive ? "no-hide-descendants" : "auto", style: [{ flexShrink: 0 }, trailingStyle], children: trailingText ? (_jsx(Text, { style: { color: resolveColorReference(listRowRecipe.trailing.textColor, theme.palette) }, variant: listRowRecipe.trailing.textVariant, children: trailingText })) : trailing })) : null] }));
|
|
167
182
|
const contentStyleFor = (pressed) => [
|
|
168
183
|
minimumTargetStyle,
|
|
@@ -212,10 +227,9 @@ export function ListRow({ title, description, leading, trailing, titleMetadata,
|
|
|
212
227
|
trailingActionStyle,
|
|
213
228
|
], children: trailingAction })] }));
|
|
214
229
|
}
|
|
215
|
-
export function Avatar({ source, renderImage, name, initials, renderFallback, size = 44, decorative = false, accessibilityLabel,
|
|
230
|
+
export function Avatar({ source, renderImage, name, initials, renderFallback, size = 44, decorative = false, accessibilityLabel, layoutStyle, }) {
|
|
216
231
|
if (!Number.isFinite(size) || size < 24)
|
|
217
232
|
throw new RangeError("Avatar size must be at least 24");
|
|
218
|
-
warnDeprecatedStyleProps("Avatar", { style, imageStyle }, "layoutStyle for placement and size/renderFallback for appearance");
|
|
219
233
|
const { colors } = useHjmNativeTheme();
|
|
220
234
|
const sourceKey = source === undefined ? "none" : resolveImageSourceKey(source);
|
|
221
235
|
const [failedSource, setFailedSource] = useState(null);
|
|
@@ -248,55 +262,55 @@ export function Avatar({ source, renderImage, name, initials, renderFallback, si
|
|
|
248
262
|
overflow: "hidden",
|
|
249
263
|
width: size,
|
|
250
264
|
},
|
|
251
|
-
style,
|
|
252
265
|
layoutStyle,
|
|
253
266
|
], children: source !== undefined && !failed ? (renderImage ? (_jsx(View, { accessible: false, accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", style: { height: size, width: size }, children: renderImage({ source, size, onError: failImage,
|
|
254
|
-
fallback: renderFallback?.({ size, decorative: true }) ?? _jsx(Text, { align: "center", style: { color: colors.contentBrand }, variant: "label", children: fallback }) }) })) : (_jsx(NativeImage, { accessible: false, onError: failImage, source: source, style: [{ height: size, width: size }
|
|
267
|
+
fallback: renderFallback?.({ size, decorative: true }) ?? _jsx(Text, { align: "center", style: { color: colors.contentBrand }, variant: "label", children: fallback }) }) })) : (_jsx(NativeImage, { accessible: false, onError: failImage, source: source, style: [{ height: size, width: size }] }))) : (_jsx(View, { accessible: false, accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: renderFallback?.({ size, decorative: true }) ?? _jsx(Text, { align: "center", style: { color: colors.contentBrand }, variant: "label", children: fallback }) })) }));
|
|
255
268
|
}
|
|
256
|
-
export function Divider({ orientation = "horizontal", inset = 0,
|
|
269
|
+
export function Divider({ orientation = "horizontal", inset = 0, layoutStyle }) {
|
|
257
270
|
if (!Number.isFinite(inset) || inset < 0)
|
|
258
271
|
throw new RangeError("Divider inset must be non-negative");
|
|
259
|
-
warnDeprecatedStyleProps("Divider", { style }, "layoutStyle for placement and orientation/inset for appearance");
|
|
260
272
|
const { colors } = useHjmNativeTheme();
|
|
261
273
|
return (_jsx(View, { accessible: false, style: [
|
|
262
274
|
orientation === "horizontal"
|
|
263
275
|
? { backgroundColor: colors.border, height: 1, marginHorizontal: inset, width: "auto" }
|
|
264
276
|
: { alignSelf: "stretch", backgroundColor: colors.border, marginVertical: inset, width: 1 },
|
|
265
|
-
style,
|
|
266
277
|
layoutStyle,
|
|
267
278
|
] }));
|
|
268
279
|
}
|
|
269
280
|
// UI control labels keep the ui font even when their metric variant is body; content still uses reading.
|
|
270
|
-
export function Accordion({ label, items, expandedValues, defaultExpandedValues = [], onExpandedValuesChange, multiple = accordionRecipe.defaults.allowsMultipleExpanded, density = accordionRecipe.defaults.density, renderIndicator,
|
|
271
|
-
warnDeprecatedStyleProps("Accordion", { style, itemStyle, triggerStyle, titleStyle, indicatorStyle, panelStyle }, "layoutStyle for placement and density/renderIndicator for appearance");
|
|
281
|
+
export function Accordion({ label, items, expandedValues, defaultExpandedValues = [], onExpandedValuesChange, multiple = accordionRecipe.defaults.allowsMultipleExpanded, density = accordionRecipe.defaults.density, renderIndicator, layoutStyle, }) {
|
|
272
282
|
if (items.length === 0)
|
|
273
283
|
throw new Error("Accordion requires at least one item");
|
|
274
284
|
const itemValues = new Set(items.map((item) => item.value));
|
|
275
285
|
if (itemValues.size !== items.length)
|
|
276
286
|
throw new TypeError("Accordion values must be unique");
|
|
277
|
-
const initial = expandedValues ?? defaultExpandedValues;
|
|
278
|
-
if (initial.some((value) => !itemValues.has(value))) {
|
|
279
|
-
throw new RangeError("Accordion expanded values must match items");
|
|
280
|
-
}
|
|
281
|
-
if (!multiple && initial.length > 1) {
|
|
282
|
-
throw new RangeError("Accordion only accepts one expanded value unless multiple is true");
|
|
283
|
-
}
|
|
284
287
|
const theme = useHjmNativeTheme();
|
|
285
288
|
const metrics = accordionRecipe.density[density];
|
|
286
289
|
const indicatorColor = resolveColorReference(accordionRecipe.indicator.color, theme.palette);
|
|
287
|
-
const [
|
|
290
|
+
const [storedExpanded, setExpanded] = useControllableState({
|
|
288
291
|
...(expandedValues === undefined ? {} : { value: expandedValues }),
|
|
289
292
|
defaultValue: defaultExpandedValues,
|
|
290
293
|
...(onExpandedValuesChange === undefined ? {} : { onChange: onExpandedValuesChange }),
|
|
291
294
|
});
|
|
292
|
-
|
|
295
|
+
const committed = useRef(false);
|
|
296
|
+
const expanded = expandedValues === undefined && committed.current ? storedExpanded.filter(value => itemValues.has(value)) : storedExpanded;
|
|
297
|
+
if (expanded.some(value => !itemValues.has(value)))
|
|
298
|
+
throw new RangeError("Accordion expanded values must match items");
|
|
299
|
+
if (!multiple && expanded.length > 1)
|
|
300
|
+
throw new RangeError("Accordion only accepts one expanded value unless multiple is true");
|
|
301
|
+
useLayoutEffect(() => {
|
|
302
|
+
committed.current = true;
|
|
303
|
+
// Retire expansion with the deleted item instead of reopening it when its key returns.
|
|
304
|
+
if (expanded.length !== storedExpanded.length)
|
|
305
|
+
setExpanded(expanded);
|
|
306
|
+
}, [expanded, storedExpanded, setExpanded]);
|
|
307
|
+
return (_jsx(View, { accessibilityLabel: label, accessibilityRole: "list", style: [layoutStyle], children: items.map((item) => {
|
|
293
308
|
const isExpanded = expanded.includes(item.value);
|
|
294
309
|
return (_jsxs(View, { style: [
|
|
295
310
|
{
|
|
296
311
|
borderBottomColor: resolveColorReference(accordionRecipe.divider, theme.palette),
|
|
297
312
|
borderBottomWidth: 1,
|
|
298
313
|
},
|
|
299
|
-
itemStyle,
|
|
300
314
|
], children: [_jsxs(Pressable, { accessibilityHint: item.accessibilityHint, accessibilityLabel: item.accessibilityLabel ?? item.title, accessibilityRole: "button", accessibilityState: { disabled: item.disabled === true, expanded: isExpanded }, ...webOnly(webDisclosureProps(isExpanded, item.disabled === true)), disabled: item.disabled, onPress: () => {
|
|
301
315
|
if (!theme.environment.reducedMotion) {
|
|
302
316
|
LayoutAnimation.configureNext({
|
|
@@ -327,14 +341,12 @@ export function Accordion({ label, items, expandedValues, defaultExpandedValues
|
|
|
327
341
|
paddingHorizontal: accordionRecipe.paddingHorizontal,
|
|
328
342
|
paddingVertical: metrics.paddingVertical,
|
|
329
343
|
},
|
|
330
|
-
triggerStyle,
|
|
331
344
|
], children: [_jsxs(View, { style: { flex: 1, gap: spacing.xxs }, children: [_jsx(Text, { fontRole: "ui", style: [
|
|
332
345
|
{
|
|
333
346
|
color: resolveColorReference(accordionRecipe.title.color, theme.palette),
|
|
334
347
|
fontWeight: accordionRecipe.title.fontWeight,
|
|
335
348
|
},
|
|
336
|
-
|
|
337
|
-
], variant: accordionRecipe.title.textVariant, children: item.title }), item.description ? _jsx(Text, { tone: "muted", variant: "caption", children: item.description }) : null] }), _jsx(View, { accessible: false, style: indicatorStyle, children: renderIndicator ? (renderIndicator({
|
|
349
|
+
], variant: accordionRecipe.title.textVariant, children: item.title }), item.description ? _jsx(Text, { tone: "muted", variant: "caption", children: item.description }) : null] }), _jsx(View, { accessible: false, children: renderIndicator ? (renderIndicator({
|
|
338
350
|
value: item.value,
|
|
339
351
|
expanded: isExpanded,
|
|
340
352
|
disabled: item.disabled === true,
|
|
@@ -345,12 +357,11 @@ export function Accordion({ label, items, expandedValues, defaultExpandedValues
|
|
|
345
357
|
paddingBottom: accordionRecipe.panel.paddingBottom,
|
|
346
358
|
paddingStart: accordionRecipe.panel.paddingInlineStart,
|
|
347
359
|
},
|
|
348
|
-
panelStyle,
|
|
349
360
|
], children: item.content })) : null] }, item.value));
|
|
350
361
|
}) }));
|
|
351
362
|
}
|
|
352
|
-
export function DescriptionList({ label, descriptor, availableWidth,
|
|
353
|
-
|
|
363
|
+
export function DescriptionList({ label, descriptor, availableWidth, layoutStyle, onLayout, ...props }) {
|
|
364
|
+
assertNoRemovedStyleProps("DescriptionList", props, ["style", "itemStyle"]);
|
|
354
365
|
const resolved = resolveDescriptionListDescriptor(descriptor);
|
|
355
366
|
const { width: windowWidth } = useWindowDimensions();
|
|
356
367
|
const { environment } = useHjmNativeTheme();
|
|
@@ -377,9 +388,8 @@ export function DescriptionList({ label, descriptor, availableWidth, style, item
|
|
|
377
388
|
flexWrap: "wrap",
|
|
378
389
|
gap: spacing.sm,
|
|
379
390
|
},
|
|
380
|
-
style,
|
|
381
391
|
layoutStyle,
|
|
382
|
-
], children: resolved.items.map((item) => (_jsxs(View, { accessibilityLabel: `${item.label}, ${item.value}`, accessible: true, style: [{ gap: spacing.xxs, width: itemWidth }
|
|
392
|
+
], children: resolved.items.map((item) => (_jsxs(View, { accessibilityLabel: `${item.label}, ${item.value}`, accessible: true, style: [{ gap: spacing.xxs, width: itemWidth }], children: [_jsx(Text, { accessible: false, tone: "muted", variant: "label", children: item.label }), _jsx(Text, { accessible: false, tone: "primary", children: item.value })] }, item.id))) }));
|
|
383
393
|
}
|
|
384
394
|
function resolveImageSourceKey(source) {
|
|
385
395
|
if (typeof source === "number")
|
|
@@ -404,27 +414,32 @@ export function Image(imageProps) {
|
|
|
404
414
|
const resolvedDecorative = descriptor.decorative;
|
|
405
415
|
const resolvedAccessibilityLabel = descriptor.decorative ? undefined : descriptor.accessibilityLabel;
|
|
406
416
|
const resolvedResizeMode = nativeResizeModes[descriptor.fit];
|
|
407
|
-
const sourceKey = `src:${descriptor.src}`;
|
|
408
417
|
const source = useMemo(() => sourceAdapter?.(descriptor) ?? { uri: descriptor.src }, [descriptor.accessibilityLabel, descriptor.decorative, descriptor.fit,
|
|
409
418
|
descriptor.height, descriptor.src, descriptor.width, sourceAdapter]);
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
419
|
+
// Auth/cache changes can create a new request at the same URL. Compare the
|
|
420
|
+
// resolved source contents, not the inline adapter function's identity.
|
|
421
|
+
const sourceKey = JSON.stringify([descriptor.src, resolveImageSourceKey(source)]);
|
|
422
|
+
// Match the Web image lifecycle: a replaced/unmounted host cannot publish
|
|
423
|
+
// results, including an old A request after the product changes A→B→A.
|
|
424
|
+
const generation = useMemo(() => ({}), [sourceKey]);
|
|
425
|
+
const activeGeneration = useRef(generation);
|
|
426
|
+
useLayoutEffect(() => {
|
|
427
|
+
activeGeneration.current = generation;
|
|
428
|
+
return () => { activeGeneration.current = null; };
|
|
429
|
+
}, [generation]);
|
|
430
|
+
const [state, setState] = useState({ generation, status: "loading" });
|
|
431
|
+
const status = state.generation === generation ? state.status : "loading";
|
|
417
432
|
const reportLoad = (event) => {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
433
|
+
if (activeGeneration.current !== generation)
|
|
434
|
+
return;
|
|
435
|
+
setState({ generation, status: "loaded" });
|
|
421
436
|
onLoadStatusChange?.("loaded");
|
|
422
437
|
onLoad?.(event);
|
|
423
438
|
};
|
|
424
439
|
const reportError = (event) => {
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
440
|
+
if (activeGeneration.current !== generation)
|
|
441
|
+
return;
|
|
442
|
+
setState({ generation, status: "error" });
|
|
428
443
|
onLoadStatusChange?.("error");
|
|
429
444
|
onError?.(event);
|
|
430
445
|
};
|
|
@@ -518,15 +533,15 @@ const styles = StyleSheet.create({
|
|
|
518
533
|
width: glyph.lg,
|
|
519
534
|
},
|
|
520
535
|
});
|
|
521
|
-
export function CounterBadge({ count, accessibilityLabel, max = counterBadgeRecipe.defaults.max, tone = counterBadgeRecipe.defaults.tone, size = counterBadgeRecipe.defaults.size, variant = counterBadgeRecipe.defaults.variant,
|
|
522
|
-
warnDeprecatedStyleProps("CounterBadge", { style }, "layoutStyle for placement and tone/size/variant for appearance");
|
|
536
|
+
export function CounterBadge({ count, accessibilityLabel, max = counterBadgeRecipe.defaults.max, tone = counterBadgeRecipe.defaults.tone, size = counterBadgeRecipe.defaults.size, variant = counterBadgeRecipe.defaults.variant, layoutStyle, }) {
|
|
523
537
|
if (accessibilityLabel !== undefined && !accessibilityLabel.trim()) {
|
|
524
538
|
throw new TypeError("CounterBadge accessibilityLabel must not be empty");
|
|
525
539
|
}
|
|
540
|
+
// A zero count hides the badge, but must not change its Hook call order.
|
|
541
|
+
const { colors } = useHjmNativeTheme();
|
|
526
542
|
const visibleLabel = formatCounterBadgeCount(count, max);
|
|
527
543
|
if (visibleLabel === null)
|
|
528
544
|
return null;
|
|
529
|
-
const { colors } = useHjmNativeTheme();
|
|
530
545
|
const presentation = {
|
|
531
546
|
danger: { background: colors.dangerFill, content: colors.onDanger },
|
|
532
547
|
brand: { background: colors.primary, content: colors.onPrimary },
|
|
@@ -546,13 +561,12 @@ export function CounterBadge({ count, accessibilityLabel, max = counterBadgeReci
|
|
|
546
561
|
minWidth: metrics.minWidth,
|
|
547
562
|
paddingHorizontal: metrics.paddingHorizontal,
|
|
548
563
|
},
|
|
549
|
-
style,
|
|
550
564
|
layoutStyle,
|
|
551
565
|
], children: _jsx(Text, { accessible: false, align: "center", style: { color: presentation[tone].content, fontWeight: "700" }, variant: "caption", children: visibleLabel }) }));
|
|
552
566
|
}
|
|
553
567
|
/** Semantic list container that owns separator rhythm around composed rows. */
|
|
554
|
-
export function List({ label, children, separator = listRecipe.defaults.separator, appearance = "plain",
|
|
555
|
-
|
|
568
|
+
export function List({ label, children, separator = listRecipe.defaults.separator, appearance = "plain", layoutStyle, ...props }) {
|
|
569
|
+
assertNoRemovedStyleProps("List", props, ["style"]);
|
|
556
570
|
const { colors, environment, tokens } = useHjmNativeTheme();
|
|
557
571
|
const items = Children.toArray(children);
|
|
558
572
|
const separatorContract = listRecipe.separators[separator];
|
|
@@ -569,7 +583,6 @@ export function List({ label, children, separator = listRecipe.defaults.separato
|
|
|
569
583
|
}
|
|
570
584
|
: {}),
|
|
571
585
|
},
|
|
572
|
-
style,
|
|
573
586
|
layoutStyle,
|
|
574
587
|
], children: items.map((item, index) => (_jsxs(View, { children: [item, separatorContract && index < items.length - 1 ? (_jsx(View, { accessible: false, style: {
|
|
575
588
|
backgroundColor: colors.border,
|
|
@@ -579,21 +592,10 @@ export function List({ label, children, separator = listRecipe.defaults.separato
|
|
|
579
592
|
} })) : null] }, isValidElement(item) && item.key !== null ? item.key : `hjm-list-${index}`))) }));
|
|
580
593
|
}
|
|
581
594
|
export function Statistic(props) {
|
|
582
|
-
warnDeprecatedStyleProps("Statistic", {
|
|
583
|
-
style: props.style,
|
|
584
|
-
labelStyle: props.labelStyle,
|
|
585
|
-
valueStyle: props.valueStyle,
|
|
586
|
-
affixStyle: props.affixStyle,
|
|
587
|
-
trendStyle: props.trendStyle,
|
|
588
|
-
hintStyle: props.hintStyle,
|
|
589
|
-
}, "layoutStyle for placement and density/presentation for appearance");
|
|
590
595
|
return renderStatistic(props);
|
|
591
596
|
}
|
|
592
|
-
// StatisticGroup
|
|
593
|
-
|
|
594
|
-
// keeps those internal values from being reported as caller misuse of Statistic.style. A private
|
|
595
|
-
// prop on the public component was rejected because it would leak into the exported type.
|
|
596
|
-
function renderStatistic({ descriptor, density = "comfortable", presentation = "plain", contextLabel, accessibilityLabel, composeAccessibilityLabel, renderTrendMark, style, labelStyle, valueStyle, affixStyle, trendStyle, hintStyle, layoutStyle, }) {
|
|
597
|
+
// StatisticGroup reuses this renderer with its calculated layout width.
|
|
598
|
+
function renderStatistic({ descriptor, density = "comfortable", presentation = "plain", contextLabel, accessibilityLabel, composeAccessibilityLabel, renderTrendMark, layoutStyle, }) {
|
|
597
599
|
const resolved = resolveStatisticDescriptor(descriptor);
|
|
598
600
|
const theme = useHjmNativeTheme();
|
|
599
601
|
const densityContract = statisticRecipe.density[density];
|
|
@@ -632,14 +634,12 @@ function renderStatistic({ descriptor, density = "comfortable", presentation = "
|
|
|
632
634
|
minWidth: 0,
|
|
633
635
|
padding: densityContract.padding,
|
|
634
636
|
},
|
|
635
|
-
style,
|
|
636
637
|
layoutStyle,
|
|
637
638
|
], children: [_jsx(Text, { accessible: false, style: [
|
|
638
639
|
{
|
|
639
640
|
color: resolveColorReference(statisticRecipe.label.color, theme.palette),
|
|
640
641
|
fontWeight: statisticRecipe.label.fontWeight,
|
|
641
642
|
},
|
|
642
|
-
labelStyle,
|
|
643
643
|
], variant: densityContract.labelVariant, children: resolved.label }), _jsxs(View, { accessible: false, style: {
|
|
644
644
|
alignItems: "baseline",
|
|
645
645
|
direction: theme.environment.direction,
|
|
@@ -652,7 +652,6 @@ function renderStatistic({ descriptor, density = "comfortable", presentation = "
|
|
|
652
652
|
color: resolveColorReference(statisticRecipe.affix.color, theme.palette),
|
|
653
653
|
fontWeight: statisticRecipe.affix.fontWeight,
|
|
654
654
|
},
|
|
655
|
-
affixStyle,
|
|
656
655
|
], variant: statisticRecipe.affix.textVariant, children: resolved.prefix })) : null, _jsx(Text, { accessible: false, style: [
|
|
657
656
|
{
|
|
658
657
|
color: resolveColorReference(statisticRecipe.value.color, theme.palette),
|
|
@@ -660,13 +659,11 @@ function renderStatistic({ descriptor, density = "comfortable", presentation = "
|
|
|
660
659
|
fontVariant: ["tabular-nums"],
|
|
661
660
|
fontWeight: statisticRecipe.value.fontWeight,
|
|
662
661
|
},
|
|
663
|
-
valueStyle,
|
|
664
662
|
], variant: densityContract.valueVariant, children: resolved.value }), resolved.suffix ? (_jsx(Text, { accessible: false, style: [
|
|
665
663
|
{
|
|
666
664
|
color: resolveColorReference(statisticRecipe.affix.color, theme.palette),
|
|
667
665
|
fontWeight: statisticRecipe.affix.fontWeight,
|
|
668
666
|
},
|
|
669
|
-
affixStyle,
|
|
670
667
|
], variant: statisticRecipe.affix.textVariant, children: resolved.suffix })) : null] }), resolved.trend ? (_jsxs(View, { accessible: false, style: {
|
|
671
668
|
alignItems: "center",
|
|
672
669
|
flexDirection: "row",
|
|
@@ -679,14 +676,12 @@ function renderStatistic({ descriptor, density = "comfortable", presentation = "
|
|
|
679
676
|
flexShrink: 1,
|
|
680
677
|
fontWeight: statisticRecipe.trend.fontWeight,
|
|
681
678
|
},
|
|
682
|
-
trendStyle,
|
|
683
679
|
], variant: statisticRecipe.trend.textVariant, children: resolved.trend.label })] })) : null, resolved.hint ? (_jsx(Text, { accessible: false, style: [
|
|
684
680
|
{ color: resolveColorReference(statisticRecipe.hint.color, theme.palette) },
|
|
685
|
-
hintStyle,
|
|
686
681
|
], variant: statisticRecipe.hint.textVariant, children: resolved.hint })) : null] }));
|
|
687
682
|
}
|
|
688
|
-
export function StatisticGroup({ label, descriptor, availableWidth, density, presentation, composeAccessibilityLabel, renderTrendMark,
|
|
689
|
-
|
|
683
|
+
export function StatisticGroup({ label, descriptor, availableWidth, density, presentation, composeAccessibilityLabel, renderTrendMark, layoutStyle, onLayout, ...props }) {
|
|
684
|
+
assertNoRemovedStyleProps("StatisticGroup", props, ["style", "itemStyle"]);
|
|
690
685
|
validateStatisticGroup(descriptor);
|
|
691
686
|
const { width: windowWidth } = useWindowDimensions();
|
|
692
687
|
const { environment } = useHjmNativeTheme();
|
|
@@ -725,20 +720,19 @@ export function StatisticGroup({ label, descriptor, availableWidth, density, pre
|
|
|
725
720
|
flexWrap: "wrap",
|
|
726
721
|
gap: statisticRecipe.group.gap,
|
|
727
722
|
},
|
|
728
|
-
style,
|
|
729
723
|
layoutStyle,
|
|
730
|
-
], children: descriptor.items.map((item, index) => (_jsx(StatisticGroupItem, { contextLabel: label, descriptor: item, ...(composeAccessibilityLabel === undefined ? {} : { composeAccessibilityLabel }), ...(density === undefined ? {} : { density }), ...(presentation === undefined ? {} : { presentation }), ...(renderTrendMark === undefined ? {} : { renderTrendMark }), layoutStyle: { width: index >= finalRowStart ? finalRowItemWidth : itemWidth }
|
|
724
|
+
], children: descriptor.items.map((item, index) => (_jsx(StatisticGroupItem, { contextLabel: label, descriptor: item, ...(composeAccessibilityLabel === undefined ? {} : { composeAccessibilityLabel }), ...(density === undefined ? {} : { density }), ...(presentation === undefined ? {} : { presentation }), ...(renderTrendMark === undefined ? {} : { renderTrendMark }), layoutStyle: { width: index >= finalRowStart ? finalRowItemWidth : itemWidth } }, item.id))) }));
|
|
731
725
|
}
|
|
732
726
|
/** Group cell: same render as Statistic without attributing the group's styles to the caller. */
|
|
733
727
|
function StatisticGroupItem(props) {
|
|
734
728
|
return renderStatistic(props);
|
|
735
729
|
}
|
|
736
730
|
/** Ordered record of completed events; unlike Steps it has no current cursor. */
|
|
737
|
-
export function Timeline({ items, composeAccessibleName,
|
|
738
|
-
|
|
731
|
+
export function Timeline({ items, composeAccessibleName, layoutStyle, ...props }) {
|
|
732
|
+
assertNoRemovedStyleProps("Timeline", props, ["style"]);
|
|
739
733
|
const theme = useHjmNativeTheme();
|
|
740
734
|
const resolved = resolveTimelineDescriptor({ items }, { composeAccessibleName });
|
|
741
|
-
return (_jsx(View, { ...props, style: [{ gap: timelineRecipe.gap },
|
|
735
|
+
return (_jsx(View, { ...props, style: [{ gap: timelineRecipe.gap }, layoutStyle], children: resolved.map((item, index) => {
|
|
742
736
|
const tone = timelineRecipe.dot.tones[item.tone];
|
|
743
737
|
const accessibilityLabel = [
|
|
744
738
|
item.accessibleName,
|