one
Version:
One is a React framework for web, iOS, and Android apps.
367 lines (364 loc) • 15.8 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { useControlled } from "./controlled.native.js";
import { Platform } from "react-native";
import { assertSwiftUIValue } from "./generated/swiftui.native.js";
import { dispatchSDKEvent, swiftStyleNative } from "./generated/swiftStyleNative.native.js";
import { tabViewSlotAvailability } from "./generated/viewSlots.native.js";
import { Children, isValidElement, useMemo } from "react";
import NativeTab from "./specs/OneNativeTabNativeComponent.native.js";
import NativeTabs from "./specs/OneNativeTabsNativeComponent.native.js";
import { Toolbar, ToolbarNode } from "./NavigationStack.native.js";
var PAGE_STYLE = {
position: "absolute",
left: 0,
top: 0,
width: "100%",
height: "100%"
};
function TabViewBottomAccessory(_props) {
throw new Error("Swift.TabViewBottomAccessory must be a direct child of Swift.Tabs");
}
function TabViewSlot(_props) {
throw new Error("Swift.TabViewSlot must be a direct child of Swift.Tabs");
}
function TabSection(_props) {
throw new Error("Swift.TabSection must be a direct child of Swift.Tabs");
}
function Tab(_props) {
throw new Error("Swift.Tab must be a direct child of Swift.Tabs or Swift.TabSection");
}
function tabContentModifiers(owner, props, iosVersion) {
var _props_sectionActions;
if (props.disabled !== void 0 && iosVersion < 18.4) throw new Error(`${owner} disabled requires iOS 18.4 or later`);
if (props.help !== void 0 && iosVersion < 27) throw new Error(`${owner} help requires iOS 27 or later`);
var placements = function placements2(value) {
var _ref;
var list = (_ref = value === null || value === void 0 ? void 0 : value.for) !== null && _ref !== void 0 ? _ref : [];
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
try {
for (var _iterator = list[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var placement = _step.value;
assertSwiftUIValue("AdaptableTabBarPlacement", placement, iosVersion);
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
if (new Set(list).size !== list.length) throw new Error(`${owner} lists a placement twice`);
return list;
};
if (props.customizationBehavior) assertSwiftUIValue("TabCustomizationBehavior", props.customizationBehavior.behavior, iosVersion);
if (props.defaultVisibility) assertSwiftUIValue("Visibility", props.defaultVisibility.visibility, iosVersion);
if (props.springLoadingBehavior) assertSwiftUIValue("SpringLoadingBehavior", props.springLoadingBehavior, iosVersion);
if (props.tabPlacement) assertSwiftUIValue("TabPlacement", props.tabPlacement, iosVersion);
if (props.defaultSectionExpansion) assertSwiftUIValue("TabSectionExpansion", props.defaultSectionExpansion, iosVersion);
return JSON.stringify({
image: props.image,
labelStyle: props.labelStyle,
section: props.section,
disabled: props.disabled,
hidden: props.hidden,
customizationID: props.customizationID,
customizationBehavior: props.customizationBehavior && {
value: props.customizationBehavior.behavior,
placements: placements(props.customizationBehavior)
},
defaultVisibility: props.defaultVisibility && {
value: props.defaultVisibility.visibility,
placements: placements(props.defaultVisibility)
},
springLoadingBehavior: props.springLoadingBehavior,
tabPlacement: props.tabPlacement,
defaultSectionExpansion: props.defaultSectionExpansion,
sectionActions: (_props_sectionActions = props.sectionActions) === null || _props_sectionActions === void 0 ? void 0 : _props_sectionActions.map(function(param) {
var { id, title, systemImage } = param;
return {
id,
title,
systemImage: systemImage !== null && systemImage !== void 0 ? systemImage : ""
};
}),
accessibilityLabel: props.accessibilityLabel,
accessibilityHint: props.accessibilityHint,
accessibilityValue: props.accessibilityValue,
accessibilityIdentifier: props.accessibilityIdentifier,
help: props.help
});
}
function Tabs(param) {
var { children, selection, onSelectionChange, onReselect, revision = 0, tabViewStyle = "automatic", tabBarVisibility = "automatic", customization = "", onCustomizationChange, swiftStyle, style, ...props } = param;
var _ref, _accessory_inline, _ref1, _accessory_expanded, _ref2;
var iosVersion = Number.parseFloat(String(Platform.Version));
assertSwiftUIValue("TabViewStyle", tabViewStyle, iosVersion);
assertSwiftUIValue("Visibility", tabBarVisibility, iosVersion);
var controlled = useControlled(function(event) {
return onSelectionChange(event.selection);
}, revision);
var { entries, accessory, actions, toolbar } = useMemo(function() {
var ids = /* @__PURE__ */ new Set();
var entries2 = [];
var accessory2;
var toolbar2;
var actions2 = /* @__PURE__ */ new Map();
var claim = function claim2(owner, id) {
if (!id || ids.has(id)) throw new Error(`${owner} requires unique, nonempty ids: "${id}"`);
ids.add(id);
};
var tab = function tab2(props2, section) {
var { id, title, systemImage, image, badge, role, testID, onPress, swiftStyle: swiftStyle2, children: page } = props2;
claim("Swift.Tab", id);
if (Boolean(onPress) === (page !== void 0)) {
throw new Error(`Swift.Tab "${id}" needs exactly one of onPress and children: a tab either runs an action or shows a page`);
}
if (systemImage && image) throw new Error(`Swift.Tab "${id}" takes systemImage or image, not both`);
if (role) assertSwiftUIValue("TabRole", role, iosVersion);
entries2.push({
id,
kind: onPress ? "action" : "page",
title,
systemImage: systemImage !== null && systemImage !== void 0 ? systemImage : "",
badge: badge === void 0 ? "" : String(badge),
role: role !== null && role !== void 0 ? role : "",
slotHeight: 0,
tabModifiers: tabContentModifiers(`Swift.Tab "${id}"`, {
...props2,
section
}, iosVersion),
swiftStyle: swiftStyle2,
testID,
onPress,
children: page
});
if (onPress) actions2.set(id, onPress);
};
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
try {
var _loop = function() {
var child = _step.value;
if (!/* @__PURE__ */ isValidElement(child)) throw new Error("Swift.Tabs children must be elements");
if (child.type === Tab) {
tab(child.props, void 0);
} else if (child.type === TabSection) {
var _section_sectionActions;
var section = child.props;
claim("Swift.TabSection", section.id);
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = void 0;
try {
for (var _iterator2 = ((_section_sectionActions = section.sectionActions) !== null && _section_sectionActions !== void 0 ? _section_sectionActions : [])[Symbol.iterator](), _step1; !(_iteratorNormalCompletion2 = (_step1 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var action = _step1.value;
claim(`Swift.TabSection "${section.id}" sectionActions`, action.id);
actions2.set(action.id, action.onPress);
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
entries2.push({
id: section.id,
kind: "section",
title: section.title,
systemImage: "",
badge: "",
role: "",
slotHeight: 0,
tabModifiers: tabContentModifiers(`Swift.TabSection "${section.id}"`, section, iosVersion),
children: void 0
});
var tabs = Children.toArray(section.children);
if (!tabs.length) throw new Error(`Swift.TabSection "${section.id}" needs Swift.Tab children`);
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;
try {
for (var _iterator1 = tabs[Symbol.iterator](), _step2; !(_iteratorNormalCompletion1 = (_step2 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
var sectionChild = _step2.value;
if (!/* @__PURE__ */ isValidElement(sectionChild) || sectionChild.type !== Tab) throw new Error(`Swift.TabSection "${section.id}" accepts Swift.Tab elements as children`);
tab(sectionChild.props, section.id);
}
} catch (err) {
_didIteratorError1 = true;
_iteratorError1 = err;
} finally {
try {
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
_iterator1.return();
}
} finally {
if (_didIteratorError1) {
throw _iteratorError1;
}
}
}
} else if (child.type === TabViewBottomAccessory) {
if (accessory2) throw new Error("Swift.Tabs accepts one TabViewBottomAccessory");
accessory2 = child.props;
} else if (child.type === Toolbar) {
if (toolbar2) throw new Error("Swift.Tabs accepts one Swift.Toolbar");
toolbar2 = child.props.children;
} else if (child.type === TabViewSlot) {
var slot = child.props;
if (!Object.hasOwn(tabViewSlotAvailability, slot.name)) throw new Error(`Swift.TabViewSlot has no SDK modifier ${slot.name}`);
if (iosVersion < tabViewSlotAvailability[slot.name]) throw new Error(`Swift.TabViewSlot ${slot.name} requires iOS ${tabViewSlotAvailability[slot.name]} or later`);
if (!Number.isFinite(slot.height) || slot.height <= 0) throw new Error("Swift.TabViewSlot height must be a positive number");
if (slot.children === void 0) throw new Error("Swift.TabViewSlot needs children");
if (entries2.some(function(entry) {
return entry.kind === "slot" && entry.id === slot.name;
})) throw new Error(`Swift.Tabs accepts one ${slot.name} slot`);
entries2.push({
id: slot.name,
kind: "slot",
title: "",
systemImage: "",
badge: "",
role: "",
slotHeight: slot.height,
tabModifiers: "{}",
children: slot.children
});
} else {
throw new Error("Swift.Tabs accepts Swift.Tab, Swift.TabSection, Swift.TabViewSlot, Swift.TabViewBottomAccessory, and Swift.Toolbar elements as direct children");
}
};
for (var _iterator = Children.toArray(children)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) _loop();
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return != null) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return {
entries: entries2,
accessory: accessory2,
actions: actions2,
toolbar: toolbar2
};
}, [children, iosVersion]);
var tabsBeyondIOS17 = entries.some(function(entry) {
return entry.kind === "section" || entry.kind !== "slot" && entry.tabModifiers !== "{}";
});
if (iosVersion < 18 && (tabsBeyondIOS17 || tabViewStyle !== "automatic" || onCustomizationChange)) throw new Error("Swift.Tabs sections, tab modifiers, styles, and customization require iOS 18 or later");
if (accessory) {
if (entries.some(function(entry) {
return entry.kind === "slot" && entry.id === "tabViewBottomAccessory";
})) throw new Error("Swift.Tabs accepts one tabViewBottomAccessory slot");
if (iosVersion < 26) throw new Error("Swift.TabViewBottomAccessory requires iOS 26 or later");
if (accessory.isEnabled !== void 0 && iosVersion < 26.1) throw new Error("Swift.TabViewBottomAccessory isEnabled requires iOS 26.1 or later");
if (accessory.children === void 0 && accessory.inline === void 0 && accessory.expanded === void 0) throw new Error("Swift.TabViewBottomAccessory needs children, inline, or expanded content");
}
var selected = entries.find(function(entry) {
return entry.id === selection;
});
if (!selected || selected.kind !== "page" && selected.kind !== "action") {
throw new Error(`Swift.Tabs selection "${selection}" must identify a mounted Swift.Tab`);
}
if (selected.kind === "action") {
throw new Error(`Swift.Tabs selection "${selection}" is an action tab, which never becomes the selection`);
}
var accessoryEntries = accessory ? [{
kind: "accessoryInline",
content: (_ref = (_accessory_inline = accessory.inline) !== null && _accessory_inline !== void 0 ? _accessory_inline : accessory.children) !== null && _ref !== void 0 ? _ref : accessory.expanded
}, {
kind: "accessoryExpanded",
content: (_ref1 = (_accessory_expanded = accessory.expanded) !== null && _accessory_expanded !== void 0 ? _accessory_expanded : accessory.children) !== null && _ref1 !== void 0 ? _ref1 : accessory.inline
}].map(function(param2) {
var { kind, content } = param2;
return {
id: kind,
kind,
title: "",
systemImage: "",
badge: "",
role: "",
slotHeight: 0,
tabModifiers: "{}",
children: content
};
}) : [];
return /* @__PURE__ */ jsxs(NativeTabs, {
...props,
style: [{ flex: 1 }, style],
swiftStyle: swiftStyleNative(swiftStyle),
onNativeSDKEvent: function onNativeSDKEvent(param2) {
var { nativeEvent } = param2;
return dispatchSDKEvent(swiftStyle, nativeEvent.name, nativeEvent.value);
},
selection,
acknowledgedEvent: controlled.acknowledgedEvent,
revision,
tabViewStyle,
tabBarVisibility,
customization,
customizable: Boolean(onCustomizationChange),
bottomAccessoryEnabled: (_ref2 = accessory === null || accessory === void 0 ? void 0 : accessory.isEnabled) !== null && _ref2 !== void 0 ? _ref2 : true,
onNativeTabsSelectionChange: function onNativeTabsSelectionChange(param2) {
var { nativeEvent } = param2;
return controlled.onNativeChange(nativeEvent);
},
onNativeTabsAction: function onNativeTabsAction(param2) {
var { nativeEvent } = param2;
var action = actions.get(nativeEvent.tabId);
if (action) action();
else onReselect === null || onReselect === void 0 ? void 0 : onReselect(nativeEvent.tabId);
},
onNativeTabsCustomizationChange: function onNativeTabsCustomizationChange(param2) {
var { nativeEvent } = param2;
return onCustomizationChange === null || onCustomizationChange === void 0 ? void 0 : onCustomizationChange(nativeEvent.customization);
},
children: [[...entries, ...accessoryEntries].map(function(entry) {
var hidden = (entry.kind === "page" || entry.kind === "action") && entry.id !== selection;
return /* @__PURE__ */ jsx(NativeTab, {
tabId: entry.id,
kind: entry.kind,
title: entry.title,
systemImage: entry.systemImage,
badge: entry.badge,
tabRole: entry.role,
slotHeight: entry.slotHeight,
tabModifiers: entry.tabModifiers,
swiftStyle: swiftStyleNative(entry.swiftStyle),
onNativeSDKEvent: function onNativeSDKEvent(param2) {
var { nativeEvent } = param2;
return dispatchSDKEvent(entry.swiftStyle, nativeEvent.name, nativeEvent.value);
},
testID: entry.testID,
style: PAGE_STYLE,
collapsable: false,
pointerEvents: hidden ? "none" : "auto",
accessibilityElementsHidden: hidden,
importantForAccessibility: hidden ? "no-hide-descendants" : "auto",
children: entry.children
}, `${entry.kind}:${entry.id}`);
}), toolbar ? /* @__PURE__ */ jsx(ToolbarNode, {
iosVersion,
children: toolbar
}) : null]
});
}
export { Tab, TabSection, TabViewBottomAccessory, TabViewSlot, Tabs };
//# sourceMappingURL=Tabs.native.js.map