@tastic/hud 0.1.0 → 0.1.1
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.
|
@@ -100,7 +100,15 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
100
100
|
return path;
|
|
101
101
|
}, [segments, litIndicesKey, transitionFromKey, singleSelect, step, startDeg, dashAngleDeg, totalDurationMs, oval.x, oval.y, oval.width, oval.height]);
|
|
102
102
|
if (segments < 2) return null;
|
|
103
|
-
|
|
103
|
+
const gaugeSizeStyle = {
|
|
104
|
+
height: size,
|
|
105
|
+
width: size
|
|
106
|
+
};
|
|
107
|
+
const canvasSizeStyle = {
|
|
108
|
+
height: canvasSize,
|
|
109
|
+
width: canvasSize
|
|
110
|
+
};
|
|
111
|
+
return /* @__PURE__ */ jsx(View, { style: [styles.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ jsxs(Canvas, { style: canvasSizeStyle, children: [
|
|
104
112
|
/* @__PURE__ */ jsx(Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
|
|
105
113
|
/* @__PURE__ */ jsx(Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
|
|
106
114
|
] }) });
|
package/dist/index.js
CHANGED
|
@@ -122,7 +122,15 @@ function TriggerGauge({ segments, litIndices, size, accentColor, mutedColor, das
|
|
|
122
122
|
return path;
|
|
123
123
|
}, [segments, litIndicesKey, transitionFromKey, singleSelect, step, startDeg, dashAngleDeg, totalDurationMs, oval.x, oval.y, oval.width, oval.height]);
|
|
124
124
|
if (segments < 2) return null;
|
|
125
|
-
|
|
125
|
+
const gaugeSizeStyle = {
|
|
126
|
+
height: size,
|
|
127
|
+
width: size
|
|
128
|
+
};
|
|
129
|
+
const canvasSizeStyle = {
|
|
130
|
+
height: canvasSize,
|
|
131
|
+
width: canvasSize
|
|
132
|
+
};
|
|
133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native8.View, { style: [styles4.container, gaugeSizeStyle], pointerEvents: "none", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_native_skia.Canvas, { style: canvasSizeStyle, children: [
|
|
126
134
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native_skia.Path, { path: unlitPath, style: "stroke", strokeWidth: UNLIT_THICKNESS, strokeCap: "round", color: mutedColor, opacity: 0.35 }),
|
|
127
135
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native_skia.Path, { path: litPath, style: "stroke", strokeWidth: LIT_THICKNESS, strokeCap: "round", color: accentColor, opacity: 1 })
|
|
128
136
|
] }) });
|
|
@@ -418,7 +426,10 @@ var import_react_native7 = require("react-native");
|
|
|
418
426
|
var import_react_native_paper2 = require("react-native-paper");
|
|
419
427
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
420
428
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
421
|
-
|
|
429
|
+
const readyButtonStyle = [styles3.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
430
|
+
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
431
|
+
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
432
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_feedback_press2.TouchableRipple, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_native_paper2.Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
422
433
|
}
|
|
423
434
|
var styles3 = import_react_native7.StyleSheet.create({
|
|
424
435
|
readyButton: {
|
|
@@ -493,13 +504,16 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
493
504
|
}
|
|
494
505
|
gaugeOffset += section.options.length;
|
|
495
506
|
}
|
|
496
|
-
|
|
507
|
+
const anchorStyle = [styles5.anchor, open && styles5.anchorOpen];
|
|
508
|
+
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
509
|
+
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: anchorStyle, children: [
|
|
497
511
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { ref: triggerRef, collapsable: false, style: styles5.triggerBox, children: [
|
|
498
512
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
499
513
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
500
514
|
] }),
|
|
501
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.ScrollView, { style: [styles5.menu,
|
|
502
|
-
sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, { style: [styles5.divider,
|
|
515
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.ScrollView, { style: [styles5.menu, menuStyle], contentContainerStyle: styles5.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { children: [
|
|
516
|
+
sectionIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, { style: [styles5.divider, dividerStyle] }),
|
|
503
517
|
section.kind === "single" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
504
518
|
SingleSection,
|
|
505
519
|
{
|
|
@@ -528,11 +542,14 @@ function SingleSection({
|
|
|
528
542
|
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_jsx_runtime7.Fragment, { children: section.options.map((option) => {
|
|
529
543
|
const selected = option.value === section.value;
|
|
530
544
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
531
|
-
|
|
545
|
+
const itemStyle = [styles5.item, selected && { backgroundColor: accentColor }];
|
|
546
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
547
|
+
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
548
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: styles5.itemRow, children: [
|
|
532
549
|
option.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
533
550
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: styles5.itemLabelColumn, children: [
|
|
534
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style:
|
|
535
|
-
option.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelSmall", style:
|
|
551
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
552
|
+
option.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
536
553
|
] })
|
|
537
554
|
] }) }, option.value);
|
|
538
555
|
}) });
|
|
@@ -552,9 +569,11 @@ function MultiSection({
|
|
|
552
569
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
553
570
|
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
554
571
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
555
|
-
|
|
572
|
+
const itemStyle = [styles5.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
573
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_native9.View, { style: styles5.itemRow, children: [
|
|
556
575
|
option.icon && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Icon, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
557
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: [styles5.itemLabelFlex,
|
|
576
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: [styles5.itemLabelFlex, labelStyle], children: option.label })
|
|
558
577
|
] }) }, option.value);
|
|
559
578
|
}),
|
|
560
579
|
section.allClear && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_feedback_press3.TouchableRipple, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles5.item, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_paper3.Text, { variant: "labelLarge", style: [styles5.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
package/dist/index.mjs
CHANGED
|
@@ -245,7 +245,10 @@ import { StyleSheet as StyleSheet4 } from "react-native";
|
|
|
245
245
|
import { Text } from "react-native-paper";
|
|
246
246
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
247
247
|
function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }) {
|
|
248
|
-
|
|
248
|
+
const readyButtonStyle = [styles3.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style];
|
|
249
|
+
const labelTextStyle = { fontFamily: labelFontFamily, fontWeight: "bold" };
|
|
250
|
+
const labelColorStyle = { color: ready ? "#000000" : color };
|
|
251
|
+
return /* @__PURE__ */ jsx4(TouchableRipple2, { onPress: onToggleReady, borderless: true, style: readyButtonStyle, children: /* @__PURE__ */ jsx4(Text, { variant: "labelLarge", style: [labelTextStyle, labelColorStyle], children: ready ? "READY \u2713" : "READY?" }) });
|
|
249
252
|
}
|
|
250
253
|
var styles3 = StyleSheet4.create({
|
|
251
254
|
readyButton: {
|
|
@@ -268,7 +271,7 @@ import { Icon as Icon2, Text as Text2 } from "react-native-paper";
|
|
|
268
271
|
// src/TriggerGaugeHost.tsx
|
|
269
272
|
import { lazy, Suspense } from "react";
|
|
270
273
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
271
|
-
var LazyTriggerGauge = lazy(() => loadSkiaWeb().then(() => import("./TriggerGauge-
|
|
274
|
+
var LazyTriggerGauge = lazy(() => loadSkiaWeb().then(() => import("./TriggerGauge-XBKZ3KER.mjs").then((m) => ({ default: m.TriggerGauge }))));
|
|
272
275
|
function TriggerGaugeHost(props) {
|
|
273
276
|
return /* @__PURE__ */ jsx5(Suspense, { fallback: null, children: /* @__PURE__ */ jsx5(LazyTriggerGauge, { ...props }) });
|
|
274
277
|
}
|
|
@@ -320,13 +323,16 @@ function SectionedDropdown({ id, host, icon, accessibilityLabel, sections, accen
|
|
|
320
323
|
}
|
|
321
324
|
gaugeOffset += section.options.length;
|
|
322
325
|
}
|
|
323
|
-
|
|
326
|
+
const anchorStyle = [styles4.anchor, open && styles4.anchorOpen];
|
|
327
|
+
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight };
|
|
328
|
+
const dividerStyle = { backgroundColor: menuBorderColor };
|
|
329
|
+
return /* @__PURE__ */ jsxs3(View4, { style: anchorStyle, children: [
|
|
324
330
|
/* @__PURE__ */ jsxs3(View4, { ref: triggerRef, collapsable: false, style: styles4.triggerBox, children: [
|
|
325
331
|
/* @__PURE__ */ jsx6(TriggerGaugeHost, { segments: gaugeSegments, litIndices: gaugeLitIndices, size: TRIGGER_SIZE, accentColor, mutedColor }),
|
|
326
332
|
/* @__PURE__ */ jsx6(IconButton, { icon: triggerIcon, iconColor: triggerIconColor, size: triggerIconSize, accessibilityLabel, onPress: () => host.toggle(id) })
|
|
327
333
|
] }),
|
|
328
|
-
/* @__PURE__ */ jsx6(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx6(ScrollView2, { style: [styles4.menu,
|
|
329
|
-
sectionIndex > 0 && /* @__PURE__ */ jsx6(View4, { style: [styles4.divider,
|
|
334
|
+
/* @__PURE__ */ jsx6(PopoverBody, { visible: open && measured, align, verticalAlign, caretColor: menuBg, caretBorderColor: menuBorderColor, caretBorderWidth: MENU_BORDER_WIDTH, triggerSize: TRIGGER_SIZE, children: /* @__PURE__ */ jsx6(ScrollView2, { style: [styles4.menu, menuStyle], contentContainerStyle: styles4.menuContent, showsVerticalScrollIndicator: false, children: sections.map((section, sectionIndex) => /* @__PURE__ */ jsxs3(View4, { children: [
|
|
335
|
+
sectionIndex > 0 && /* @__PURE__ */ jsx6(View4, { style: [styles4.divider, dividerStyle] }),
|
|
330
336
|
section.kind === "single" ? /* @__PURE__ */ jsx6(
|
|
331
337
|
SingleSection,
|
|
332
338
|
{
|
|
@@ -355,11 +361,14 @@ function SingleSection({
|
|
|
355
361
|
return /* @__PURE__ */ jsx6(Fragment2, { children: section.options.map((option) => {
|
|
356
362
|
const selected = option.value === section.value;
|
|
357
363
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
358
|
-
|
|
364
|
+
const itemStyle = [styles4.item, selected && { backgroundColor: accentColor }];
|
|
365
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
366
|
+
const descriptionStyle = { fontFamily: labelFontFamily, color: rowColor };
|
|
367
|
+
return /* @__PURE__ */ jsx6(TouchableRipple3, { onPress: () => onSelect(option.value), style: itemStyle, children: /* @__PURE__ */ jsxs3(View4, { style: styles4.itemRow, children: [
|
|
359
368
|
option.icon && /* @__PURE__ */ jsx6(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
360
369
|
/* @__PURE__ */ jsxs3(View4, { style: styles4.itemLabelColumn, children: [
|
|
361
|
-
/* @__PURE__ */ jsx6(Text2, { variant: "labelLarge", style:
|
|
362
|
-
option.description && /* @__PURE__ */ jsx6(Text2, { variant: "labelSmall", style:
|
|
370
|
+
/* @__PURE__ */ jsx6(Text2, { variant: "labelLarge", style: labelStyle, children: option.label }),
|
|
371
|
+
option.description && /* @__PURE__ */ jsx6(Text2, { variant: "labelSmall", style: descriptionStyle, children: option.description })
|
|
363
372
|
] })
|
|
364
373
|
] }) }, option.value);
|
|
365
374
|
}) });
|
|
@@ -379,9 +388,11 @@ function MultiSection({
|
|
|
379
388
|
const rowColor = selected ? onAccentColor : mutedColor;
|
|
380
389
|
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value);
|
|
381
390
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value);
|
|
382
|
-
|
|
391
|
+
const itemStyle = [styles4.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }];
|
|
392
|
+
const labelStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? "bold" : "normal" };
|
|
393
|
+
return /* @__PURE__ */ jsx6(TouchableRipple3, { onPress: () => section.onChange(selected ? section.value.filter((v) => v !== option.value) : [...section.value, option.value]), style: itemStyle, children: /* @__PURE__ */ jsxs3(View4, { style: styles4.itemRow, children: [
|
|
383
394
|
option.icon && /* @__PURE__ */ jsx6(Icon2, { source: option.icon, size: MENU_ITEM_ICON_SIZE, color: rowColor }),
|
|
384
|
-
/* @__PURE__ */ jsx6(Text2, { variant: "labelLarge", style: [styles4.itemLabelFlex,
|
|
395
|
+
/* @__PURE__ */ jsx6(Text2, { variant: "labelLarge", style: [styles4.itemLabelFlex, labelStyle], children: option.label })
|
|
385
396
|
] }) }, option.value);
|
|
386
397
|
}),
|
|
387
398
|
section.allClear && /* @__PURE__ */ jsx6(TouchableRipple3, { onPress: () => section.onChange(allSelected ? [] : section.options.map((o) => o.value)), style: styles4.item, children: /* @__PURE__ */ jsx6(Text2, { variant: "labelLarge", style: [styles4.allClearLabel, { fontFamily: labelFontFamily, color: accentColor }], children: allSelected ? allClearLabels.clear : allClearLabels.all }) })
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tastic/hud",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Visual component kit for local-multiplayer React Native games: inline (non-modal) popovers, dropdowns, color pickers, gauges, ready buttons, and dialogs, built to stay scoped to one player's own zone on a shared screen",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
package/src/ReadyButton.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TouchableRipple } from '@rific/feedback-press'
|
|
2
|
-
import { StyleProp, StyleSheet, ViewStyle } from 'react-native'
|
|
2
|
+
import { StyleProp, StyleSheet, TextStyle, ViewStyle } from 'react-native'
|
|
3
3
|
import { Text } from 'react-native-paper'
|
|
4
4
|
|
|
5
5
|
import { MONO_FONT } from './fonts'
|
|
@@ -21,9 +21,13 @@ interface Props {
|
|
|
21
21
|
// below a shared row — e.g. a vs-CPU mode with only one human player needs just one Ready toggle,
|
|
22
22
|
// not one tucked under each slot.
|
|
23
23
|
export function ReadyButton({ color, ready, onToggleReady, style, labelFontFamily = MONO_FONT }: Props) {
|
|
24
|
+
const readyButtonStyle = [styles.readyButton, { borderColor: color }, ready && { backgroundColor: color }, style]
|
|
25
|
+
const labelTextStyle: TextStyle = { fontFamily: labelFontFamily, fontWeight: 'bold' }
|
|
26
|
+
const labelColorStyle = { color: ready ? '#000000' : color }
|
|
27
|
+
|
|
24
28
|
return (
|
|
25
|
-
<TouchableRipple onPress={onToggleReady} borderless style={
|
|
26
|
-
<Text variant='labelLarge' style={[
|
|
29
|
+
<TouchableRipple onPress={onToggleReady} borderless style={readyButtonStyle}>
|
|
30
|
+
<Text variant='labelLarge' style={[labelTextStyle, labelColorStyle]}>
|
|
27
31
|
{ready ? 'READY ✓' : 'READY?'}
|
|
28
32
|
</Text>
|
|
29
33
|
</TouchableRipple>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getBlendedColor, getColorRoles } from '@rific/auto-paper'
|
|
2
2
|
import { IconButton, TouchableRipple } from '@rific/feedback-press'
|
|
3
|
-
import { ScrollView, StyleSheet, View } from 'react-native'
|
|
3
|
+
import { ScrollView, StyleSheet, TextStyle, View } from 'react-native'
|
|
4
4
|
import { Icon, Text } from 'react-native-paper'
|
|
5
5
|
|
|
6
6
|
import { MONO_FONT } from './fonts'
|
|
@@ -177,8 +177,12 @@ export function SectionedDropdown({ id, host, icon, accessibilityLabel, sections
|
|
|
177
177
|
gaugeOffset += section.options.length
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
const anchorStyle = [styles.anchor, open && styles.anchorOpen]
|
|
181
|
+
const menuStyle = { backgroundColor: menuBg, borderColor: menuBorderColor, maxHeight }
|
|
182
|
+
const dividerStyle = { backgroundColor: menuBorderColor }
|
|
183
|
+
|
|
180
184
|
return (
|
|
181
|
-
<View style={
|
|
185
|
+
<View style={anchorStyle}>
|
|
182
186
|
<View ref={triggerRef} collapsable={false} style={styles.triggerBox}>
|
|
183
187
|
<TriggerGaugeHost segments={gaugeSegments} litIndices={gaugeLitIndices} size={TRIGGER_SIZE} accentColor={accentColor} mutedColor={mutedColor} />
|
|
184
188
|
<IconButton icon={triggerIcon} iconColor={triggerIconColor} size={triggerIconSize} accessibilityLabel={accessibilityLabel} onPress={() => host.toggle(id)} />
|
|
@@ -194,13 +198,13 @@ export function SectionedDropdown({ id, host, icon, accessibilityLabel, sections
|
|
|
194
198
|
is always <= maxHeight then, so nothing scrolls); on a short landscape screen where neither
|
|
195
199
|
direction has enough room, this is what keeps the menu from just running off the screen
|
|
196
200
|
edge instead of flipping only made it run off a *smaller* amount. */}
|
|
197
|
-
<ScrollView style={[styles.menu,
|
|
201
|
+
<ScrollView style={[styles.menu, menuStyle]} contentContainerStyle={styles.menuContent} showsVerticalScrollIndicator={false}>
|
|
198
202
|
{sections.map((section, sectionIndex) => (
|
|
199
203
|
<View key={section.id}>
|
|
200
204
|
{/* Every section after the first gets a rule above it — the divider belongs to the
|
|
201
205
|
boundary between sections, not to either section itself, so it's keyed off position
|
|
202
206
|
rather than each section carrying its own "divider below me" flag. */}
|
|
203
|
-
{sectionIndex > 0 && <View style={[styles.divider,
|
|
207
|
+
{sectionIndex > 0 && <View style={[styles.divider, dividerStyle]} />}
|
|
204
208
|
|
|
205
209
|
{section.kind === 'single' ? (
|
|
206
210
|
<SingleSection
|
|
@@ -247,16 +251,19 @@ function SingleSection({
|
|
|
247
251
|
{section.options.map((option) => {
|
|
248
252
|
const selected = option.value === section.value
|
|
249
253
|
const rowColor = selected ? onAccentColor : mutedColor
|
|
254
|
+
const itemStyle = [styles.item, selected && { backgroundColor: accentColor }]
|
|
255
|
+
const labelStyle: TextStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? 'bold' : 'normal' }
|
|
256
|
+
const descriptionStyle: TextStyle = { fontFamily: labelFontFamily, color: rowColor }
|
|
250
257
|
return (
|
|
251
|
-
<TouchableRipple key={option.value} onPress={() => onSelect(option.value)} style={
|
|
258
|
+
<TouchableRipple key={option.value} onPress={() => onSelect(option.value)} style={itemStyle}>
|
|
252
259
|
<View style={styles.itemRow}>
|
|
253
260
|
{option.icon && <Icon source={option.icon} size={MENU_ITEM_ICON_SIZE} color={rowColor} />}
|
|
254
261
|
<View style={styles.itemLabelColumn}>
|
|
255
|
-
<Text variant='labelLarge' style={
|
|
262
|
+
<Text variant='labelLarge' style={labelStyle}>
|
|
256
263
|
{option.label}
|
|
257
264
|
</Text>
|
|
258
265
|
{option.description && (
|
|
259
|
-
<Text variant='labelSmall' style={
|
|
266
|
+
<Text variant='labelSmall' style={descriptionStyle}>
|
|
260
267
|
{option.description}
|
|
261
268
|
</Text>
|
|
262
269
|
)}
|
|
@@ -299,11 +306,13 @@ function MultiSection({
|
|
|
299
306
|
// separately-rounded pills.
|
|
300
307
|
const prevSelected = selected && i > 0 && section.value.includes(section.options[i - 1].value)
|
|
301
308
|
const nextSelected = selected && i < section.options.length - 1 && section.value.includes(section.options[i + 1].value)
|
|
309
|
+
const itemStyle = [styles.item, selected && { backgroundColor: accentColor }, prevSelected && { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, nextSelected && { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }]
|
|
310
|
+
const labelStyle: TextStyle = { fontFamily: labelFontFamily, color: rowColor, fontWeight: selected ? 'bold' : 'normal' }
|
|
302
311
|
return (
|
|
303
|
-
<TouchableRipple key={option.value} onPress={() => section.onChange(selected ? section.value.filter((v: unknown) => v !== option.value) : [...section.value, option.value])} style={
|
|
312
|
+
<TouchableRipple key={option.value} onPress={() => section.onChange(selected ? section.value.filter((v: unknown) => v !== option.value) : [...section.value, option.value])} style={itemStyle}>
|
|
304
313
|
<View style={styles.itemRow}>
|
|
305
314
|
{option.icon && <Icon source={option.icon} size={MENU_ITEM_ICON_SIZE} color={rowColor} />}
|
|
306
|
-
<Text variant='labelLarge' style={[styles.itemLabelFlex,
|
|
315
|
+
<Text variant='labelLarge' style={[styles.itemLabelFlex, labelStyle]}>
|
|
307
316
|
{option.label}
|
|
308
317
|
</Text>
|
|
309
318
|
</View>
|
package/src/TriggerGauge.tsx
CHANGED
|
@@ -266,9 +266,18 @@ export function TriggerGauge({ segments, litIndices, size, accentColor, mutedCol
|
|
|
266
266
|
|
|
267
267
|
if (segments < 2) return null
|
|
268
268
|
|
|
269
|
+
const gaugeSizeStyle = {
|
|
270
|
+
height: size,
|
|
271
|
+
width: size
|
|
272
|
+
}
|
|
273
|
+
const canvasSizeStyle = {
|
|
274
|
+
height: canvasSize,
|
|
275
|
+
width: canvasSize
|
|
276
|
+
}
|
|
277
|
+
|
|
269
278
|
return (
|
|
270
|
-
<View style={[styles.container,
|
|
271
|
-
<Canvas style={
|
|
279
|
+
<View style={[styles.container, gaugeSizeStyle]} pointerEvents='none'>
|
|
280
|
+
<Canvas style={canvasSizeStyle}>
|
|
272
281
|
<Path path={unlitPath} style='stroke' strokeWidth={UNLIT_THICKNESS} strokeCap='round' color={mutedColor} opacity={0.35} />
|
|
273
282
|
<Path path={litPath} style='stroke' strokeWidth={LIT_THICKNESS} strokeCap='round' color={accentColor} opacity={1} />
|
|
274
283
|
</Canvas>
|