@kanso-labs/react-native-kanso-ui 0.8.0 → 0.9.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/dist/badge/index.js +9 -70
- package/dist/badge/index.js.map +1 -1
- package/dist/button/index.js +1 -1
- package/dist/button/palettes.d.ts +2 -0
- package/dist/components/badge/index.d.ts +48 -0
- package/dist/components/badge/index.js +122 -0
- package/dist/components/badge/index.js.map +1 -0
- package/dist/{badge → components/badge}/styles.js +10 -6
- package/dist/components/badge/styles.js.map +1 -0
- package/dist/components/breadcrumbs/index.d.ts +66 -0
- package/dist/components/breadcrumbs/index.js +285 -0
- package/dist/components/breadcrumbs/index.js.map +1 -0
- package/dist/components/checkbox/index.d.ts +7 -1
- package/dist/components/checkbox/index.js +183 -138
- package/dist/components/checkbox/index.js.map +1 -1
- package/dist/components/checkbox-group/index.d.ts +93 -0
- package/dist/components/checkbox-group/index.js +306 -0
- package/dist/components/checkbox-group/index.js.map +1 -0
- package/dist/components/code/index.d.ts +25 -0
- package/dist/components/code/index.js +87 -0
- package/dist/components/code/index.js.map +1 -0
- package/dist/components/container/index.d.ts +47 -0
- package/dist/components/container/index.js +85 -0
- package/dist/components/container/index.js.map +1 -0
- package/dist/components/fab/index.d.ts +80 -0
- package/dist/components/fab/index.js +231 -0
- package/dist/components/fab/index.js.map +1 -0
- package/dist/components/fab-menu/index.d.ts +120 -0
- package/dist/components/fab-menu/index.js +640 -0
- package/dist/components/fab-menu/index.js.map +1 -0
- package/dist/components/feed/index.d.ts +57 -0
- package/dist/components/feed/index.js +167 -0
- package/dist/components/feed/index.js.map +1 -0
- package/dist/components/keycap/index.d.ts +27 -0
- package/dist/components/keycap/index.js +136 -0
- package/dist/components/keycap/index.js.map +1 -0
- package/dist/components/menu/index.js +1 -1
- package/dist/components/separator/index.d.ts +3 -2
- package/dist/components/separator/index.js +29 -26
- package/dist/components/separator/index.js.map +1 -1
- package/dist/components/supporting-pane/index.d.ts +44 -0
- package/dist/components/supporting-pane/index.js +109 -0
- package/dist/components/supporting-pane/index.js.map +1 -0
- package/dist/components/text/index.d.ts +1 -1
- package/dist/components/text/index.js +49 -21
- package/dist/components/text/index.js.map +1 -1
- package/dist/components/text-area/index.d.ts +145 -0
- package/dist/components/text-area/index.js +231 -0
- package/dist/components/text-area/index.js.map +1 -0
- package/dist/components/toolbar/index.d.ts +53 -0
- package/dist/components/toolbar/index.js +185 -0
- package/dist/components/toolbar/index.js.map +1 -0
- package/dist/control/group.js +23 -0
- package/dist/control/group.js.map +1 -0
- package/dist/fab/index.d.ts +19 -0
- package/dist/fab/index.js +147 -0
- package/dist/fab/index.js.map +1 -0
- package/dist/field/index.js +84 -43
- package/dist/field/index.js.map +1 -1
- package/dist/field/styles.js +18 -0
- package/dist/field/styles.js.map +1 -1
- package/dist/form/index.d.ts +1 -2
- package/dist/form/index.js +1 -1
- package/dist/form/index.js.map +1 -1
- package/dist/index.d.ts +17 -4
- package/dist/index.js +15 -3
- package/dist/modal/index.js +59 -46
- package/dist/modal/index.js.map +1 -1
- package/dist/navigation/index.js +8 -5
- package/dist/navigation/index.js.map +1 -1
- package/dist/overlay/placement.js +3 -1
- package/dist/overlay/placement.js.map +1 -1
- package/dist/separator/index.js +7 -0
- package/dist/separator/index.js.map +1 -0
- package/dist/typography/size.js +14 -0
- package/dist/typography/size.js.map +1 -0
- package/package.json +1 -1
- package/dist/badge/styles.js.map +0 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { ButtonLinkForm, ButtonPressForm } from "../../button/index.js";
|
|
2
|
+
import { FabSize, FabTone, FabVariant } from "../../fab/index.js";
|
|
3
|
+
import { PressableProps, StyleProp, View, ViewStyle } from "react-native";
|
|
4
|
+
import { ComponentRef, ReactNode, Ref } from "react";
|
|
5
|
+
//#region src/components/fab/index.d.ts
|
|
6
|
+
type FabNaming = {
|
|
7
|
+
/**
|
|
8
|
+
* What the FAB does, in words. A FAB without a `label` is an icon
|
|
9
|
+
* alone, which has no name of its own, so it needs this; with a
|
|
10
|
+
* `label` the label is its name.
|
|
11
|
+
*/
|
|
12
|
+
readonly 'aria-label': string;
|
|
13
|
+
readonly label?: never;
|
|
14
|
+
} | {
|
|
15
|
+
readonly 'aria-label'?: string;
|
|
16
|
+
/**
|
|
17
|
+
* A label after the icon, which makes this the extended FAB: as tall
|
|
18
|
+
* as the size, as wide as what it holds.
|
|
19
|
+
*/
|
|
20
|
+
readonly label: ReactNode;
|
|
21
|
+
};
|
|
22
|
+
type FabPressForm = Omit<ButtonPressForm, 'isPending' | 'pendingLabel'> & {
|
|
23
|
+
readonly isPending?: never;
|
|
24
|
+
readonly pendingLabel?: never;
|
|
25
|
+
};
|
|
26
|
+
type FabProps = (ButtonLinkForm | FabPressForm) & FabNaming & Omit<PressableProps, 'aria-label' | 'children' | 'disabled' | 'style'> & {
|
|
27
|
+
/**
|
|
28
|
+
* The FAB's icon. The FAB hands it its colour and the size's icon size
|
|
29
|
+
* through `useIconStyle()`.
|
|
30
|
+
*/
|
|
31
|
+
readonly children?: ReactNode;
|
|
32
|
+
/**
|
|
33
|
+
* Draws no press ripple. The state layers are unaffected.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
readonly disableRipple?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Draws the FAB disabled, without its shadow, and takes no presses.
|
|
39
|
+
* @default false
|
|
40
|
+
*/
|
|
41
|
+
readonly isDisabled?: boolean;
|
|
42
|
+
readonly ref?: Ref<ComponentRef<typeof View>>;
|
|
43
|
+
/**
|
|
44
|
+
* The pages' three sizes: `md` the FAB at 56dp, `lg` the medium FAB at
|
|
45
|
+
* 80dp and `xl` the large FAB at 96dp.
|
|
46
|
+
* @default 'md'
|
|
47
|
+
*/
|
|
48
|
+
readonly size?: FabSize;
|
|
49
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
50
|
+
/**
|
|
51
|
+
* The colour role the FAB is drawn in.
|
|
52
|
+
* @default 'primary'
|
|
53
|
+
*/
|
|
54
|
+
readonly tone?: FabTone;
|
|
55
|
+
/**
|
|
56
|
+
* `tonal` draws the tone's container pair, the pages' default; `filled`
|
|
57
|
+
* draws the tone itself.
|
|
58
|
+
* @default 'tonal'
|
|
59
|
+
*/
|
|
60
|
+
readonly variant?: FabVariant;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* A screen's primary action, raised over its content. Its icon is its
|
|
64
|
+
* children; given a `label` it is the extended FAB, with the label after the
|
|
65
|
+
* icon. Given `href` it is a link with the same appearance.
|
|
66
|
+
*
|
|
67
|
+
* ```tsx
|
|
68
|
+
* <Fab aria-label="Label">
|
|
69
|
+
* <PlusIcon />
|
|
70
|
+
* </Fab>
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* Without a `label` it is an icon alone, so `aria-label` is required there.
|
|
74
|
+
* `style`, `ref` and `testID` land on the `Pressable`, which is what a call
|
|
75
|
+
* site positions over its screen.
|
|
76
|
+
*/
|
|
77
|
+
declare function Fab({ children, delayLongPress, disableRipple, href, isDisabled, label, onBlur, onFocus, onHoverIn, onHoverOut, onLongPress, onPress, onPressIn, onPressOut, ref, size, slot, style, tone, type, variant, ...props }: FabProps): import("react").JSX.Element;
|
|
78
|
+
//#endregion
|
|
79
|
+
export { Fab, type FabProps, type FabSize, type FabTone, type FabVariant };
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { IconStyleContext } from "../../glyphs/icon-style.js";
|
|
2
|
+
import { useTheme } from "../../theme/scope.js";
|
|
3
|
+
import { composeStyles } from "../../theme/styles.js";
|
|
4
|
+
import { usePressFeedback } from "../../press/index.js";
|
|
5
|
+
import { useTypeRole } from "../../typography/roles.js";
|
|
6
|
+
import { AnimatedPressable, buttonStyles, useButtonAction, useSlotTrigger } from "../../button/index.js";
|
|
7
|
+
import { EXTENDED_FAB_ROLES, FAB_ICON_SIZES, extendedFabSizesOf, fabCornersOf, fabPalettesOf, fabShadowOf, fabSizesOf } from "../../fab/index.js";
|
|
8
|
+
import { c } from "react/compiler-runtime";
|
|
9
|
+
import { StyleSheet, Text, View } from "react-native";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
//#region src/components/fab/index.tsx
|
|
12
|
+
const styles = StyleSheet.create({
|
|
13
|
+
base: {
|
|
14
|
+
alignItems: "center",
|
|
15
|
+
flexDirection: "row",
|
|
16
|
+
flexShrink: 0,
|
|
17
|
+
justifyContent: "center"
|
|
18
|
+
},
|
|
19
|
+
icon: {
|
|
20
|
+
alignItems: "center",
|
|
21
|
+
flexShrink: 0,
|
|
22
|
+
justifyContent: "center"
|
|
23
|
+
},
|
|
24
|
+
label: { flexShrink: 1 }
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* A screen's primary action, raised over its content. Its icon is its
|
|
28
|
+
* children; given a `label` it is the extended FAB, with the label after the
|
|
29
|
+
* icon. Given `href` it is a link with the same appearance.
|
|
30
|
+
*
|
|
31
|
+
* ```tsx
|
|
32
|
+
* <Fab aria-label="Label">
|
|
33
|
+
* <PlusIcon />
|
|
34
|
+
* </Fab>
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* Without a `label` it is an icon alone, so `aria-label` is required there.
|
|
38
|
+
* `style`, `ref` and `testID` land on the `Pressable`, which is what a call
|
|
39
|
+
* site positions over its screen.
|
|
40
|
+
*/
|
|
41
|
+
function Fab(t0) {
|
|
42
|
+
const $ = c(41);
|
|
43
|
+
let children;
|
|
44
|
+
let delayLongPress;
|
|
45
|
+
let href;
|
|
46
|
+
let label;
|
|
47
|
+
let onBlur;
|
|
48
|
+
let onFocus;
|
|
49
|
+
let onHoverIn;
|
|
50
|
+
let onHoverOut;
|
|
51
|
+
let onLongPress;
|
|
52
|
+
let onPress;
|
|
53
|
+
let onPressIn;
|
|
54
|
+
let onPressOut;
|
|
55
|
+
let props;
|
|
56
|
+
let ref;
|
|
57
|
+
let slot;
|
|
58
|
+
let style;
|
|
59
|
+
let t1;
|
|
60
|
+
let t2;
|
|
61
|
+
let t3;
|
|
62
|
+
let t4;
|
|
63
|
+
let t5;
|
|
64
|
+
let type;
|
|
65
|
+
if ($[0] !== t0) {
|
|
66
|
+
({children, delayLongPress, disableRipple: t1, href, isDisabled: t2, label, onBlur, onFocus, onHoverIn, onHoverOut, onLongPress, onPress, onPressIn, onPressOut, ref, size: t3, slot, style, tone: t4, type, variant: t5, ...props} = t0);
|
|
67
|
+
$[0] = t0;
|
|
68
|
+
$[1] = children;
|
|
69
|
+
$[2] = delayLongPress;
|
|
70
|
+
$[3] = href;
|
|
71
|
+
$[4] = label;
|
|
72
|
+
$[5] = onBlur;
|
|
73
|
+
$[6] = onFocus;
|
|
74
|
+
$[7] = onHoverIn;
|
|
75
|
+
$[8] = onHoverOut;
|
|
76
|
+
$[9] = onLongPress;
|
|
77
|
+
$[10] = onPress;
|
|
78
|
+
$[11] = onPressIn;
|
|
79
|
+
$[12] = onPressOut;
|
|
80
|
+
$[13] = props;
|
|
81
|
+
$[14] = ref;
|
|
82
|
+
$[15] = slot;
|
|
83
|
+
$[16] = style;
|
|
84
|
+
$[17] = t1;
|
|
85
|
+
$[18] = t2;
|
|
86
|
+
$[19] = t3;
|
|
87
|
+
$[20] = t4;
|
|
88
|
+
$[21] = t5;
|
|
89
|
+
$[22] = type;
|
|
90
|
+
} else {
|
|
91
|
+
children = $[1];
|
|
92
|
+
delayLongPress = $[2];
|
|
93
|
+
href = $[3];
|
|
94
|
+
label = $[4];
|
|
95
|
+
onBlur = $[5];
|
|
96
|
+
onFocus = $[6];
|
|
97
|
+
onHoverIn = $[7];
|
|
98
|
+
onHoverOut = $[8];
|
|
99
|
+
onLongPress = $[9];
|
|
100
|
+
onPress = $[10];
|
|
101
|
+
onPressIn = $[11];
|
|
102
|
+
onPressOut = $[12];
|
|
103
|
+
props = $[13];
|
|
104
|
+
ref = $[14];
|
|
105
|
+
slot = $[15];
|
|
106
|
+
style = $[16];
|
|
107
|
+
t1 = $[17];
|
|
108
|
+
t2 = $[18];
|
|
109
|
+
t3 = $[19];
|
|
110
|
+
t4 = $[20];
|
|
111
|
+
t5 = $[21];
|
|
112
|
+
type = $[22];
|
|
113
|
+
}
|
|
114
|
+
const disableRipple = t1 === void 0 ? false : t1;
|
|
115
|
+
const isDisabled = t2 === void 0 ? false : t2;
|
|
116
|
+
const size = t3 === void 0 ? "md" : t3;
|
|
117
|
+
const tone = t4 === void 0 ? "primary" : t4;
|
|
118
|
+
const variant = t5 === void 0 ? "tonal" : t5;
|
|
119
|
+
const theme = useTheme();
|
|
120
|
+
const role = useTypeRole(EXTENDED_FAB_ROLES[size]);
|
|
121
|
+
const t6 = slot ?? "default";
|
|
122
|
+
let t7;
|
|
123
|
+
if ($[23] !== href || $[24] !== onPress || $[25] !== t6 || $[26] !== type) {
|
|
124
|
+
t7 = {
|
|
125
|
+
defaultSelected: void 0,
|
|
126
|
+
href,
|
|
127
|
+
isSelected: void 0,
|
|
128
|
+
isToggle: false,
|
|
129
|
+
onChange: void 0,
|
|
130
|
+
onPress,
|
|
131
|
+
slot: t6,
|
|
132
|
+
type
|
|
133
|
+
};
|
|
134
|
+
$[23] = href;
|
|
135
|
+
$[24] = onPress;
|
|
136
|
+
$[25] = t6;
|
|
137
|
+
$[26] = type;
|
|
138
|
+
$[27] = t7;
|
|
139
|
+
} else t7 = $[27];
|
|
140
|
+
const action = useButtonAction(t7);
|
|
141
|
+
let t8;
|
|
142
|
+
if ($[28] !== delayLongPress || $[29] !== href || $[30] !== onHoverIn || $[31] !== onHoverOut || $[32] !== onLongPress || $[33] !== ref || $[34] !== slot) {
|
|
143
|
+
t8 = {
|
|
144
|
+
delayLongPress,
|
|
145
|
+
href,
|
|
146
|
+
onHoverIn,
|
|
147
|
+
onHoverOut,
|
|
148
|
+
onLongPress,
|
|
149
|
+
ref,
|
|
150
|
+
slot
|
|
151
|
+
};
|
|
152
|
+
$[28] = delayLongPress;
|
|
153
|
+
$[29] = href;
|
|
154
|
+
$[30] = onHoverIn;
|
|
155
|
+
$[31] = onHoverOut;
|
|
156
|
+
$[32] = onLongPress;
|
|
157
|
+
$[33] = ref;
|
|
158
|
+
$[34] = slot;
|
|
159
|
+
$[35] = t8;
|
|
160
|
+
} else t8 = $[35];
|
|
161
|
+
const t9 = useSlotTrigger(t8);
|
|
162
|
+
let hoverIn;
|
|
163
|
+
let hoverOut;
|
|
164
|
+
let longPress;
|
|
165
|
+
let triggerProps;
|
|
166
|
+
if ($[36] !== t9) {
|
|
167
|
+
({onHoverIn: hoverIn, onHoverOut: hoverOut, onLongPress: longPress, ...triggerProps} = t9);
|
|
168
|
+
$[36] = t9;
|
|
169
|
+
$[37] = hoverIn;
|
|
170
|
+
$[38] = hoverOut;
|
|
171
|
+
$[39] = longPress;
|
|
172
|
+
$[40] = triggerProps;
|
|
173
|
+
} else {
|
|
174
|
+
hoverIn = $[37];
|
|
175
|
+
hoverOut = $[38];
|
|
176
|
+
longPress = $[39];
|
|
177
|
+
triggerProps = $[40];
|
|
178
|
+
}
|
|
179
|
+
const palettes = fabPalettesOf(theme);
|
|
180
|
+
const colors = isDisabled ? palettes.disabled : palettes[variant][tone];
|
|
181
|
+
const feedback = usePressFeedback({
|
|
182
|
+
color: colors.content,
|
|
183
|
+
disabled: isDisabled,
|
|
184
|
+
disableRipple,
|
|
185
|
+
onBlur,
|
|
186
|
+
onFocus,
|
|
187
|
+
onHoverIn: hoverIn,
|
|
188
|
+
onHoverOut: hoverOut,
|
|
189
|
+
onPressIn,
|
|
190
|
+
onPressOut
|
|
191
|
+
});
|
|
192
|
+
const corner = fabCornersOf(theme)[size];
|
|
193
|
+
const isExtended = label !== void 0;
|
|
194
|
+
return /* @__PURE__ */ jsxs(AnimatedPressable, {
|
|
195
|
+
role: href === void 0 ? "button" : "link",
|
|
196
|
+
...props,
|
|
197
|
+
...triggerProps,
|
|
198
|
+
...feedback.handlers,
|
|
199
|
+
disabled: isDisabled,
|
|
200
|
+
onLongPress: longPress,
|
|
201
|
+
onPress: action.onPress,
|
|
202
|
+
style: composeStyles(styles.base, isExtended ? extendedFabSizesOf(theme)[size] : fabSizesOf(theme)[size], corner, colors.container, fabShadowOf(feedback, isDisabled, theme), feedback.ring, style),
|
|
203
|
+
children: [
|
|
204
|
+
/* @__PURE__ */ jsx(View, {
|
|
205
|
+
style: composeStyles(buttonStyles.clip, corner),
|
|
206
|
+
children: feedback.layer
|
|
207
|
+
}),
|
|
208
|
+
children === void 0 ? null : /* @__PURE__ */ jsx(View, {
|
|
209
|
+
style: styles.icon,
|
|
210
|
+
children: /* @__PURE__ */ jsx(IconStyleContext, {
|
|
211
|
+
value: iconStyleOf(colors.content, size),
|
|
212
|
+
children
|
|
213
|
+
})
|
|
214
|
+
}),
|
|
215
|
+
isExtended ? /* @__PURE__ */ jsx(Text, {
|
|
216
|
+
style: composeStyles(role, styles.label, colors.label),
|
|
217
|
+
children: label
|
|
218
|
+
}) : null
|
|
219
|
+
]
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
function iconStyleOf(color, size) {
|
|
223
|
+
return {
|
|
224
|
+
color,
|
|
225
|
+
size: FAB_ICON_SIZES[size]
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
//#endregion
|
|
229
|
+
export { Fab };
|
|
230
|
+
|
|
231
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["ComponentRef","ReactNode","Ref","PressableProps","StyleProp","TextStyle","ViewStyle","AnimatedStyle","Text","NativeText","StyleSheet","View","ButtonLinkForm","ButtonPressForm","FabSize","FabTone","FabVariant","IconStyle","AnimatedPressable","buttonStyles","useButtonAction","useSlotTrigger","EXTENDED_FAB_ROLES","extendedFabSizesOf","FAB_ICON_SIZES","fabCornersOf","fabPalettesOf","fabShadowOf","fabSizesOf","IconStyleContext","usePressFeedback","useTheme","composeStyles","useTypeRole","FabNaming","label","FabPressForm","Omit","isPending","pendingLabel","FabProps","children","disableRipple","isDisabled","ref","size","style","tone","variant","styles","create","base","alignItems","flexDirection","flexShrink","justifyContent","icon","Fab","t0","$","_c","delayLongPress","href","onBlur","onFocus","onHoverIn","onHoverOut","onLongPress","onPress","onPressIn","onPressOut","props","slot","t1","t2","t3","t4","t5","type","undefined","theme","role","t6","t7","defaultSelected","isSelected","isToggle","onChange","action","t8","t9","hoverIn","hoverOut","longPress","triggerProps","palettes","colors","disabled","feedback","color","content","corner","isExtended","handlers","container","ring","clip","layer","iconStyleOf","_c","NativeText"],"sources":["../../../src/components/fab/index.tsx"],"sourcesContent":["import type { ComponentRef, ReactNode, Ref } from 'react'\nimport type {\n PressableProps,\n StyleProp,\n TextStyle,\n ViewStyle,\n} from 'react-native'\nimport type { AnimatedStyle } from 'react-native-reanimated'\n\nimport { Text as NativeText, StyleSheet, View } from 'react-native'\n\nimport type { ButtonLinkForm, ButtonPressForm } from '../../button'\nimport type { FabSize, FabTone, FabVariant } from '../../fab'\nimport type { IconStyle } from '../../glyphs/icon-style'\n\nimport {\n AnimatedPressable,\n buttonStyles,\n useButtonAction,\n useSlotTrigger,\n} from '../../button'\nimport {\n EXTENDED_FAB_ROLES,\n extendedFabSizesOf,\n FAB_ICON_SIZES,\n fabCornersOf,\n fabPalettesOf,\n fabShadowOf,\n fabSizesOf,\n} from '../../fab'\nimport { IconStyleContext } from '../../glyphs/icon-style'\nimport { usePressFeedback } from '../../press'\nimport { useTheme } from '../../theme/scope'\nimport { composeStyles } from '../../theme/styles'\nimport { useTypeRole } from '../../typography/roles'\n\n// kanso-ui's Fab: the FAB page's floating action button, and the extended\n// FAB page's form of it with a label. A screen's primary action, raised over\n// the content on the pages' level 3 shadow and lifted to level 4 under a\n// hovering pointer, which is an iPad's or an Android mouse's, since a finger\n// never hovers.\n//\n// Three sizes, the pages' FAB, medium FAB and large FAB: `md` is 56dp with a\n// 24dp icon and a 16dp corner, `lg` 80dp with 28dp and 20dp, and `xl` 96dp\n// with 36dp and 28dp. The extended form keeps the size's height and corner\n// and sets a label after the icon in the size's type role, title medium,\n// title large and headline small, with 16dp, 26dp and 28dp of padding and\n// 8dp, 12dp and 16dp before the label. The 80dp size, the 20dp corner and\n// the 26dp and 28dp paddings fall between steps of their scales and are\n// written out. The pages' small FAB is gone from the newer set, so there is\n// no `xs`.\n//\n// Six colour pairs, by `tone` and `variant`: `tonal` draws the tone's\n// container pair, primary container being the pages' default, and `filled`\n// the tone itself, as Button's two variants of those names do.\n//\n// The hover, focus and pressed layers and the ripple are src/press's, in the\n// icon's colour over the container, as Button's are. The pages give no\n// disabled FAB; a disabled one takes the container every disabled button\n// takes, on-surface at the two disabled opacities, and drops its shadow.\n//\n// Unlike Button, the corner does not morph: the pages draw the FAB at one\n// shape in every state, as web does. Web's forced-colours rule has no\n// counterpart on iOS or Android and is not drawn.\n//\n// It is placed as any view is. A column stretches the extended form as it\n// does a Button, so a FAB floating over a screen takes its place from the\n// call site's `style`.\n//\n// What a press does, the link form and the slot it fills in an overlay are\n// src/button's, shared with Button and IconButton. The metrics and colours\n// are src/fab's, shared with FabMenu's FAB.\n\ntype FabNaming =\n | {\n /**\n * What the FAB does, in words. A FAB without a `label` is an icon\n * alone, which has no name of its own, so it needs this; with a\n * `label` the label is its name.\n */\n readonly 'aria-label': string\n readonly label?: never\n }\n | {\n readonly 'aria-label'?: string\n /**\n * A label after the icon, which makes this the extended FAB: as tall\n * as the size, as wide as what it holds.\n */\n readonly label: ReactNode\n }\n\n// A plain button's form, without the pending state web's FAB leaves out.\n// The two are named `never`, so a FAB given them does not compile.\ntype FabPressForm = Omit<ButtonPressForm, 'isPending' | 'pendingLabel'> & {\n readonly isPending?: never\n readonly pendingLabel?: never\n}\n\ntype FabProps = (ButtonLinkForm | FabPressForm) &\n FabNaming &\n Omit<PressableProps, 'aria-label' | 'children' | 'disabled' | 'style'> & {\n /**\n * The FAB's icon. The FAB hands it its colour and the size's icon size\n * through `useIconStyle()`.\n */\n readonly children?: ReactNode\n /**\n * Draws no press ripple. The state layers are unaffected.\n * @default false\n */\n readonly disableRipple?: boolean\n /**\n * Draws the FAB disabled, without its shadow, and takes no presses.\n * @default false\n */\n readonly isDisabled?: boolean\n readonly ref?: Ref<ComponentRef<typeof View>>\n /**\n * The pages' three sizes: `md` the FAB at 56dp, `lg` the medium FAB at\n * 80dp and `xl` the large FAB at 96dp.\n * @default 'md'\n */\n readonly size?: FabSize\n readonly style?: StyleProp<ViewStyle>\n /**\n * The colour role the FAB is drawn in.\n * @default 'primary'\n */\n readonly tone?: FabTone\n /**\n * `tonal` draws the tone's container pair, the pages' default; `filled`\n * draws the tone itself.\n * @default 'tonal'\n */\n readonly variant?: FabVariant\n }\n\nconst styles = StyleSheet.create({\n // The icon and the label sit in the middle of the container, and a row\n // never squeezes it.\n base: {\n alignItems: 'center',\n flexDirection: 'row',\n flexShrink: 0,\n justifyContent: 'center',\n },\n icon: {\n alignItems: 'center',\n flexShrink: 0,\n justifyContent: 'center',\n },\n label: {\n flexShrink: 1,\n },\n})\n\n/**\n * A screen's primary action, raised over its content. Its icon is its\n * children; given a `label` it is the extended FAB, with the label after the\n * icon. Given `href` it is a link with the same appearance.\n *\n * ```tsx\n * <Fab aria-label=\"Label\">\n * <PlusIcon />\n * </Fab>\n * ```\n *\n * Without a `label` it is an icon alone, so `aria-label` is required there.\n * `style`, `ref` and `testID` land on the `Pressable`, which is what a call\n * site positions over its screen.\n */\nfunction Fab({\n children,\n delayLongPress,\n disableRipple = false,\n href,\n isDisabled = false,\n label,\n onBlur,\n onFocus,\n onHoverIn,\n onHoverOut,\n onLongPress,\n onPress,\n onPressIn,\n onPressOut,\n ref,\n size = 'md',\n slot,\n style,\n tone = 'primary',\n type,\n variant = 'tonal',\n ...props\n}: FabProps) {\n const theme = useTheme()\n const role = useTypeRole(EXTENDED_FAB_ROLES[size])\n const action = useButtonAction({\n defaultSelected: undefined,\n href,\n isSelected: undefined,\n isToggle: false,\n onChange: undefined,\n onPress,\n slot: slot ?? 'default',\n type,\n })\n const {\n onHoverIn: hoverIn,\n onHoverOut: hoverOut,\n onLongPress: longPress,\n ...triggerProps\n } = useSlotTrigger({\n delayLongPress,\n href,\n onHoverIn,\n onHoverOut,\n onLongPress,\n ref,\n slot,\n })\n const palettes = fabPalettesOf(theme)\n const colors = isDisabled ? palettes.disabled : palettes[variant][tone]\n const feedback = usePressFeedback({\n color: colors.content,\n disabled: isDisabled,\n disableRipple,\n onBlur,\n onFocus,\n onHoverIn: hoverIn,\n onHoverOut: hoverOut,\n onPressIn,\n onPressOut,\n })\n const corner = fabCornersOf(theme)[size]\n const isExtended = label !== undefined\n\n return (\n <AnimatedPressable\n role={href === undefined ? 'button' : 'link'}\n {...props}\n {...triggerProps}\n {...feedback.handlers}\n disabled={isDisabled}\n onLongPress={longPress}\n onPress={action.onPress}\n style={composeStyles<AnimatedStyle<ViewStyle>>(\n styles.base,\n isExtended ? extendedFabSizesOf(theme)[size] : fabSizesOf(theme)[size],\n corner,\n colors.container,\n fabShadowOf(feedback, isDisabled, theme),\n feedback.ring,\n style,\n )}\n >\n <View style={composeStyles<ViewStyle>(buttonStyles.clip, corner)}>\n {feedback.layer}\n </View>\n {children === undefined ? null : (\n <View style={styles.icon}>\n <IconStyleContext value={iconStyleOf(colors.content, size)}>\n {children}\n </IconStyleContext>\n </View>\n )}\n {isExtended ? (\n <NativeText\n style={composeStyles<TextStyle>(role, styles.label, colors.label)}\n >\n {label}\n </NativeText>\n ) : null}\n </AnimatedPressable>\n )\n}\n\nfunction iconStyleOf(color: string, size: FabSize): IconStyle {\n return { color, size: FAB_ICON_SIZES[size] }\n}\n\nexport { Fab }\nexport type { FabProps, FabSize, FabTone, FabVariant }\n"],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { FabSize, FabTone } from "../../fab/index.js";
|
|
2
|
+
import { HostInstance, PressableProps, StyleProp, View, ViewStyle } from "react-native";
|
|
3
|
+
import { ComponentRef, ReactNode, Ref } from "react";
|
|
4
|
+
import { Key } from "react-stately";
|
|
5
|
+
//#region src/components/fab-menu/index.d.ts
|
|
6
|
+
type FabMenuItemProps = Omit<PressableProps, 'children' | 'disabled' | 'id' | 'role' | 'style'> & {
|
|
7
|
+
/** The action's name, drawn as its label. */
|
|
8
|
+
readonly children: ReactNode;
|
|
9
|
+
/**
|
|
10
|
+
* An icon before the label, which takes the label's colour at the page's
|
|
11
|
+
* 24dp through `useIconStyle()`.
|
|
12
|
+
*/
|
|
13
|
+
readonly icon?: ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* The key the action is reported by. Give one to every action the call
|
|
16
|
+
* site needs to tell apart.
|
|
17
|
+
*/
|
|
18
|
+
readonly id?: Key;
|
|
19
|
+
/**
|
|
20
|
+
* Draws the action disabled, without its shadow, and takes no presses on
|
|
21
|
+
* it.
|
|
22
|
+
* @default false
|
|
23
|
+
*/
|
|
24
|
+
readonly isDisabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Called when a press runs the action, in place of the menu's `onAction`
|
|
27
|
+
* for this one.
|
|
28
|
+
*/
|
|
29
|
+
readonly onAction?: () => void;
|
|
30
|
+
readonly ref?: Ref<HostInstance>;
|
|
31
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
32
|
+
/**
|
|
33
|
+
* The action's text, read off `children` when they are a plain string, so
|
|
34
|
+
* an action whose label is an element passes it.
|
|
35
|
+
*/
|
|
36
|
+
readonly textValue?: string;
|
|
37
|
+
};
|
|
38
|
+
type FabMenuProps = {
|
|
39
|
+
/**
|
|
40
|
+
* What the FAB does, in words: an icon alone has no name, and the menu
|
|
41
|
+
* takes its name from the FAB that opens it.
|
|
42
|
+
*/
|
|
43
|
+
readonly 'aria-label': string;
|
|
44
|
+
/** The actions, as `FabMenu.Item`s. The page asks for two to six. */
|
|
45
|
+
readonly children: ReactNode;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the menu starts open, when it keeps its own state.
|
|
48
|
+
* @default false
|
|
49
|
+
*/
|
|
50
|
+
readonly defaultOpen?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* The FAB's icon while the menu is closed. The FAB hands it its colour and
|
|
53
|
+
* the size's icon size through `useIconStyle()`.
|
|
54
|
+
*/
|
|
55
|
+
readonly icon: ReactNode;
|
|
56
|
+
/** Whether the menu is open, when the call site holds the state. */
|
|
57
|
+
readonly isOpen?: boolean;
|
|
58
|
+
/** Called with an action's `id` when a press runs it. */
|
|
59
|
+
readonly onAction?: (key: Key) => void;
|
|
60
|
+
/** Called with the new state as the menu opens or closes. */
|
|
61
|
+
readonly onOpenChange?: (isOpen: boolean) => void;
|
|
62
|
+
readonly ref?: Ref<ComponentRef<typeof View>>;
|
|
63
|
+
/**
|
|
64
|
+
* The FAB's size while the menu is closed, as Fab's: `md` 56dp, `lg` 80dp
|
|
65
|
+
* or `xl` 96dp. Open, it is the close button's 56dp whatever it was.
|
|
66
|
+
* @default 'md'
|
|
67
|
+
*/
|
|
68
|
+
readonly size?: FabSize;
|
|
69
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
70
|
+
readonly testID?: string;
|
|
71
|
+
/**
|
|
72
|
+
* The page's three colour sets: the close button takes the tone and the
|
|
73
|
+
* actions its container pair.
|
|
74
|
+
* @default 'primary'
|
|
75
|
+
*/
|
|
76
|
+
readonly tone?: FabTone;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* A FAB that opens a column of related actions above it, and closes them
|
|
80
|
+
* again. The actions are `FabMenu.Item`s.
|
|
81
|
+
*
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <FabMenu aria-label="Label" icon={<PlusIcon />}>
|
|
84
|
+
* <FabMenu.Item icon={<FirstIcon />} id="first">
|
|
85
|
+
* First item
|
|
86
|
+
* </FabMenu.Item>
|
|
87
|
+
* <FabMenu.Item icon={<SecondIcon />} id="second">
|
|
88
|
+
* Second item
|
|
89
|
+
* </FabMenu.Item>
|
|
90
|
+
* </FabMenu>
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* `style`, `ref` and `testID` land on the FAB, which is what a call site
|
|
94
|
+
* positions over its screen.
|
|
95
|
+
*/
|
|
96
|
+
declare function FabMenu({ 'aria-label': label, children, defaultOpen, icon, isOpen, onAction, onOpenChange, ref, size, style, testID, tone }: FabMenuProps): import("react").JSX.Element;
|
|
97
|
+
declare namespace FabMenu {
|
|
98
|
+
var Item: typeof FabMenuItem;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* One action: a pill holding an icon and a label, on the menu's tone. A press
|
|
102
|
+
* on it runs it and closes the menu.
|
|
103
|
+
*
|
|
104
|
+
* The menu draws it from its entry in the collection, so it renders nothing
|
|
105
|
+
* on its own. `style`, `ref` and `testID` land on the pill.
|
|
106
|
+
*/
|
|
107
|
+
declare function FabMenuItem(_props: FabMenuItemProps): null;
|
|
108
|
+
declare namespace FabMenuItem {
|
|
109
|
+
var getCollectionNode: (props: FabMenuItemProps) => Generator<{
|
|
110
|
+
hasChildNodes: boolean;
|
|
111
|
+
key: Key | undefined;
|
|
112
|
+
props: FabMenuItemProps;
|
|
113
|
+
rendered: ReactNode;
|
|
114
|
+
textValue: string;
|
|
115
|
+
type: string;
|
|
116
|
+
}, void, unknown>;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { FabMenu, FabMenuItem, type FabMenuItemProps, type FabMenuProps };
|
|
120
|
+
//# sourceMappingURL=index.d.ts.map
|