react-native-terra-ui 0.11.5 → 0.11.7
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/CHANGELOG.md +13 -0
- package/lib/module/components/chip/Chip.js +25 -8
- package/lib/module/components/chip/Chip.js.map +1 -1
- package/lib/module/components/chip/utils.js +1 -1
- package/lib/module/components/chip/utils.js.map +1 -1
- package/lib/module/components/header/index.js.map +1 -1
- package/lib/module/components/header/parts/HeaderAccessory.js +58 -0
- package/lib/module/components/header/parts/HeaderAccessory.js.map +1 -0
- package/lib/module/components/header/parts/HeaderSurface.js +58 -0
- package/lib/module/components/header/parts/HeaderSurface.js.map +1 -0
- package/lib/module/components/header/types.js +2 -0
- package/lib/module/components/header/types.js.map +1 -0
- package/lib/module/components/header/variants/LargeTitleHeader/index.js +114 -46
- package/lib/module/components/header/variants/LargeTitleHeader/index.js.map +1 -1
- package/lib/module/components/header/variants/TitleHeader/index.js +33 -28
- package/lib/module/components/header/variants/TitleHeader/index.js.map +1 -1
- package/lib/module/components/screen/ScreenContext.js +16 -1
- package/lib/module/components/screen/ScreenContext.js.map +1 -1
- package/lib/module/components/screen/ScreenList.js +24 -5
- package/lib/module/components/screen/ScreenList.js.map +1 -1
- package/lib/module/components/screen/ScreenScrollView.js +10 -4
- package/lib/module/components/screen/ScreenScrollView.js.map +1 -1
- package/lib/typescript/src/components/chip/Chip.d.ts +8 -0
- package/lib/typescript/src/components/chip/Chip.d.ts.map +1 -1
- package/lib/typescript/src/components/chip/utils.d.ts +6 -1
- package/lib/typescript/src/components/chip/utils.d.ts.map +1 -1
- package/lib/typescript/src/components/header/index.d.ts +1 -0
- package/lib/typescript/src/components/header/index.d.ts.map +1 -1
- package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts +19 -0
- package/lib/typescript/src/components/header/parts/HeaderAccessory.d.ts.map +1 -0
- package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts +22 -0
- package/lib/typescript/src/components/header/parts/HeaderSurface.d.ts.map +1 -0
- package/lib/typescript/src/components/header/types.d.ts +15 -0
- package/lib/typescript/src/components/header/types.d.ts.map +1 -0
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts +8 -1
- package/lib/typescript/src/components/header/variants/LargeTitleHeader/index.d.ts.map +1 -1
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts +14 -1
- package/lib/typescript/src/components/header/variants/TitleHeader/index.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenContext.d.ts +22 -0
- package/lib/typescript/src/components/screen/ScreenContext.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenList.d.ts.map +1 -1
- package/lib/typescript/src/components/screen/ScreenScrollView.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/chip/Chip.tsx +22 -9
- package/src/components/chip/utils.ts +7 -2
- package/src/components/header/index.ts +1 -0
- package/src/components/header/parts/HeaderAccessory.tsx +55 -0
- package/src/components/header/parts/HeaderSurface.tsx +62 -0
- package/src/components/header/types.ts +15 -0
- package/src/components/header/variants/LargeTitleHeader/index.tsx +114 -42
- package/src/components/header/variants/TitleHeader/index.tsx +45 -22
- package/src/components/screen/ScreenContext.tsx +42 -0
- package/src/components/screen/ScreenList.tsx +30 -5
- package/src/components/screen/ScreenScrollView.tsx +28 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/header/variants/TitleHeader/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/components/header/variants/TitleHeader/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,OAAO,CAAC;AAKhE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAM/C,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,yBAAsB,CAAC;AAGpF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAa,CAAC;AAG1D,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,sCAAsC;IACtC,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,uCAAuC;IACvC,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAC1C,8DAA8D;IAC9D,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAC;IACnC,mGAAmG;IACnG,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kCAAkC;IAClC,EAAE,CAAC,EAAE,UAAU,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,cAAc,EACd,eAAe,EACf,WAAW,EACX,YAAY,EACZ,SAAS,EACT,gBAAsB,EACtB,aAAsB,EACtB,UAAU,EACV,SAAS,EACT,cAAyB,EACzB,UAAU,EACV,EAAE,GACH,EAAE,gBAAgB,+BAiElB"}
|
|
@@ -51,6 +51,28 @@ export interface ScreenContextValue {
|
|
|
51
51
|
margins: ScreenContentPadding;
|
|
52
52
|
/** Whether a `Screen.Header` is present. Used by scroll containers to add top inset. */
|
|
53
53
|
hasHeader: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Measured height (dp) of the pinned accessory a header renders below its bar
|
|
56
|
+
* — a search field, a tab strip. Zero when there is none.
|
|
57
|
+
*
|
|
58
|
+
* The theme header height covers the bar alone, and an accessory is whatever
|
|
59
|
+
* the caller put there, so scroll containers reserve this on top of it. That
|
|
60
|
+
* is why it is measured rather than declared: only the accessory knows how
|
|
61
|
+
* tall it is, and it can change with Dynamic Type or its own content.
|
|
62
|
+
*/
|
|
63
|
+
headerAccessoryHeight: number;
|
|
64
|
+
/**
|
|
65
|
+
* Reports the measured accessory height. Called by the header that owns the
|
|
66
|
+
* accessory; zero releases the reserved space.
|
|
67
|
+
*/
|
|
68
|
+
setHeaderAccessoryHeight: (height: number) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Primary scroll container's resolved top padding in dp, including header clearance.
|
|
71
|
+
* Used to position a sticky accessory below the large title at scroll offset zero.
|
|
72
|
+
*/
|
|
73
|
+
contentTopPadding: number;
|
|
74
|
+
/** Reported by the primary scroll container from its layout or resolved padding. */
|
|
75
|
+
setContentTopPadding: (padding: number) => void;
|
|
54
76
|
/** Vertical scroll offset, updated on the UI thread for header animations. */
|
|
55
77
|
scrollY: SharedValue<number>;
|
|
56
78
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScreenContext.d.ts","sourceRoot":"","sources":["../../../../../src/components/screen/ScreenContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAA8C,MAAM,OAAO,CAAC;AAElG,OAAO,QAAQ,EAAE,EACf,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAS,CAAC;AAEpE,6EAA6E;AAC7E,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAE/D,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,kBAAkB,CAAC;AAEzD,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,cAAc,EAAE,oBAAoB,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;;;;;;OASG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;OAUG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;;;;;OAQG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,sCAAsC;IACtC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;IACnB,8EAA8E;IAC9E,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B;;;OAGG;IACH,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,iGAAiG;IACjG,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,SAAS,EAAE,eAAe,CAAC;IAC3B,yDAAyD;IACzD,aAAa,EAAE,sBAAsB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAE/D,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,oDAAiD,CAAC;AAE5E,4DAA4D;AAC5D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,SAAS,CAAC;IACpB,sFAAsF;IACtF,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,UAA0B,EAC1B,QAAQ,EACR,cAAsB,EACtB,QAAiB,EACjB,sBAA8B,EAC9B,qBAA6B,EAC7B,sBAA8B,EAC9B,SAAiB,GAClB,EAAE,yBAAyB,+
|
|
1
|
+
{"version":3,"file":"ScreenContext.d.ts","sourceRoot":"","sources":["../../../../../src/components/screen/ScreenContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAA8C,MAAM,OAAO,CAAC;AAElG,OAAO,QAAQ,EAAE,EACf,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,WAAW,EAIjB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,YAAS,CAAC;AAEpE,6EAA6E;AAC7E,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAE/D,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,kBAAkB,CAAC;AAEzD,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,cAAc,EAAE,oBAAoB,CAAC;IACrC,6EAA6E;IAC7E,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;;;;;;OASG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC;;;;;;;;;;OAUG;IACH,qBAAqB,EAAE,OAAO,CAAC;IAC/B;;;;;;;;OAQG;IACH,sBAAsB,EAAE,OAAO,CAAC;IAChC,sCAAsC;IACtC,OAAO,EAAE,oBAAoB,CAAC;IAC9B,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;OAQG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;OAGG;IACH,wBAAwB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oFAAoF;IACpF,oBAAoB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,8EAA8E;IAC9E,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B;;;OAGG;IACH,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1C;;;OAGG;IACH,iBAAiB,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,iGAAiG;IACjG,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD;;;;OAIG;IACH,SAAS,EAAE,eAAe,CAAC;IAC3B,yDAAyD;IACzD,aAAa,EAAE,sBAAsB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAE/D,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,oDAAiD,CAAC;AAE5E,4DAA4D;AAC5D,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,SAAS,CAAC;IACpB,sFAAsF;IACtF,cAAc,CAAC,EAAE,oBAAoB,CAAC;IACtC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,qFAAqF;IACrF,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,0FAA0F;IAC1F,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,6EAA6E;IAC7E,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,UAA0B,EAC1B,QAAQ,EACR,cAAsB,EACtB,QAAiB,EACjB,sBAA8B,EAC9B,qBAA6B,EAC7B,sBAA8B,EAC9B,SAAiB,GAClB,EAAE,yBAAyB,+BA4E3B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAM9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScreenList.d.ts","sourceRoot":"","sources":["../../../../../src/components/screen/ScreenList.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,EAE1B,KAAK,WAAW,EAEhB,KAAK,YAAY,EAEjB,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"ScreenList.d.ts","sourceRoot":"","sources":["../../../../../src/components/screen/ScreenList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScreenScrollView.d.ts","sourceRoot":"","sources":["../../../../../src/components/screen/ScreenScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,SAAS,
|
|
1
|
+
{"version":3,"file":"ScreenScrollView.d.ts","sourceRoot":"","sources":["../../../../../src/components/screen/ScreenScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,SAAS,EAAe,MAAM,OAAO,CAAC;AAC7F,OAAO,EAGL,KAAK,eAAe,EACpB,KAAK,SAAS,EAEd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAatB,OAAO,KAAK,EAAwB,qBAAqB,EAAE,MAAM,YAAS,CAAC;AAG3E,qFAAqF;AACrF,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,eAAe,EAAE,YAAY,CAAC,EAAE,qBAAqB;IACvG,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iEAAiE;IACjE,YAAY,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACpC,uFAAuF;IACvF,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,8MAoF5B,CAAC"}
|
package/package.json
CHANGED
|
@@ -14,6 +14,14 @@ export interface ChipProps extends ViewProps {
|
|
|
14
14
|
size?: ChipSize;
|
|
15
15
|
variant?: ChipVariant;
|
|
16
16
|
color?: ChipColor;
|
|
17
|
+
/**
|
|
18
|
+
* Fill behind the chip, overriding the one its `variant` would paint.
|
|
19
|
+
*
|
|
20
|
+
* Only `outline` has a fill worth naming a default for — `'surface.default'`,
|
|
21
|
+
* so an outlined chip reads as a solid capsule rather than a ring over
|
|
22
|
+
* whatever it happens to sit on. Pass `'transparent'` to get the ring back.
|
|
23
|
+
*/
|
|
24
|
+
background?: ColorToken;
|
|
17
25
|
children?: ReactNode;
|
|
18
26
|
}
|
|
19
27
|
|
|
@@ -177,9 +185,10 @@ function renderChildren(children: ReactNode): ReactNode {
|
|
|
177
185
|
// ─── Component ────────────────────────────────────────────────────────────────
|
|
178
186
|
|
|
179
187
|
const ChipRoot = forwardRef<ComponentRef<typeof View>, ChipProps>(function Chip(
|
|
180
|
-
{ size = "md", variant = "soft", color = "secondary", children, style, ...rest },
|
|
188
|
+
{ size = "md", variant = "soft", color = "secondary", background, children, style, ...rest },
|
|
181
189
|
ref
|
|
182
190
|
) {
|
|
191
|
+
const { theme } = useUnistyles();
|
|
183
192
|
// Compound variants only match the 5 named schemes above — an arbitrary
|
|
184
193
|
// literal never matches one, so it's cast to satisfy `useVariants`'s
|
|
185
194
|
// literal-union type while still comparing against the real value below.
|
|
@@ -195,15 +204,20 @@ const ChipRoot = forwardRef<ComponentRef<typeof View>, ChipProps>(function Chip(
|
|
|
195
204
|
const customPaint =
|
|
196
205
|
customColors && variant !== "ghost"
|
|
197
206
|
? {
|
|
198
|
-
|
|
207
|
+
// Absent for outline, whose fill comes from the `outline` style
|
|
208
|
+
// variant — spreading `undefined` here would clear it instead.
|
|
209
|
+
...(customColors.bg === undefined ? null : { backgroundColor: customColors.bg }),
|
|
199
210
|
borderColor: customColors.border,
|
|
200
211
|
borderWidth: customColors.borderWidth,
|
|
201
212
|
}
|
|
202
213
|
: null;
|
|
214
|
+
// Last of the paint layers, so an explicit fill beats both the variant's own
|
|
215
|
+
// and the one derived from a custom color literal.
|
|
216
|
+
const backgroundPaint = background ? { backgroundColor: resolveThemeColor(background, theme) } : null;
|
|
203
217
|
|
|
204
218
|
return (
|
|
205
219
|
<ChipContext.Provider value={{ color: fg, size }}>
|
|
206
|
-
<View ref={ref} style={[styles.base, customPaint, style]} {...rest}>
|
|
220
|
+
<View ref={ref} style={[styles.base, customPaint, backgroundPaint, style]} {...rest}>
|
|
207
221
|
{renderChildren(children)}
|
|
208
222
|
</View>
|
|
209
223
|
</ChipContext.Provider>
|
|
@@ -314,7 +328,11 @@ const styles = StyleSheet.create((theme) => {
|
|
|
314
328
|
variant: {
|
|
315
329
|
solid: {},
|
|
316
330
|
soft: {},
|
|
317
|
-
|
|
331
|
+
// The fill every outlined chip gets, whatever its color — the
|
|
332
|
+
// compound rows below only add the ring. A named default lives here
|
|
333
|
+
// rather than in each row so a custom color literal, which matches no
|
|
334
|
+
// compound row at all, is filled the same way.
|
|
335
|
+
outline: { backgroundColor: c["surface.default"] },
|
|
318
336
|
ghost: {
|
|
319
337
|
backgroundColor: "transparent",
|
|
320
338
|
borderColor: "transparent",
|
|
@@ -343,7 +361,6 @@ const styles = StyleSheet.create((theme) => {
|
|
|
343
361
|
color: "primary",
|
|
344
362
|
variant: "outline",
|
|
345
363
|
styles: {
|
|
346
|
-
backgroundColor: "transparent",
|
|
347
364
|
borderColor: c["accent.soft.bg"],
|
|
348
365
|
borderWidth: 1,
|
|
349
366
|
},
|
|
@@ -368,7 +385,6 @@ const styles = StyleSheet.create((theme) => {
|
|
|
368
385
|
color: "secondary",
|
|
369
386
|
variant: "outline",
|
|
370
387
|
styles: {
|
|
371
|
-
backgroundColor: "transparent",
|
|
372
388
|
borderColor: c["neutral.soft.bg"],
|
|
373
389
|
borderWidth: 1,
|
|
374
390
|
},
|
|
@@ -393,7 +409,6 @@ const styles = StyleSheet.create((theme) => {
|
|
|
393
409
|
color: "success",
|
|
394
410
|
variant: "outline",
|
|
395
411
|
styles: {
|
|
396
|
-
backgroundColor: "transparent",
|
|
397
412
|
borderColor: c["success.soft.bg"],
|
|
398
413
|
borderWidth: 1,
|
|
399
414
|
},
|
|
@@ -418,7 +433,6 @@ const styles = StyleSheet.create((theme) => {
|
|
|
418
433
|
color: "warning",
|
|
419
434
|
variant: "outline",
|
|
420
435
|
styles: {
|
|
421
|
-
backgroundColor: "transparent",
|
|
422
436
|
borderColor: c["warning.soft.bg"],
|
|
423
437
|
borderWidth: 1,
|
|
424
438
|
},
|
|
@@ -443,7 +457,6 @@ const styles = StyleSheet.create((theme) => {
|
|
|
443
457
|
color: "danger",
|
|
444
458
|
variant: "outline",
|
|
445
459
|
styles: {
|
|
446
|
-
backgroundColor: "transparent",
|
|
447
460
|
borderColor: c["danger.soft.bg"],
|
|
448
461
|
borderWidth: 1,
|
|
449
462
|
},
|
|
@@ -6,7 +6,12 @@ import { readableOn, withAlpha } from "#utils/color-utils";
|
|
|
6
6
|
// full color scheme.
|
|
7
7
|
|
|
8
8
|
export interface CustomChipColors {
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Undefined for `outline`, which takes the fill its style variant paints
|
|
11
|
+
* rather than deriving one — the outlined chip's fill is a surface, not a
|
|
12
|
+
* tint of the literal, so there is nothing here to derive it from.
|
|
13
|
+
*/
|
|
14
|
+
bg: string | undefined;
|
|
10
15
|
border: string;
|
|
11
16
|
borderWidth: number;
|
|
12
17
|
fg: string;
|
|
@@ -22,7 +27,7 @@ export function getCustomColorColors(
|
|
|
22
27
|
// read as the same weight of colour — one filled, one drawn.
|
|
23
28
|
if (variant === "outline") {
|
|
24
29
|
return {
|
|
25
|
-
bg:
|
|
30
|
+
bg: undefined,
|
|
26
31
|
border: withAlpha(literal, CUSTOM_COLOR_SOFT_ALPHA),
|
|
27
32
|
borderWidth: 1,
|
|
28
33
|
fg: literal,
|
|
@@ -7,6 +7,7 @@ export {
|
|
|
7
7
|
type HeaderDismissNavigation,
|
|
8
8
|
type HeaderDismissProps,
|
|
9
9
|
} from "./header-buttons";
|
|
10
|
+
export type { HeaderAccessoryBehavior, HeaderAccessoryPadding } from "./types";
|
|
10
11
|
export type { LargeTitleHeaderProps } from "./variants/LargeTitleHeader";
|
|
11
12
|
export { LargeTitleHeader } from "./variants/LargeTitleHeader";
|
|
12
13
|
export type { TitleHeaderProps } from "./variants/TitleHeader";
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type ReactNode, useCallback, useEffect } from "react";
|
|
2
|
+
import { type LayoutChangeEvent, type StyleProp, View, type ViewStyle } from "react-native";
|
|
3
|
+
|
|
4
|
+
import Animated from "react-native-reanimated";
|
|
5
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
6
|
+
|
|
7
|
+
import type { HeaderAccessoryPadding } from "../types";
|
|
8
|
+
|
|
9
|
+
export interface HeaderAccessoryProps {
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
/** Horizontal padding around the accessory. */
|
|
12
|
+
padding: HeaderAccessoryPadding;
|
|
13
|
+
/** Reports layout height in dp; reports zero on cleanup to release reserved space. */
|
|
14
|
+
onHeightChange: (height: number) => void;
|
|
15
|
+
/** Additional styles for the accessory container. */
|
|
16
|
+
style?: StyleProp<ViewStyle>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Measures accessory content so the header can reserve space in the scroll container. */
|
|
20
|
+
export function HeaderAccessory({ children, padding, onHeightChange, style }: HeaderAccessoryProps) {
|
|
21
|
+
const handleLayout = useCallback(
|
|
22
|
+
(event: LayoutChangeEvent) => {
|
|
23
|
+
onHeightChange(event.nativeEvent.layout.height);
|
|
24
|
+
},
|
|
25
|
+
[onHeightChange]
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Release the previous owner’s space when the callback changes or the accessory unmounts.
|
|
29
|
+
useEffect(() => () => onHeightChange(0), [onHeightChange]);
|
|
30
|
+
|
|
31
|
+
styles.useVariants({ padding });
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Animated.View style={[styles.accessory, style]} onLayout={handleLayout}>
|
|
35
|
+
{children}
|
|
36
|
+
</Animated.View>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Reserves scroll-content space for the sticky accessory rendered in the header overlay. */
|
|
41
|
+
export function HeaderAccessorySpacer({ height }: { height: number }) {
|
|
42
|
+
return <View style={styles.spacer(height)} />;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const styles = StyleSheet.create((theme) => ({
|
|
46
|
+
accessory: {
|
|
47
|
+
variants: {
|
|
48
|
+
padding: {
|
|
49
|
+
x: { paddingHorizontal: theme.layout.screen.padding.x },
|
|
50
|
+
none: {},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
spacer: (height: number) => ({ height }),
|
|
55
|
+
}));
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { View } from "react-native";
|
|
2
|
+
|
|
3
|
+
import Animated, { type useAnimatedStyle } from "react-native-reanimated";
|
|
4
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
5
|
+
|
|
6
|
+
import { HEADER_FADE_EXTENT, HeaderGradientOverlay } from "./HeaderGradientOverlay";
|
|
7
|
+
|
|
8
|
+
type HeaderOpacityStyle = ReturnType<typeof useAnimatedStyle<{ opacity: number }>>;
|
|
9
|
+
|
|
10
|
+
export interface HeaderSurfaceProps {
|
|
11
|
+
/** Fill color, fading to fully transparent along the bottom edge. */
|
|
12
|
+
color: string;
|
|
13
|
+
/** Opacity style for variants that fade the whole surface in as they collapse. */
|
|
14
|
+
animatedStyle?: HeaderOpacityStyle;
|
|
15
|
+
/**
|
|
16
|
+
* Height of the bottom gradient in dp. The region above it uses a solid fill.
|
|
17
|
+
* @defaultValue The themed bar height plus `HEADER_FADE_EXTENT`.
|
|
18
|
+
*/
|
|
19
|
+
fadeHeight?: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Header background with a solid fill and a bottom gradient.
|
|
24
|
+
* A fixed gradient height keeps tall accessories from becoming translucent.
|
|
25
|
+
*/
|
|
26
|
+
export function HeaderSurface({ color, animatedStyle, fadeHeight }: HeaderSurfaceProps) {
|
|
27
|
+
return (
|
|
28
|
+
<Animated.View style={[styles.surface, animatedStyle]} pointerEvents="none">
|
|
29
|
+
<View style={styles.fill(color, fadeHeight)} />
|
|
30
|
+
<View style={styles.fade(fadeHeight)}>
|
|
31
|
+
<HeaderGradientOverlay color={color} />
|
|
32
|
+
</View>
|
|
33
|
+
</Animated.View>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const styles = StyleSheet.create((theme) => ({
|
|
38
|
+
// Extend the fade below the header's layout bounds.
|
|
39
|
+
surface: {
|
|
40
|
+
position: "absolute",
|
|
41
|
+
top: 0,
|
|
42
|
+
left: 0,
|
|
43
|
+
right: 0,
|
|
44
|
+
bottom: -HEADER_FADE_EXTENT,
|
|
45
|
+
},
|
|
46
|
+
// Fill the region above the gradient.
|
|
47
|
+
fill: (color: string, fadeHeight: number | undefined) => ({
|
|
48
|
+
position: "absolute",
|
|
49
|
+
top: 0,
|
|
50
|
+
left: 0,
|
|
51
|
+
right: 0,
|
|
52
|
+
bottom: fadeHeight ?? theme.layout.header.height + HEADER_FADE_EXTENT,
|
|
53
|
+
backgroundColor: color,
|
|
54
|
+
}),
|
|
55
|
+
fade: (fadeHeight: number | undefined) => ({
|
|
56
|
+
position: "absolute",
|
|
57
|
+
left: 0,
|
|
58
|
+
right: 0,
|
|
59
|
+
bottom: 0,
|
|
60
|
+
height: fadeHeight ?? theme.layout.header.height + HEADER_FADE_EXTENT,
|
|
61
|
+
}),
|
|
62
|
+
}));
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Horizontal padding around a header accessory.
|
|
3
|
+
* - `'x'`: match the header bar's horizontal padding.
|
|
4
|
+
* - `'none'`: extend to the screen edges, for example for a scrollable tab strip.
|
|
5
|
+
*/
|
|
6
|
+
export type HeaderAccessoryPadding = "x" | "none";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Accessory placement while a large-title header scrolls.
|
|
10
|
+
* - `'pinned'`: remain directly below the compact bar.
|
|
11
|
+
* - `'sticky'`: scroll with the large title, then pin below the compact bar.
|
|
12
|
+
*
|
|
13
|
+
* Used by `Header.LargeTitle`. A hidden large title always uses pinned placement.
|
|
14
|
+
*/
|
|
15
|
+
export type HeaderAccessoryBehavior = "pinned" | "sticky";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { Text, View } from "react-native";
|
|
1
|
+
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { type LayoutChangeEvent, Text, View } from "react-native";
|
|
3
3
|
|
|
4
4
|
import Animated, { interpolate, useAnimatedStyle, useSharedValue } from "react-native-reanimated";
|
|
5
5
|
import { StyleSheet, useUnistyles } from "react-native-unistyles";
|
|
@@ -11,7 +11,10 @@ import { useHeaderBackground } from "../../../screen/parts/ScreenHeaderAppearanc
|
|
|
11
11
|
import { SCREEN_HEADER_PORTAL_HOST, useScreen } from "../../../screen/ScreenContext";
|
|
12
12
|
import { Toolbar } from "../../../toolbar";
|
|
13
13
|
import { HeaderDismissButton } from "../../header-buttons";
|
|
14
|
-
import {
|
|
14
|
+
import { HeaderAccessory, HeaderAccessorySpacer } from "../../parts/HeaderAccessory";
|
|
15
|
+
import { HEADER_FADE_EXTENT } from "../../parts/HeaderGradientOverlay";
|
|
16
|
+
import { HeaderSurface } from "../../parts/HeaderSurface";
|
|
17
|
+
import type { HeaderAccessoryBehavior } from "../../types";
|
|
15
18
|
import { isCustomTitle, isTextTitle } from "../../utils";
|
|
16
19
|
import type { TitleHeaderProps } from "../TitleHeader";
|
|
17
20
|
|
|
@@ -29,6 +32,12 @@ export interface LargeTitleHeaderProps extends TitleHeaderProps {
|
|
|
29
32
|
subtitle?: string;
|
|
30
33
|
/** Hide the large title (keeps the compact bar). Defaults to `false`. */
|
|
31
34
|
isLargeTitleHidden?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* How `accessory` moves while scrolling. `'sticky'` starts below the large title
|
|
37
|
+
* and pins below the compact bar when scrolled up. A hidden large title always pins.
|
|
38
|
+
* @defaultValue 'pinned'
|
|
39
|
+
*/
|
|
40
|
+
accessoryBehavior?: HeaderAccessoryBehavior;
|
|
32
41
|
/**
|
|
33
42
|
* Placement of the compact bar title. The large title stack always stays
|
|
34
43
|
* left-aligned. Defaults to `'center'`.
|
|
@@ -40,7 +49,11 @@ function LargeTitlePortalContent({
|
|
|
40
49
|
title,
|
|
41
50
|
overline,
|
|
42
51
|
subtitle,
|
|
43
|
-
|
|
52
|
+
onHeightChange,
|
|
53
|
+
}: Pick<LargeTitleHeaderProps, "title" | "overline" | "subtitle"> & {
|
|
54
|
+
/** Reports the large-title block's layout height in dp. */
|
|
55
|
+
onHeightChange?: (height: number) => void;
|
|
56
|
+
}) {
|
|
44
57
|
const { theme } = useUnistyles();
|
|
45
58
|
const { scrollY } = useScreen();
|
|
46
59
|
|
|
@@ -62,8 +75,11 @@ function LargeTitlePortalContent({
|
|
|
62
75
|
};
|
|
63
76
|
});
|
|
64
77
|
|
|
78
|
+
// Layout height excludes the collapse transform.
|
|
79
|
+
const handleLayout = (event: LayoutChangeEvent) => onHeightChange?.(event.nativeEvent.layout.height);
|
|
80
|
+
|
|
65
81
|
return (
|
|
66
|
-
<Animated.View style={[styles.portalContent, largeTitleAnimatedStyle]}>
|
|
82
|
+
<Animated.View style={[styles.portalContent, largeTitleAnimatedStyle]} onLayout={handleLayout}>
|
|
67
83
|
{!!overline && (
|
|
68
84
|
<Text
|
|
69
85
|
style={styles.overline}
|
|
@@ -123,6 +139,9 @@ export function LargeTitleHeader({
|
|
|
123
139
|
trailingActions,
|
|
124
140
|
LeftToolbar,
|
|
125
141
|
RightToolbar,
|
|
142
|
+
accessory,
|
|
143
|
+
accessoryPadding = "x",
|
|
144
|
+
accessoryBehavior = "pinned",
|
|
126
145
|
dismissAction = "none",
|
|
127
146
|
navigation,
|
|
128
147
|
onDismiss,
|
|
@@ -133,7 +152,7 @@ export function LargeTitleHeader({
|
|
|
133
152
|
}: LargeTitleHeaderProps) {
|
|
134
153
|
const { theme } = useUnistyles();
|
|
135
154
|
|
|
136
|
-
const { scrollY, background: screenBackground } = useScreen();
|
|
155
|
+
const { scrollY, background: screenBackground, setHeaderAccessoryHeight, contentTopPadding } = useScreen();
|
|
137
156
|
const colorToken = background ?? bg;
|
|
138
157
|
const bgColor =
|
|
139
158
|
(colorToken ? resolveThemeColor(colorToken, theme) : screenBackground) ?? theme.color["surface.canvas"];
|
|
@@ -141,7 +160,39 @@ export function LargeTitleHeader({
|
|
|
141
160
|
const trailingContent = trailingActions !== undefined ? trailingActions : RightToolbar;
|
|
142
161
|
|
|
143
162
|
const gradientColor = bgColor;
|
|
163
|
+
const isSticky = accessoryBehavior === "sticky" && !isLargeTitleHidden;
|
|
164
|
+
// Sticky accessories reserve space below the large title; pinned ones add top padding.
|
|
165
|
+
const [stickyAccessoryHeight, setStickyAccessoryHeight] = useState(0);
|
|
166
|
+
const [largeTitleHeight, setLargeTitleHeight] = useState(0);
|
|
144
167
|
const isLargeTitleHiddenValue = useSharedValue(isLargeTitleHidden);
|
|
168
|
+
|
|
169
|
+
const handleAccessoryHeightChange = useCallback(
|
|
170
|
+
(height: number) => {
|
|
171
|
+
if (isSticky) setStickyAccessoryHeight(Math.max(0, Math.round(height)));
|
|
172
|
+
else setHeaderAccessoryHeight(height);
|
|
173
|
+
},
|
|
174
|
+
[isSticky, setHeaderAccessoryHeight]
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
const handleLargeTitleHeightChange = useCallback((height: number) => {
|
|
178
|
+
setLargeTitleHeight(Math.max(0, Math.round(height)));
|
|
179
|
+
}, []);
|
|
180
|
+
|
|
181
|
+
// Rest below the title, including the scroll container's top padding.
|
|
182
|
+
const stickyAccessoryOffset = Math.max(
|
|
183
|
+
0,
|
|
184
|
+
contentTopPadding + largeTitleHeight - theme.layout.header.height
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
// Zero translation places the accessory directly below the compact bar.
|
|
188
|
+
const stickyAccessoryStyle = useAnimatedStyle(() => {
|
|
189
|
+
if (isLargeTitleHiddenValue.value) {
|
|
190
|
+
return { transform: [{ translateY: 0 }] };
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
transform: [{ translateY: Math.max(0, stickyAccessoryOffset - scrollY.value) }],
|
|
194
|
+
};
|
|
195
|
+
});
|
|
145
196
|
const headerCollapseHeight = theme.layout.header.height;
|
|
146
197
|
styles.useVariants({ titleAlignment });
|
|
147
198
|
|
|
@@ -209,56 +260,77 @@ export function LargeTitleHeader({
|
|
|
209
260
|
);
|
|
210
261
|
|
|
211
262
|
return (
|
|
212
|
-
|
|
263
|
+
// Let touches in the expanded header's empty space reach the scroll content.
|
|
264
|
+
<View style={styles.container(isSticky ? stickyAccessoryOffset : 0)} pointerEvents="box-none">
|
|
213
265
|
{!isLargeTitleHidden && (
|
|
214
266
|
<Portal hostName={SCREEN_HEADER_PORTAL_HOST}>
|
|
215
|
-
<LargeTitlePortalContent
|
|
267
|
+
<LargeTitlePortalContent
|
|
268
|
+
title={title}
|
|
269
|
+
overline={overline}
|
|
270
|
+
subtitle={subtitle}
|
|
271
|
+
onHeightChange={isSticky ? handleLargeTitleHeightChange : undefined}
|
|
272
|
+
/>
|
|
273
|
+
{/* Reserve space for the accessory rendered in the overlay. */}
|
|
274
|
+
{isSticky && accessory != null && <HeaderAccessorySpacer height={stickyAccessoryHeight} />}
|
|
216
275
|
</Portal>
|
|
217
276
|
)}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
277
|
+
{/* Share a background between the bar and a pinned accessory. */}
|
|
278
|
+
<View style={styles.barGroup}>
|
|
279
|
+
<HeaderSurface color={gradientColor} animatedStyle={gradientOpacityStyle} />
|
|
280
|
+
<View style={styles.bar}>
|
|
281
|
+
{leading != null && <Toolbar>{leading}</Toolbar>}
|
|
282
|
+
{/* Text can never be the touch target, but custom content may be, so its
|
|
283
|
+
container passes touches through to it instead of swallowing them. */}
|
|
284
|
+
<Animated.View
|
|
285
|
+
style={[styles.titleContainer, compactTitleAnimatedStyle]}
|
|
286
|
+
pointerEvents={isCustomTitle(title) ? "box-none" : "none"}
|
|
287
|
+
>
|
|
288
|
+
{isTextTitle(title) ? (
|
|
289
|
+
<AnimatedText
|
|
290
|
+
style={styles.compactTitle}
|
|
291
|
+
maxFontSizeMultiplier={theme.typography.variants["title-md"].maxFontSizeMultiplier}
|
|
292
|
+
>
|
|
293
|
+
{title}
|
|
294
|
+
</AnimatedText>
|
|
295
|
+
) : (
|
|
296
|
+
title
|
|
297
|
+
)}
|
|
298
|
+
</Animated.View>
|
|
299
|
+
{trailing != null && <Toolbar style={styles.trailing}>{trailing}</Toolbar>}
|
|
300
|
+
</View>
|
|
301
|
+
{accessory != null && !isSticky && (
|
|
302
|
+
<HeaderAccessory padding={accessoryPadding} onHeightChange={handleAccessoryHeightChange}>
|
|
303
|
+
{accessory}
|
|
304
|
+
</HeaderAccessory>
|
|
305
|
+
)}
|
|
241
306
|
</View>
|
|
307
|
+
{accessory != null && isSticky && (
|
|
308
|
+
// The background moves with the sticky accessory.
|
|
309
|
+
<Animated.View style={[styles.stickyAccessory, stickyAccessoryStyle]}>
|
|
310
|
+
<HeaderSurface color={gradientColor} fadeHeight={HEADER_FADE_EXTENT} />
|
|
311
|
+
<HeaderAccessory padding={accessoryPadding} onHeightChange={handleAccessoryHeightChange}>
|
|
312
|
+
{accessory}
|
|
313
|
+
</HeaderAccessory>
|
|
314
|
+
</Animated.View>
|
|
315
|
+
)}
|
|
242
316
|
</View>
|
|
243
317
|
);
|
|
244
318
|
}
|
|
245
319
|
|
|
246
320
|
const styles = StyleSheet.create((theme) => ({
|
|
247
|
-
|
|
321
|
+
// Include the translated accessory in the parent's touchable bounds.
|
|
322
|
+
container: (accessoryOffset: number) => ({
|
|
248
323
|
position: "absolute",
|
|
249
324
|
top: 0,
|
|
250
325
|
left: 0,
|
|
251
326
|
right: 0,
|
|
252
327
|
zIndex: 1000,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
right: 0,
|
|
260
|
-
bottom: -HEADER_FADE_EXTENT,
|
|
261
|
-
},
|
|
328
|
+
paddingBottom: accessoryOffset,
|
|
329
|
+
}),
|
|
330
|
+
// Normal flow places the accessory directly below the bar.
|
|
331
|
+
stickyAccessory: { position: "relative" },
|
|
332
|
+
// Anchors the absolutely positioned surface over the bar and the accessory both.
|
|
333
|
+
barGroup: { position: "relative" },
|
|
262
334
|
bar: {
|
|
263
335
|
height: theme.layout.header.height,
|
|
264
336
|
flexDirection: "row",
|
|
@@ -282,7 +354,7 @@ const styles = StyleSheet.create((theme) => ({
|
|
|
282
354
|
portalContent: {
|
|
283
355
|
gap: 2,
|
|
284
356
|
minHeight: theme.layout.header.height,
|
|
285
|
-
paddingBottom: theme.spacing["
|
|
357
|
+
paddingBottom: theme.spacing["1"],
|
|
286
358
|
paddingHorizontal: theme.layout.screen.padding.x,
|
|
287
359
|
},
|
|
288
360
|
overline: {
|