achery-ui 0.12.0 → 0.13.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.
@@ -5993,6 +5993,133 @@ var MoreButton = ({ active, onPress, tokens: tokens$1 }) => /* @__PURE__ */ jsxR
5993
5993
  ]
5994
5994
  }
5995
5995
  );
5996
+ var cornerStyle = (corner, inset) => {
5997
+ if (corner === "none") return {};
5998
+ const [v, h] = corner.split("-");
5999
+ return { position: "absolute", [v]: inset, [h]: inset };
6000
+ };
6001
+ var Marginalia = ({
6002
+ glyph = "fern",
6003
+ size = 120,
6004
+ opacity = 0.4,
6005
+ accent = false,
6006
+ corner = "bottom-right",
6007
+ inset = 16,
6008
+ style
6009
+ }) => {
6010
+ const { tokens } = useTheme();
6011
+ const color = accent ? tokens.accent : tokens.fgMute;
6012
+ return /* @__PURE__ */ jsxRuntime.jsx(
6013
+ reactNative.View,
6014
+ {
6015
+ pointerEvents: "none",
6016
+ accessibilityElementsHidden: true,
6017
+ importantForAccessibility: "no-hide-descendants",
6018
+ style: [cornerStyle(corner, inset), { opacity }, style],
6019
+ children: /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: glyph, size, color })
6020
+ }
6021
+ );
6022
+ };
6023
+ var defaultNormalize = (t) => t.trim().toLowerCase().replace(/\s+/g, " ");
6024
+ var TagInput = ({
6025
+ value,
6026
+ onChange,
6027
+ suggestions = [],
6028
+ placeholder,
6029
+ onLeather = false,
6030
+ normalize = defaultNormalize,
6031
+ disabled = false,
6032
+ style
6033
+ }) => {
6034
+ const { tokens } = useTheme();
6035
+ const [text, setText] = react.useState("");
6036
+ const chipBorder = onLeather ? tokens.goldDeep : tokens.border;
6037
+ const chipText = onLeather ? tokens.materialLeatherFg : tokens.fg;
6038
+ const placeholderColor = onLeather ? `${tokens.materialLeatherFg}80` : tokens.fgMute;
6039
+ const add = (raw) => {
6040
+ const t = normalize(raw);
6041
+ if (t && !value.includes(t)) onChange([...value, t]);
6042
+ setText("");
6043
+ };
6044
+ const remove = (t) => onChange(value.filter((x) => x !== t));
6045
+ const handleChange = (t) => {
6046
+ if (t.endsWith(",") || t.endsWith(" ")) {
6047
+ const token = t.slice(0, -1);
6048
+ if (token.trim()) add(token);
6049
+ else setText("");
6050
+ return;
6051
+ }
6052
+ setText(t);
6053
+ };
6054
+ const matches = text.trim() ? suggestions.filter((s) => s.includes(normalize(text)) && !value.includes(s)).slice(0, 6) : [];
6055
+ return /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style, children: [
6056
+ /* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: [styles.field, { borderColor: chipBorder }], children: [
6057
+ value.map((tag) => /* @__PURE__ */ jsxRuntime.jsxs(
6058
+ reactNative.Pressable,
6059
+ {
6060
+ onPress: () => !disabled && remove(tag),
6061
+ style: [styles.chip, { borderColor: chipBorder }],
6062
+ children: [
6063
+ /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "caption", style: { color: chipText }, children: tag }),
6064
+ /* @__PURE__ */ jsxRuntime.jsx(Glyph, { name: "cross", size: 10, color: chipText })
6065
+ ]
6066
+ },
6067
+ tag
6068
+ )),
6069
+ /* @__PURE__ */ jsxRuntime.jsx(
6070
+ reactNative.TextInput,
6071
+ {
6072
+ value: text,
6073
+ editable: !disabled,
6074
+ onChangeText: handleChange,
6075
+ onSubmitEditing: () => text.trim() && add(text),
6076
+ onKeyPress: (e) => {
6077
+ if (e.nativeEvent.key === "Backspace" && !text && value.length) {
6078
+ const last = value[value.length - 1];
6079
+ if (last) remove(last);
6080
+ }
6081
+ },
6082
+ placeholder: value.length === 0 ? placeholder : void 0,
6083
+ placeholderTextColor: placeholderColor,
6084
+ autoCapitalize: "none",
6085
+ autoCorrect: false,
6086
+ style: [styles.input, { color: chipText }]
6087
+ }
6088
+ )
6089
+ ] }),
6090
+ matches.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: styles.suggestions, children: matches.map((s) => /* @__PURE__ */ jsxRuntime.jsx(
6091
+ reactNative.Pressable,
6092
+ {
6093
+ onPress: () => add(s),
6094
+ style: [styles.suggestion, { borderColor: tokens.borderMute }],
6095
+ children: /* @__PURE__ */ jsxRuntime.jsx(Text, { variant: "caption", style: { color: tokens.fg2 }, children: s })
6096
+ },
6097
+ s
6098
+ )) })
6099
+ ] });
6100
+ };
6101
+ var styles = reactNative.StyleSheet.create({
6102
+ field: {
6103
+ flexDirection: "row",
6104
+ flexWrap: "wrap",
6105
+ alignItems: "center",
6106
+ gap: 6,
6107
+ borderWidth: 1.5,
6108
+ padding: 8,
6109
+ minHeight: 44
6110
+ },
6111
+ chip: {
6112
+ flexDirection: "row",
6113
+ alignItems: "center",
6114
+ gap: 4,
6115
+ borderWidth: 1,
6116
+ paddingHorizontal: 8,
6117
+ paddingVertical: 4
6118
+ },
6119
+ input: { flex: 1, minWidth: 80, paddingVertical: 4, fontSize: 14 },
6120
+ suggestions: { flexDirection: "row", flexWrap: "wrap", gap: 6, marginTop: 6 },
6121
+ suggestion: { borderWidth: 1, paddingHorizontal: 8, paddingVertical: 4 }
6122
+ });
5996
6123
 
5997
6124
  exports.Badge = Badge;
5998
6125
  exports.BottomSheet = BottomSheet;
@@ -6007,6 +6134,7 @@ exports.GlyphAliases = GlyphAliases;
6007
6134
  exports.GlyphCategories = GlyphCategories;
6008
6135
  exports.GlyphPicker = GlyphPicker;
6009
6136
  exports.Input = Input;
6137
+ exports.Marginalia = Marginalia;
6010
6138
  exports.MaterialCard = MaterialCard;
6011
6139
  exports.MaterialEyebrow = MaterialEyebrow;
6012
6140
  exports.NativeThemeProvider = NativeThemeProvider;
@@ -6017,6 +6145,7 @@ exports.SheetRow = SheetRow;
6017
6145
  exports.Skeleton = Skeleton;
6018
6146
  exports.StatusDot = StatusDot;
6019
6147
  exports.Tabs = Tabs;
6148
+ exports.TagInput = TagInput;
6020
6149
  exports.Text = Text;
6021
6150
  exports.Textarea = Textarea;
6022
6151
  exports.ToastProvider = ToastProvider;