@octane-xplat/ui 0.5.0 → 0.6.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/README.md +3 -0
- package/dist/native/Absolute.native.tsrx.js +43 -0
- package/dist/native/Accordion.native.tsrx.js +75 -0
- package/dist/native/ActivityIndicator.native.tsrx.js +35 -0
- package/dist/native/Alert.native.tsrx.js +74 -0
- package/dist/native/Avatar.native.tsrx.js +76 -0
- package/dist/native/AvatarGroup.native.tsrx.js +84 -0
- package/dist/native/Badge.native.tsrx.js +29 -0
- package/dist/native/Banner.native.tsrx.js +80 -0
- package/dist/native/Breadcrumb.native.tsrx.js +66 -0
- package/dist/native/Button.native.tsrx.js +62 -0
- package/dist/native/CameraView.native.tsrx.js +165 -0
- package/dist/native/Card.native.tsrx.js +64 -0
- package/dist/native/Checkbox.native.tsrx.js +58 -0
- package/dist/native/CheckboxGroup.native.tsrx.js +70 -0
- package/dist/native/Chip.native.tsrx.js +83 -0
- package/dist/native/Collapsible.native.tsrx.js +74 -0
- package/dist/native/CommandPalette.native.tsrx.js +143 -0
- package/dist/native/ContextMenu.native.tsrx.js +140 -0
- package/dist/native/Drawer.native.tsrx.js +60 -0
- package/dist/native/DropdownMenu.native.tsrx.js +155 -0
- package/dist/native/Empty.native.tsrx.js +82 -0
- package/dist/native/FieldGroup.native.tsrx.js +39 -0
- package/dist/native/FormField.native.tsrx.js +53 -0
- package/dist/native/{ui8.js → Grid.native.tsrx.js} +19 -8
- package/dist/native/{ui59.js → Heading.native.tsrx.js} +2 -2
- package/dist/native/{ui58.js → Icon.native.tsrx.js} +4 -4
- package/dist/native/{ui29.js → Image.native.tsrx.js} +4 -4
- package/dist/native/InputNumber.native.tsrx.js +146 -0
- package/dist/native/InputRating.native.tsrx.js +74 -0
- package/dist/native/InputTags.native.tsrx.js +131 -0
- package/dist/native/Kbd.native.tsrx.js +29 -0
- package/dist/native/{ui50.js → KeyboardAvoiding.native.tsrx.js} +1 -1
- package/dist/native/{ui17.js → Link.native.tsrx.js} +1 -1
- package/dist/native/{ui55.js → Meter.native.tsrx.js} +2 -2
- package/dist/native/{ui22.js → NavLink.native.tsrx.js} +3 -3
- package/dist/native/NavigationMenu.native.tsrx.js +67 -0
- package/dist/native/{ui35.js → Overlay.native.tsrx.js} +3 -3
- package/dist/native/Pager.native.tsrx.js +282 -0
- package/dist/native/Pagination.native.tsrx.js +107 -0
- package/dist/native/PinInput.native.tsrx.js +94 -0
- package/dist/native/{ui38.js → Popover.native.tsrx.js} +5 -5
- package/dist/native/{ui16.js → Pressable.native.tsrx.js} +20 -14
- package/dist/native/ProgressGroup.native.tsrx.js +66 -0
- package/dist/native/RadioGroup.native.tsrx.js +85 -0
- package/dist/native/{ui15.js → RichText.native.tsrx.js} +15 -22
- package/dist/native/Row.native.tsrx.js +98 -0
- package/dist/native/{ui49.js → SafeArea.native.tsrx.js} +2 -2
- package/dist/native/{ui45.js → Screen.native.tsrx.js} +3 -3
- package/dist/native/{ui26.js → ScrollBox.native.tsrx.js} +1 -1
- package/dist/native/ScrollView.native.tsrx.js +233 -0
- package/dist/native/SearchInput.native.tsrx.js +151 -0
- package/dist/native/SegmentedControl.native.tsrx.js +75 -0
- package/dist/native/Select.native.tsrx.js +202 -0
- package/dist/native/Separator.native.tsrx.js +25 -0
- package/dist/native/{ui63.js → Sheet.native.tsrx.js} +15 -7
- package/dist/native/Skeleton.native.tsrx.js +28 -0
- package/dist/native/Slider.native.tsrx.js +98 -0
- package/dist/native/{ui13.js → Spacer.native.tsrx.js} +2 -2
- package/dist/native/{ui9.js → Stack.native.tsrx.js} +20 -9
- package/dist/native/Stepper.native.tsrx.js +75 -0
- package/dist/native/Switch.native.tsrx.js +33 -0
- package/dist/native/Table.native.tsrx.js +103 -0
- package/dist/native/Tabs.native.tsrx.js +163 -0
- package/dist/native/{ui14.js → Text.native.tsrx.js} +4 -3
- package/dist/native/{ui24.js → TextArea.native.tsrx.js} +17 -16
- package/dist/native/{ui23.js → TextInput.native.tsrx.js} +21 -16
- package/dist/native/Timeline.native.tsrx.js +112 -0
- package/dist/native/Tree.native.tsrx.js +140 -0
- package/dist/native/User.native.tsrx.js +95 -0
- package/dist/native/Video.native.tsrx.js +248 -0
- package/dist/native/View.native.tsrx.js +98 -0
- package/dist/native/WebView.native.tsrx.js +110 -0
- package/dist/native/aliases.native.tsrx.js +38 -0
- package/dist/native/android/BottomNavigationView.android.tsrx.js +171 -0
- package/dist/native/android/CircularProgressIndicator.android.tsrx.js +27 -0
- package/dist/native/{ui51.js → android/DrawerLayout.android.tsrx.js} +5 -7
- package/dist/native/android/MaterialDialog.android.tsrx.js +62 -0
- package/dist/native/android/MaterialSwitch.android.tsrx.js +28 -0
- package/dist/native/android/RecyclerView.android.tsrx.js +248 -0
- package/dist/native/android/SeekBar.android.tsrx.js +34 -0
- package/dist/native/android/index.js +9 -0
- package/dist/native/android/openModal.android.js +39 -0
- package/dist/native/camera-permission.native.js +47 -0
- package/dist/native/child-array.js +15 -0
- package/dist/native/icons.js +25 -0
- package/dist/native/{ui11.js → ios/LiquidGlass.ios.tsrx.js} +4 -4
- package/dist/native/{ui12.js → ios/LiquidGlassContainer.ios.tsrx.js} +4 -4
- package/dist/native/ios/SideDrawer.ios.tsrx.js +64 -0
- package/dist/native/{ui53.js → ios/UIActivityIndicatorView.ios.tsrx.js} +5 -5
- package/dist/native/{ui32.js → ios/UIModal.ios.tsrx.js} +10 -6
- package/dist/native/{ui56.js → ios/UISlider.ios.tsrx.js} +5 -5
- package/dist/native/{ui47.js → ios/UISwitch.ios.tsrx.js} +5 -5
- package/dist/native/ios/UITabBar.ios.tsrx.js +166 -0
- package/dist/native/ios/UITableView.ios.tsrx.js +270 -0
- package/dist/native/ios/index.js +11 -0
- package/dist/native/{ui33.js → ios/openModal.ios.js} +5 -4
- package/dist/native/modal-presenter.native.js +19 -0
- package/dist/native/native/index.js +4 -0
- package/dist/native/octane-client-build.json +1 -1
- package/dist/native/{ui6.js → pan.native.tsrx.js} +9 -69
- package/dist/native/platform.native.js +10 -0
- package/dist/native/refresh-metrics.js +9 -0
- package/dist/native/refresh.native.js +177 -0
- package/dist/native/{ui34.js → root-layout.native.js} +6 -1
- package/dist/native/{ui21.js → route.native.js} +96 -12
- package/dist/native/sheet-detents.native.js +102 -0
- package/dist/native/{ui64.js → sheet-service.native.js} +19 -9
- package/dist/native/sheet-snap.js +35 -0
- package/dist/native/text-write.native.js +27 -0
- package/dist/native/{ui42.js → theme/status-bar-scheme.native.js} +2 -2
- package/dist/{web/ui29.js → native/theme/theme-scheme.js} +2 -2
- package/dist/native/{ui40.js → toast-anchor.native.tsrx.js} +3 -3
- package/dist/native/translate.native.js +11 -0
- package/dist/native/ui.js +93 -55
- package/dist/native/use-back.native.tsrx.js +9 -0
- package/dist/native/{ui52.js → useMeasure.native.tsrx.js} +1 -1
- package/dist/native/video-chrome.native.tsrx.js +365 -0
- package/dist/web/Absolute.web.tsrx.js +47 -0
- package/dist/web/Accordion.web.tsrx.js +85 -0
- package/dist/web/{ui48.js → ActivityIndicator.web.tsrx.js} +1 -1
- package/dist/web/Alert.web.tsrx.js +79 -0
- package/dist/web/Avatar.web.tsrx.js +106 -0
- package/dist/web/AvatarGroup.web.tsrx.js +108 -0
- package/dist/web/Badge.web.tsrx.js +37 -0
- package/dist/web/Banner.web.tsrx.js +79 -0
- package/dist/web/Breadcrumb.web.tsrx.js +135 -0
- package/dist/web/Button.web.tsrx.js +45 -0
- package/dist/web/CameraView.web.tsrx.js +310 -0
- package/dist/web/Card.web.tsrx.js +73 -0
- package/dist/web/Checkbox.web.tsrx.js +89 -0
- package/dist/web/CheckboxGroup.web.tsrx.js +79 -0
- package/dist/web/Chip.web.tsrx.js +64 -0
- package/dist/web/Collapsible.web.tsrx.js +94 -0
- package/dist/web/CommandPalette.web.tsrx.js +125 -0
- package/dist/web/ContextMenu.web.tsrx.js +154 -0
- package/dist/web/{ui45.js → Drawer.web.tsrx.js} +13 -9
- package/dist/web/DropdownMenu.web.tsrx.js +162 -0
- package/dist/web/Empty.web.tsrx.js +89 -0
- package/dist/web/FieldGroup.web.tsrx.js +57 -0
- package/dist/web/FormField.web.tsrx.js +92 -0
- package/dist/web/Grid.web.tsrx.js +65 -0
- package/dist/web/{ui54.js → Heading.web.tsrx.js} +2 -2
- package/dist/web/{ui53.js → Icon.web.tsrx.js} +2 -2
- package/dist/web/{ui25.js → Image.web.tsrx.js} +2 -2
- package/dist/web/InputNumber.web.tsrx.js +99 -0
- package/dist/web/InputRating.web.tsrx.js +72 -0
- package/dist/web/InputTags.web.tsrx.js +122 -0
- package/dist/web/Kbd.web.tsrx.js +37 -0
- package/dist/web/{ui50.js → Meter.web.tsrx.js} +1 -1
- package/dist/web/{ui19.js → NavLink.web.tsrx.js} +1 -1
- package/dist/web/NavigationMenu.web.tsrx.js +118 -0
- package/dist/web/{ui31.js → Overlay.web.tsrx.js} +2 -2
- package/dist/web/Pager.web.tsrx.js +337 -0
- package/dist/web/Pagination.web.tsrx.js +80 -0
- package/dist/web/PinInput.web.tsrx.js +72 -0
- package/dist/web/{ui33.js → Popover.web.tsrx.js} +3 -3
- package/dist/web/{ui15.js → Pressable.web.tsrx.js} +68 -95
- package/dist/web/ProgressGroup.web.tsrx.js +109 -0
- package/dist/web/RadioGroup.web.tsrx.js +69 -0
- package/dist/web/{ui14.js → RichText.web.tsrx.js} +2 -2
- package/dist/web/Row.web.tsrx.js +250 -0
- package/dist/web/{ui43.js → SafeArea.web.tsrx.js} +1 -1
- package/dist/web/{ui39.js → Screen.web.tsrx.js} +1 -1
- package/dist/web/{ui24.js → ScrollBox.web.tsrx.js} +1 -1
- package/dist/web/ScrollView.web.tsrx.js +388 -0
- package/dist/web/SearchInput.web.tsrx.js +137 -0
- package/dist/web/SegmentedControl.web.tsrx.js +75 -0
- package/dist/web/Select.web.tsrx.js +149 -0
- package/dist/web/Separator.web.tsrx.js +42 -0
- package/dist/web/Sheet.web.tsrx.js +81 -0
- package/dist/web/Skeleton.web.tsrx.js +56 -0
- package/dist/web/Slider.web.tsrx.js +97 -0
- package/dist/web/{ui12.js → Spacer.web.tsrx.js} +1 -1
- package/dist/web/Stack.web.tsrx.js +47 -0
- package/dist/web/Stepper.web.tsrx.js +65 -0
- package/dist/web/Switch.web.tsrx.js +59 -0
- package/dist/web/Table.web.tsrx.js +161 -0
- package/dist/web/{ui40.js → Tabs.web.tsrx.js} +33 -16
- package/dist/web/{ui13.js → Text.web.tsrx.js} +18 -50
- package/dist/web/{ui21.js → TextArea.web.tsrx.js} +4 -4
- package/dist/web/{ui20.js → TextInput.web.tsrx.js} +8 -8
- package/dist/web/Timeline.web.tsrx.js +172 -0
- package/dist/web/Tree.web.tsrx.js +146 -0
- package/dist/web/User.web.tsrx.js +116 -0
- package/dist/web/Video.web.tsrx.js +400 -0
- package/dist/web/View.web.tsrx.js +250 -0
- package/dist/web/WebView.web.tsrx.js +235 -0
- package/dist/web/aliases.web.tsrx.js +24 -0
- package/dist/web/{ui36.js → anim.web.tsrx.js} +3 -35
- package/dist/web/child-array.js +15 -0
- package/dist/web/icons.js +25 -0
- package/dist/web/octane-client-build.json +1 -1
- package/dist/web/pan.web.tsrx.js +66 -0
- package/dist/web/platform.web.js +9 -0
- package/dist/web/refresh-metrics.js +9 -0
- package/dist/web/refresh.web.js +133 -0
- package/dist/web/{ui18.js → route.web.js} +14 -2
- package/dist/web/sheet-detents.web.js +103 -0
- package/dist/web/{ui60.js → sheet-service.web.js} +5 -1
- package/dist/web/sheet-snap.js +35 -0
- package/dist/{native/ui31.js → web/theme/theme-scheme.js} +2 -2
- package/dist/web/{ui35.js → toast-anchor.web.tsrx.js} +3 -3
- package/dist/web/transform.web.js +43 -0
- package/dist/web/translate.web.js +13 -0
- package/dist/web/ui.js +91 -53
- package/dist/web/use-back.web.tsrx.js +9 -0
- package/dist/web/video-chrome.web.tsrx.js +207 -0
- package/dist/web/{ui34.js → web/Hoverable.web.tsrx.js} +6 -6
- package/dist/web/web/Tooltip.web.tsrx.js +183 -0
- package/dist/web/web/index.js +3 -0
- package/package.json +30 -3
- package/src/theme/tokens.css +1380 -200
- package/types/android.d.ts +53 -0
- package/types/index.d.ts +32 -17
- package/types/index.native.d.ts +273 -0
- package/types/index.web.d.ts +272 -0
- package/types/ios.d.ts +59 -0
- package/types/native.d.ts +5 -0
- package/types/props.d.ts +930 -40
- package/types/web.d.ts +17 -0
- package/dist/native/ui10.js +0 -32
- package/dist/native/ui25.js +0 -141
- package/dist/native/ui27.js +0 -61
- package/dist/native/ui39.js +0 -103
- package/dist/native/ui4.js +0 -24
- package/dist/native/ui46.js +0 -267
- package/dist/native/ui57.js +0 -19
- package/dist/native/ui60.js +0 -14
- package/dist/native/ui7.js +0 -52
- package/dist/web/ui10.js +0 -46
- package/dist/web/ui11.js +0 -42
- package/dist/web/ui22.js +0 -108
- package/dist/web/ui23.js +0 -96
- package/dist/web/ui26.js +0 -45
- package/dist/web/ui3.js +0 -31
- package/dist/web/ui30.js +0 -34
- package/dist/web/ui41.js +0 -43
- package/dist/web/ui44.js +0 -42
- package/dist/web/ui5.js +0 -168
- package/dist/web/ui51.js +0 -47
- package/dist/web/ui52.js +0 -19
- package/dist/web/ui55.js +0 -17
- package/dist/web/ui59.js +0 -44
- package/dist/web/ui6.js +0 -94
- package/dist/web/ui7.js +0 -62
- package/dist/web/ui8.js +0 -46
- package/dist/web/ui9.js +0 -46
- /package/dist/native/{ui20.js → RouteHost.native.tsrx.js} +0 -0
- /package/dist/native/{ui41.js → anim.native.tsrx.js} +0 -0
- /package/dist/native/{ui2.js → cx.js} +0 -0
- /package/dist/native/{ui3.js → escape-props.native.js} +0 -0
- /package/dist/native/{ui5.js → layout-child.native.js} +0 -0
- /package/dist/native/{ui54.js → meter-math.js} +0 -0
- /package/dist/native/{ui36.js → platformProps.native.js} +0 -0
- /package/dist/native/{ui37.js → popover-position.js} +0 -0
- /package/dist/native/{ui19.js → route-table.js} +0 -0
- /package/dist/native/{ui48.js → safeAreaInsets.native.tsrx.js} +0 -0
- /package/dist/native/{ui18.js → stacks.native.js} +0 -0
- /package/dist/native/{ui61.js → store.js} +0 -0
- /package/dist/native/{ui43.js → styled.native.tsrx.js} +0 -0
- /package/dist/native/{ui28.js → svg.native.js} +0 -0
- /package/dist/native/{ui30.js → theme/colorScheme.native.js} +0 -0
- /package/dist/native/{ui62.js → use-store.native.tsrx.js} +0 -0
- /package/dist/native/{ui44.js → windows.native.js} +0 -0
- /package/dist/web/{ui16.js → Link.web.tsrx.js} +0 -0
- /package/dist/web/{ui28.js → cx.js} +0 -0
- /package/dist/web/{ui2.js → escape-props.web.js} +0 -0
- /package/dist/web/{ui4.js → layout-child.web.js} +0 -0
- /package/dist/web/{ui49.js → meter-math.js} +0 -0
- /package/dist/web/{ui47.js → platformProps.web.js} +0 -0
- /package/dist/web/{ui32.js → popover-position.js} +0 -0
- /package/dist/web/{ui17.js → route-table.js} +0 -0
- /package/dist/web/{ui42.js → safeAreaInsets.web.tsrx.js} +0 -0
- /package/dist/web/{ui56.js → stacks.web.js} +0 -0
- /package/dist/web/{ui57.js → store.js} +0 -0
- /package/dist/web/{ui37.js → styled.web.tsrx.js} +0 -0
- /package/dist/web/{ui27.js → theme/colorScheme.web.js} +0 -0
- /package/dist/web/{ui58.js → use-store.web.tsrx.js} +0 -0
- /package/dist/web/{ui46.js → useMeasure.web.tsrx.js} +0 -0
- /package/dist/web/{ui38.js → windows.web.js} +0 -0
package/src/theme/tokens.css
CHANGED
|
@@ -70,15 +70,26 @@ img {
|
|
|
70
70
|
display: flex;
|
|
71
71
|
flex-direction: column;
|
|
72
72
|
}
|
|
73
|
-
/* Native has no scroll chaining — a ScrollView
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
.vx-scroll
|
|
77
|
-
.vx-list {
|
|
73
|
+
/* Native has no scroll chaining — a ScrollView just bounces inside
|
|
74
|
+
itself because the parent is never a scroller. contain is the DOM
|
|
75
|
+
equivalent: scroll stays in the leaf it started in. */
|
|
76
|
+
.vx-scroll {
|
|
78
77
|
overscroll-behavior: contain;
|
|
79
78
|
}
|
|
80
79
|
/* xplat-web-only:end */
|
|
81
80
|
|
|
81
|
+
/* Shared normalization — NS FlexboxLayout defaults flex children to
|
|
82
|
+
shrink:1 with NO min-content floor (its shrink pass clamps at
|
|
83
|
+
effectiveMinWidth/Height = the explicit min-* prop, default 0), so an
|
|
84
|
+
overflowing column crushes intrinsic children toward zero where the
|
|
85
|
+
web stops at min-content. RN's Yoga defaults flexShrink:0 for the same
|
|
86
|
+
reason — do the same on both engines. `*` is zero-specificity: flex-1
|
|
87
|
+
(the shorthand sets shrink:1) and .shrink still opt back in, and
|
|
88
|
+
truncation patterns pair them with min-w-0/min-h-0. */
|
|
89
|
+
* {
|
|
90
|
+
flex-shrink: 0;
|
|
91
|
+
}
|
|
92
|
+
|
|
82
93
|
/* vocabulary base styles */
|
|
83
94
|
|
|
84
95
|
.vx-view,
|
|
@@ -109,8 +120,17 @@ img {
|
|
|
109
120
|
display: flex;
|
|
110
121
|
flex-direction: column;
|
|
111
122
|
}
|
|
112
|
-
/*
|
|
113
|
-
|
|
123
|
+
/* Self-drawn drawer — shared geometry. Native grid children overlay the
|
|
124
|
+
cell (panel pins left via horizontalAlignment in the leaf); DOM
|
|
125
|
+
positioning extras are web-only below. */
|
|
126
|
+
.vx-drawer-backdrop {
|
|
127
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
128
|
+
}
|
|
129
|
+
.vx-drawer-panel {
|
|
130
|
+
width: 280px;
|
|
131
|
+
background-color: var(--color-surface);
|
|
132
|
+
}
|
|
133
|
+
/* xplat-web-only:start */
|
|
114
134
|
.vx-drawer {
|
|
115
135
|
display: flex;
|
|
116
136
|
flex-direction: row;
|
|
@@ -125,7 +145,6 @@ img {
|
|
|
125
145
|
.vx-drawer-backdrop {
|
|
126
146
|
position: absolute;
|
|
127
147
|
inset: 0;
|
|
128
|
-
background: rgba(0, 0, 0, 0.4);
|
|
129
148
|
}
|
|
130
149
|
.vx-drawer-panel {
|
|
131
150
|
position: absolute;
|
|
@@ -133,9 +152,7 @@ img {
|
|
|
133
152
|
top: 0;
|
|
134
153
|
bottom: 0;
|
|
135
154
|
left: 0;
|
|
136
|
-
width: 280px;
|
|
137
155
|
overflow: auto;
|
|
138
|
-
background: var(--color-surface);
|
|
139
156
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
|
|
140
157
|
}
|
|
141
158
|
/* xplat-web-only:end */
|
|
@@ -167,189 +184,1327 @@ img {
|
|
|
167
184
|
.vx-spacer {
|
|
168
185
|
flex-grow: 1;
|
|
169
186
|
}
|
|
170
|
-
|
|
171
|
-
.vx-pressable {
|
|
172
|
-
display: flex;
|
|
187
|
+
|
|
188
|
+
.vx-pressable {
|
|
189
|
+
display: flex;
|
|
190
|
+
flex-direction: column;
|
|
191
|
+
user-select: none;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* web press feedback */
|
|
195
|
+
.vx-pressable:active {
|
|
196
|
+
opacity: 0.85;
|
|
197
|
+
}
|
|
198
|
+
/* native press feedback (NS pseudo — dead rule on web, and vice versa) */
|
|
199
|
+
.vx-pressable:pressed {
|
|
200
|
+
opacity: 0.85;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* xplat-web-only:start — overlays/toasts/popovers render through RootLayout
|
|
204
|
+
or showModal on native; these portal/positioning rules are web-only */
|
|
205
|
+
.vx-overlay {
|
|
206
|
+
z-index: 1000;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.vx-overlay-shade {
|
|
210
|
+
position: absolute;
|
|
211
|
+
inset: 0;
|
|
212
|
+
background-color: rgba(0, 0, 0, 0.4);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.vx-overlay-content {
|
|
216
|
+
position: relative;
|
|
217
|
+
z-index: 1;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.vx-popover {
|
|
221
|
+
z-index: 1001;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.vx-popover-backdrop {
|
|
225
|
+
background-color: transparent;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.vx-tooltip {
|
|
229
|
+
padding: 4px 8px;
|
|
230
|
+
border-width: 1px;
|
|
231
|
+
border-color: var(--color-border);
|
|
232
|
+
border-radius: var(--radius-sm);
|
|
233
|
+
corner-shape: squircle;
|
|
234
|
+
background-color: var(--color-surface);
|
|
235
|
+
color: var(--color-text);
|
|
236
|
+
font-size: 12px;
|
|
237
|
+
line-height: 16px;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.vx-toast-host {
|
|
241
|
+
position: fixed;
|
|
242
|
+
z-index: 1002;
|
|
243
|
+
left: 0;
|
|
244
|
+
right: 0;
|
|
245
|
+
display: flex;
|
|
246
|
+
justify-content: center;
|
|
247
|
+
pointer-events: none;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.vx-toast-top {
|
|
251
|
+
top: 24px;
|
|
252
|
+
}
|
|
253
|
+
.vx-toast-bottom {
|
|
254
|
+
bottom: 24px;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
.vx-toast {
|
|
258
|
+
pointer-events: auto;
|
|
259
|
+
}
|
|
260
|
+
/* xplat-web-only:end */
|
|
261
|
+
|
|
262
|
+
/* Normalized OS-widget reset — TextInput/TextArea are real
|
|
263
|
+
<input>/<textarea>/TextField/TextView; the leaves emit vx-input/
|
|
264
|
+
vx-textarea unconditionally so the platform chrome is stripped before
|
|
265
|
+
app styles apply. On Android the transparent background replaces the
|
|
266
|
+
default EditText drawable (kills the Material underline); zero padding
|
|
267
|
+
removes native insets. Legitimate semantics — IME, secure entry,
|
|
268
|
+
selection, autofill, caret, focus — stay platform-native by design. */
|
|
269
|
+
.vx-input,
|
|
270
|
+
.vx-textarea {
|
|
271
|
+
padding: 0;
|
|
272
|
+
margin: 0;
|
|
273
|
+
border-width: 0;
|
|
274
|
+
background-color: transparent;
|
|
275
|
+
color: var(--color-text);
|
|
276
|
+
font-size: 14px;
|
|
277
|
+
/* NS placeholder color; web uses the ::placeholder pseudo below. */
|
|
278
|
+
placeholder-color: var(--color-text-secondary);
|
|
279
|
+
}
|
|
280
|
+
/* xplat-web-only:start — DOM-only reset: element UA chrome and the
|
|
281
|
+
focus outline (normalized to the same thin ring on both). */
|
|
282
|
+
.vx-input,
|
|
283
|
+
.vx-textarea {
|
|
284
|
+
appearance: none;
|
|
285
|
+
-webkit-appearance: none;
|
|
286
|
+
outline: none;
|
|
287
|
+
}
|
|
288
|
+
.vx-input:focus,
|
|
289
|
+
.vx-textarea:focus {
|
|
290
|
+
outline: 1px solid var(--color-primary);
|
|
291
|
+
outline-offset: -1px;
|
|
292
|
+
}
|
|
293
|
+
/* xplat-web-only:end */
|
|
294
|
+
|
|
295
|
+
/* auto-grow owns height — the manual resize handle has no native analog */
|
|
296
|
+
/* xplat-web-only:start */
|
|
297
|
+
.vx-textarea {
|
|
298
|
+
resize: none;
|
|
299
|
+
}
|
|
300
|
+
/* xplat-web-only:end */
|
|
301
|
+
|
|
302
|
+
/* WebView chrome reset — the web leaf is a real <iframe>: strip the UA's
|
|
303
|
+
inset border and the inline-element baseline gap. WKWebView and
|
|
304
|
+
android.webkit.WebView ship chrome-free, so there is no native reset. */
|
|
305
|
+
/* xplat-web-only:start */
|
|
306
|
+
.vx-webview {
|
|
307
|
+
display: block;
|
|
308
|
+
border-width: 0;
|
|
309
|
+
}
|
|
310
|
+
/* xplat-web-only:end */
|
|
311
|
+
|
|
312
|
+
/* Video — surface-hosted leaf: the engine surface fills the frame and the
|
|
313
|
+
self-drawn transport layers stack on top in the same grid cell
|
|
314
|
+
(vx-stack). NS-side rules only — DOM resets sit in the web block. */
|
|
315
|
+
.vx-video {
|
|
316
|
+
background-color: #000;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.vx-video-centerbtn {
|
|
320
|
+
width: 56px;
|
|
321
|
+
height: 56px;
|
|
322
|
+
border-radius: 28px;
|
|
323
|
+
background-color: rgba(0, 0, 0, 0.55);
|
|
324
|
+
align-items: center;
|
|
325
|
+
justify-content: center;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
.vx-video-bar {
|
|
329
|
+
background-color: rgba(0, 0, 0, 0.45);
|
|
330
|
+
padding: 4px 8px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
.vx-video-btn {
|
|
334
|
+
padding: 4px;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* Full-frame tap layer — hit target only, never paints. */
|
|
338
|
+
.vx-video-tap {
|
|
339
|
+
background-color: transparent;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.vx-video-time {
|
|
343
|
+
color: #fff;
|
|
344
|
+
font-size: 11px;
|
|
345
|
+
min-width: 34px;
|
|
346
|
+
text-align: center;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/* xplat-web-only:start — the <video> element is inline and overlays would
|
|
350
|
+
otherwise swallow pointer events; native layers are hit-transparent by
|
|
351
|
+
default, so none of this exists on NS. */
|
|
352
|
+
.vx-video-surface {
|
|
353
|
+
display: block;
|
|
354
|
+
width: 100%;
|
|
355
|
+
height: 100%;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
.vx-video-poster,
|
|
359
|
+
.vx-video-barwrap {
|
|
360
|
+
pointer-events: none;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.vx-video-barwrap > * {
|
|
364
|
+
pointer-events: auto;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.vx-video-poster {
|
|
368
|
+
object-fit: cover;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/* xplat-web-only:end */
|
|
372
|
+
|
|
373
|
+
/* CameraView — surface-hosted: the preview fills the frame; web shows it
|
|
374
|
+
through an object-fit:cover <video>. */
|
|
375
|
+
.vx-cameraview {
|
|
376
|
+
background-color: #000;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* xplat-web-only:start */
|
|
380
|
+
.vx-cameraview-surface {
|
|
381
|
+
display: block;
|
|
382
|
+
width: 100%;
|
|
383
|
+
height: 100%;
|
|
384
|
+
object-fit: cover;
|
|
385
|
+
}
|
|
386
|
+
/* xplat-web-only:end */
|
|
387
|
+
|
|
388
|
+
/* xplat-web-only:start */
|
|
389
|
+
/* Modal ROUTES (pushRoute presentation:'modal') — the URL stays underneath,
|
|
390
|
+
so the overlay is a fixed layer over the shell rather than a dialog. */
|
|
391
|
+
.vx-modalroute {
|
|
392
|
+
position: fixed;
|
|
393
|
+
inset: 0;
|
|
394
|
+
z-index: 1000;
|
|
395
|
+
display: flex;
|
|
396
|
+
align-items: stretch;
|
|
397
|
+
justify-content: stretch;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
.vx-modalroute-shade {
|
|
401
|
+
position: absolute;
|
|
402
|
+
inset: 0;
|
|
403
|
+
border: 0;
|
|
404
|
+
padding: 0;
|
|
405
|
+
background: rgba(0, 0, 0, 0.4);
|
|
406
|
+
cursor: default;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
.vx-modalroute-body {
|
|
410
|
+
position: relative;
|
|
411
|
+
flex: 1;
|
|
412
|
+
min-width: 0;
|
|
413
|
+
overflow: auto;
|
|
414
|
+
color: var(--color-text);
|
|
415
|
+
background-color: var(--color-surface);
|
|
416
|
+
}
|
|
417
|
+
/* xplat-web-only:end */
|
|
418
|
+
|
|
419
|
+
/* xplat-web-only:start — placeholder pseudos are DOM-only. Muted like
|
|
420
|
+
real placeholder text, not currentColor (a full-opacity hint reads as
|
|
421
|
+
a typed value); --placeholder-color is the per-field prop escape. */
|
|
422
|
+
input::placeholder,
|
|
423
|
+
textarea::placeholder {
|
|
424
|
+
color: var(--placeholder-color, var(--color-text-secondary));
|
|
425
|
+
}
|
|
426
|
+
/* xplat-web-only:end */
|
|
427
|
+
|
|
428
|
+
/* xplat-web-only:start — form controls don't inherit the body font in the
|
|
429
|
+
DOM (UA stylesheet wins); without this they render in the UA face. */
|
|
430
|
+
input,
|
|
431
|
+
textarea,
|
|
432
|
+
select,
|
|
433
|
+
button {
|
|
434
|
+
font-family: inherit;
|
|
435
|
+
}
|
|
436
|
+
/* xplat-web-only:end */
|
|
437
|
+
|
|
438
|
+
/* Self-drawn spinner — the border ring is shared (native rotates the
|
|
439
|
+
view via `animate`; DOM spins via the keyframes below). */
|
|
440
|
+
.vx-spinner {
|
|
441
|
+
width: 24px;
|
|
442
|
+
height: 24px;
|
|
443
|
+
border-width: 2px;
|
|
444
|
+
border-color: var(--color-text-secondary);
|
|
445
|
+
border-right-color: transparent;
|
|
446
|
+
border-radius: 50%;
|
|
447
|
+
}
|
|
448
|
+
/* Pull-to-refresh — the overlay strip hosting the spinner. Its height is
|
|
449
|
+
the default `refreshThreshold` (64px web / 64dip native); the leaf
|
|
450
|
+
translates it in/out — reveal math lives in refresh.*.ts. */
|
|
451
|
+
.vx-refresh {
|
|
452
|
+
display: flex;
|
|
453
|
+
flex-direction: column;
|
|
454
|
+
align-items: center;
|
|
455
|
+
justify-content: center;
|
|
456
|
+
height: 64px;
|
|
457
|
+
}
|
|
458
|
+
/* xplat-web-only:start — the DOM leaf needs explicit clipping plus the
|
|
459
|
+
absolute overlay; native clips via the wrapper grid
|
|
460
|
+
(clipsToBounds/ViewGroup) and stacks children in one cell. */
|
|
461
|
+
.vx-refresh-wrap {
|
|
462
|
+
position: relative;
|
|
463
|
+
overflow: hidden;
|
|
464
|
+
display: flex;
|
|
465
|
+
flex-direction: column;
|
|
466
|
+
}
|
|
467
|
+
.vx-refresh-wrap > .vx-scroll {
|
|
468
|
+
flex: 1;
|
|
469
|
+
min-height: 0;
|
|
470
|
+
}
|
|
471
|
+
.vx-refresh {
|
|
472
|
+
position: absolute;
|
|
473
|
+
top: 0;
|
|
474
|
+
left: 0;
|
|
475
|
+
right: 0;
|
|
476
|
+
}
|
|
477
|
+
/* xplat-web-only:end */
|
|
478
|
+
/* xplat-web-only:start — DOM needs an inline-block box + CSS animation;
|
|
479
|
+
the native leaf drives view.animate instead */
|
|
480
|
+
.vx-spinner {
|
|
481
|
+
display: inline-block;
|
|
482
|
+
box-sizing: border-box;
|
|
483
|
+
animation: vx-spinner-turn 0.8s linear infinite;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
@keyframes vx-spinner-turn {
|
|
487
|
+
to {
|
|
488
|
+
transform: rotate(360deg);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
/* xplat-web-only:end */
|
|
492
|
+
|
|
493
|
+
/* Self-drawn switch — flex track + thumb. `--on` flips justify-content,
|
|
494
|
+
which slides the thumb; identical geometry on web and native. */
|
|
495
|
+
.vx-switch {
|
|
496
|
+
width: 48px;
|
|
497
|
+
height: 28px;
|
|
498
|
+
padding-left: 3px;
|
|
499
|
+
padding-right: 3px;
|
|
500
|
+
border-radius: 14px;
|
|
501
|
+
background-color: var(--color-border);
|
|
502
|
+
justify-content: flex-start;
|
|
503
|
+
align-items: center;
|
|
504
|
+
}
|
|
505
|
+
.vx-switch--on {
|
|
506
|
+
background-color: var(--color-primary);
|
|
507
|
+
justify-content: flex-end;
|
|
508
|
+
}
|
|
509
|
+
.vx-switch-thumb {
|
|
510
|
+
width: 22px;
|
|
511
|
+
height: 22px;
|
|
512
|
+
border-radius: 50%;
|
|
513
|
+
background-color: var(--color-surface);
|
|
514
|
+
}
|
|
515
|
+
/* xplat-web-only:start — the DOM host is a div; flex + cursor live here */
|
|
516
|
+
.vx-switch {
|
|
517
|
+
display: flex;
|
|
518
|
+
cursor: pointer;
|
|
519
|
+
}
|
|
520
|
+
/* xplat-web-only:end */
|
|
521
|
+
|
|
522
|
+
/* Self-drawn slider — host is a grid (native) / relative div (web);
|
|
523
|
+
track + fill + thumb overlay the same box. */
|
|
524
|
+
.vx-slider {
|
|
525
|
+
height: 28px;
|
|
526
|
+
}
|
|
527
|
+
.vx-slider-track {
|
|
528
|
+
height: 4px;
|
|
529
|
+
border-radius: 2px;
|
|
530
|
+
background-color: var(--color-border);
|
|
531
|
+
vertical-align: middle;
|
|
532
|
+
}
|
|
533
|
+
.vx-slider-fill {
|
|
534
|
+
height: 4px;
|
|
535
|
+
border-radius: 2px;
|
|
536
|
+
background-color: var(--color-primary);
|
|
537
|
+
vertical-align: middle;
|
|
538
|
+
}
|
|
539
|
+
.vx-slider-thumb {
|
|
540
|
+
width: 20px;
|
|
541
|
+
height: 20px;
|
|
542
|
+
border-radius: 50%;
|
|
543
|
+
background-color: var(--color-primary);
|
|
544
|
+
vertical-align: middle;
|
|
545
|
+
}
|
|
546
|
+
/* xplat-web-only:start — absolute positioning is DOM-only; native grid
|
|
547
|
+
children center via vertical-align and pin via margin-left. */
|
|
548
|
+
.vx-slider {
|
|
549
|
+
position: relative;
|
|
550
|
+
}
|
|
551
|
+
.vx-slider-track,
|
|
552
|
+
.vx-slider-fill {
|
|
553
|
+
position: absolute;
|
|
554
|
+
top: 50%;
|
|
555
|
+
left: 0;
|
|
556
|
+
right: 0;
|
|
557
|
+
transform: translateY(-50%);
|
|
558
|
+
}
|
|
559
|
+
.vx-slider-thumb {
|
|
560
|
+
position: absolute;
|
|
561
|
+
top: 50%;
|
|
562
|
+
transform: translate(-50%, -50%);
|
|
563
|
+
}
|
|
564
|
+
/* xplat-web-only:end */
|
|
565
|
+
|
|
566
|
+
/* xplat-web-only:start — Pager's web leaf is a mandatory scroll-snap row:
|
|
567
|
+
one page per item at 100% host width so scrollLeft / clientWidth is a
|
|
568
|
+
clean page index. Native pages are sized by the widget itself, so the
|
|
569
|
+
whole block is DOM-only. Scrollbar hidden (native has none); contain
|
|
570
|
+
keeps the swipe from chaining to a parent scroller, matching .vx-scroll. */
|
|
571
|
+
.vx-pager {
|
|
572
|
+
display: flex;
|
|
573
|
+
flex-direction: row;
|
|
574
|
+
overflow-x: auto;
|
|
575
|
+
overflow-y: hidden;
|
|
576
|
+
scroll-snap-type: x mandatory;
|
|
577
|
+
overscroll-behavior-x: contain;
|
|
578
|
+
scrollbar-width: none;
|
|
579
|
+
touch-action: pan-x;
|
|
580
|
+
}
|
|
581
|
+
.vx-pager::-webkit-scrollbar {
|
|
582
|
+
display: none;
|
|
583
|
+
}
|
|
584
|
+
.vx-pager-page {
|
|
585
|
+
flex: 0 0 100%;
|
|
586
|
+
min-width: 0;
|
|
587
|
+
display: flex;
|
|
588
|
+
flex-direction: column;
|
|
589
|
+
scroll-snap-align: start;
|
|
590
|
+
}
|
|
591
|
+
/* xplat-web-only:end */
|
|
592
|
+
|
|
593
|
+
/* Phase-1 self-drawn components — functional geometry + token chrome only;
|
|
594
|
+
visual design is the app's job. */
|
|
595
|
+
|
|
596
|
+
/* Button — row-direction pressable (vx-pressable already supplies display
|
|
597
|
+
and press feedback). */
|
|
598
|
+
.vx-button {
|
|
599
|
+
flex-direction: row;
|
|
600
|
+
align-items: center;
|
|
601
|
+
justify-content: center;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/* Collapsible/Accordion — column stacks. */
|
|
605
|
+
.vx-collapsible,
|
|
606
|
+
.vx-collapsible-content,
|
|
607
|
+
.vx-accordion,
|
|
608
|
+
.vx-accordion-item {
|
|
609
|
+
flex-direction: column;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/* Checkbox — 20px box + check glyph; --on fills with primary. */
|
|
613
|
+
.vx-checkbox-row {
|
|
614
|
+
flex-direction: row;
|
|
615
|
+
align-items: center;
|
|
616
|
+
}
|
|
617
|
+
.vx-checkbox {
|
|
618
|
+
width: 20px;
|
|
619
|
+
height: 20px;
|
|
620
|
+
border-width: 1px;
|
|
621
|
+
border-color: var(--color-border);
|
|
622
|
+
border-radius: var(--radius-sm);
|
|
623
|
+
align-items: center;
|
|
624
|
+
justify-content: center;
|
|
625
|
+
}
|
|
626
|
+
.vx-checkbox--on .vx-checkbox {
|
|
627
|
+
background-color: var(--color-primary);
|
|
628
|
+
border-color: var(--color-primary);
|
|
629
|
+
}
|
|
630
|
+
.vx-checkbox-check {
|
|
631
|
+
font-size: 14px;
|
|
632
|
+
line-height: 20px;
|
|
633
|
+
color: var(--color-onprimary);
|
|
634
|
+
}
|
|
635
|
+
.vx-checkbox-label {
|
|
636
|
+
margin-left: 8px;
|
|
637
|
+
}
|
|
638
|
+
.vx-checkbox--disabled {
|
|
639
|
+
opacity: 0.5;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/* Radio group — column/row of dot options. */
|
|
643
|
+
.vx-radio-group {
|
|
644
|
+
flex-direction: column;
|
|
645
|
+
}
|
|
646
|
+
.vx-radio-group--row {
|
|
647
|
+
flex-direction: row;
|
|
648
|
+
}
|
|
649
|
+
.vx-radio-row {
|
|
650
|
+
flex-direction: row;
|
|
651
|
+
align-items: center;
|
|
652
|
+
}
|
|
653
|
+
.vx-radio {
|
|
654
|
+
width: 18px;
|
|
655
|
+
height: 18px;
|
|
656
|
+
border-width: 1px;
|
|
657
|
+
border-color: var(--color-border);
|
|
658
|
+
border-radius: 50%;
|
|
659
|
+
align-items: center;
|
|
660
|
+
justify-content: center;
|
|
661
|
+
}
|
|
662
|
+
.vx-radio--on .vx-radio {
|
|
663
|
+
border-color: var(--color-primary);
|
|
664
|
+
}
|
|
665
|
+
.vx-radio-dot {
|
|
666
|
+
width: 8px;
|
|
667
|
+
height: 8px;
|
|
668
|
+
border-radius: 50%;
|
|
669
|
+
background-color: var(--color-primary);
|
|
670
|
+
}
|
|
671
|
+
.vx-radio-label {
|
|
672
|
+
margin-left: 8px;
|
|
673
|
+
}
|
|
674
|
+
.vx-radio--disabled {
|
|
675
|
+
opacity: 0.5;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/* SegmentedControl — equal-width segments in a rounded track; `--on`
|
|
679
|
+
raises the selected one. flex-basis is dead on NS (the shorthand parser
|
|
680
|
+
drops it and the standalone property isn't registered), so width:0 +
|
|
681
|
+
flex-grow:1 is what distributes segments equally on both engines. */
|
|
682
|
+
.vx-segmented {
|
|
683
|
+
flex-direction: row;
|
|
684
|
+
padding: 3px;
|
|
685
|
+
border-width: 1px;
|
|
686
|
+
border-color: var(--color-border);
|
|
687
|
+
border-radius: var(--radius-md);
|
|
688
|
+
corner-shape: squircle;
|
|
689
|
+
background-color: var(--color-surface-secondary);
|
|
690
|
+
color: var(--color-text);
|
|
691
|
+
}
|
|
692
|
+
.vx-segment {
|
|
693
|
+
flex-grow: 1;
|
|
694
|
+
width: 0;
|
|
695
|
+
flex-direction: row;
|
|
696
|
+
align-items: center;
|
|
697
|
+
justify-content: center;
|
|
698
|
+
padding-top: 6px;
|
|
699
|
+
padding-bottom: 6px;
|
|
700
|
+
padding-left: 10px;
|
|
701
|
+
padding-right: 10px;
|
|
702
|
+
border-radius: var(--radius-sm);
|
|
703
|
+
}
|
|
704
|
+
.vx-segment--on {
|
|
705
|
+
background-color: var(--color-surface);
|
|
706
|
+
}
|
|
707
|
+
.vx-segment-label {
|
|
708
|
+
font-size: 13px;
|
|
709
|
+
color: var(--color-text-secondary);
|
|
710
|
+
}
|
|
711
|
+
.vx-segment--on .vx-segment-label {
|
|
712
|
+
color: var(--color-text);
|
|
713
|
+
font-weight: 600;
|
|
714
|
+
}
|
|
715
|
+
.vx-segmented--disabled,
|
|
716
|
+
.vx-segment--disabled {
|
|
717
|
+
opacity: 0.5;
|
|
718
|
+
}
|
|
719
|
+
/* xplat-web-only:start — the DOM hosts are divs; flex + cursor live here */
|
|
720
|
+
.vx-segmented {
|
|
721
|
+
display: flex;
|
|
722
|
+
}
|
|
723
|
+
.vx-segment {
|
|
724
|
+
display: flex;
|
|
725
|
+
cursor: pointer;
|
|
726
|
+
user-select: none;
|
|
727
|
+
}
|
|
728
|
+
.vx-segment:focus {
|
|
729
|
+
outline: 1px solid var(--color-primary);
|
|
730
|
+
outline-offset: -1px;
|
|
731
|
+
}
|
|
732
|
+
.vx-segment--disabled {
|
|
733
|
+
cursor: default;
|
|
734
|
+
}
|
|
735
|
+
/* xplat-web-only:end */
|
|
736
|
+
|
|
737
|
+
/* SearchInput — chrome-reset field: bordered shell, leading glyph, the
|
|
738
|
+
field owns the remaining width, self-drawn clear. The web leaf hides the
|
|
739
|
+
engine's own search-cancel button so native's (hand-drawn) matches. */
|
|
740
|
+
.vx-search {
|
|
741
|
+
flex-direction: row;
|
|
742
|
+
align-items: center;
|
|
743
|
+
padding-top: 6px;
|
|
744
|
+
padding-bottom: 6px;
|
|
745
|
+
padding-left: 10px;
|
|
746
|
+
padding-right: 6px;
|
|
747
|
+
border-width: 1px;
|
|
748
|
+
border-color: var(--color-border);
|
|
749
|
+
border-radius: var(--radius-md);
|
|
750
|
+
corner-shape: squircle;
|
|
751
|
+
background-color: var(--color-surface);
|
|
752
|
+
color: var(--color-text);
|
|
753
|
+
}
|
|
754
|
+
.vx-search-icon {
|
|
755
|
+
color: var(--color-text-secondary);
|
|
756
|
+
}
|
|
757
|
+
.vx-search-field {
|
|
758
|
+
flex-grow: 1;
|
|
759
|
+
padding-left: 8px;
|
|
760
|
+
padding-right: 8px;
|
|
761
|
+
font-size: 14px;
|
|
762
|
+
color: var(--color-text);
|
|
763
|
+
}
|
|
764
|
+
.vx-search-clear {
|
|
765
|
+
width: 24px;
|
|
766
|
+
height: 24px;
|
|
767
|
+
border-radius: 9999px;
|
|
768
|
+
align-items: center;
|
|
769
|
+
justify-content: center;
|
|
770
|
+
background-color: var(--color-surface-secondary);
|
|
771
|
+
color: var(--color-text-secondary);
|
|
772
|
+
}
|
|
773
|
+
.vx-search--disabled {
|
|
774
|
+
opacity: 0.5;
|
|
775
|
+
}
|
|
776
|
+
/* xplat-web-only:start — the DOM host/field/buttons need display + the UA
|
|
777
|
+
reset; native's flexbox children carry these from the class already. */
|
|
778
|
+
.vx-search {
|
|
779
|
+
display: flex;
|
|
780
|
+
}
|
|
781
|
+
.vx-search-icon {
|
|
782
|
+
display: inline-flex;
|
|
783
|
+
flex: none;
|
|
784
|
+
}
|
|
785
|
+
.vx-search-field {
|
|
786
|
+
min-width: 0;
|
|
787
|
+
border: 0;
|
|
788
|
+
background: none;
|
|
789
|
+
outline: none;
|
|
790
|
+
appearance: none;
|
|
791
|
+
-webkit-appearance: none;
|
|
792
|
+
}
|
|
793
|
+
input.vx-search-field::-webkit-search-cancel-button {
|
|
794
|
+
display: none;
|
|
795
|
+
}
|
|
796
|
+
.vx-search-clear {
|
|
797
|
+
display: inline-flex;
|
|
798
|
+
border: 0;
|
|
799
|
+
padding: 0;
|
|
800
|
+
cursor: pointer;
|
|
801
|
+
}
|
|
802
|
+
/* xplat-web-only:end */
|
|
803
|
+
|
|
804
|
+
/* Anchored menus — panel + item rows (the Popover leaf positions it). */
|
|
805
|
+
.vx-menu {
|
|
806
|
+
min-width: 140px;
|
|
807
|
+
padding: 4px;
|
|
808
|
+
border-width: 1px;
|
|
809
|
+
border-color: var(--color-border);
|
|
810
|
+
border-radius: var(--radius-md);
|
|
811
|
+
corner-shape: squircle;
|
|
812
|
+
background-color: var(--color-surface);
|
|
813
|
+
color: var(--color-text);
|
|
814
|
+
}
|
|
815
|
+
.vx-menu-list {
|
|
816
|
+
flex-direction: column;
|
|
817
|
+
}
|
|
818
|
+
.vx-menu-item {
|
|
819
|
+
flex-direction: row;
|
|
820
|
+
align-items: center;
|
|
821
|
+
padding: 6px 10px;
|
|
822
|
+
border-radius: var(--radius-sm);
|
|
823
|
+
}
|
|
824
|
+
.vx-menu-item--disabled {
|
|
825
|
+
opacity: 0.5;
|
|
826
|
+
}
|
|
827
|
+
/* xplat-web-only:start — hover affordance and cursor are DOM-only */
|
|
828
|
+
.vx-menu-item {
|
|
829
|
+
cursor: pointer;
|
|
830
|
+
}
|
|
831
|
+
.vx-menu-item:hover {
|
|
832
|
+
background-color: var(--color-border);
|
|
833
|
+
}
|
|
834
|
+
/* xplat-web-only:end */
|
|
835
|
+
|
|
836
|
+
/* Badge — inline chip row. */
|
|
837
|
+
.vx-badge {
|
|
838
|
+
flex-direction: row;
|
|
839
|
+
align-items: center;
|
|
840
|
+
border-radius: var(--radius-sm);
|
|
841
|
+
padding: 1px 6px;
|
|
842
|
+
font-size: 12px;
|
|
843
|
+
line-height: 16px;
|
|
844
|
+
}
|
|
845
|
+
/* xplat-web-only:start — span is inline by default; needs inline-flex */
|
|
846
|
+
.vx-badge {
|
|
847
|
+
display: inline-flex;
|
|
848
|
+
}
|
|
849
|
+
/* xplat-web-only:end */
|
|
850
|
+
|
|
851
|
+
/* Separator — hairline rule; --h spans width, --v spans height. */
|
|
852
|
+
.vx-separator--h {
|
|
853
|
+
height: 1px;
|
|
854
|
+
background-color: var(--color-border);
|
|
855
|
+
}
|
|
856
|
+
.vx-separator--v {
|
|
857
|
+
width: 1px;
|
|
858
|
+
align-self: stretch;
|
|
859
|
+
background-color: var(--color-border);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/* Skeleton — placeholder block. */
|
|
863
|
+
.vx-skeleton {
|
|
864
|
+
background-color: var(--color-border);
|
|
865
|
+
border-radius: var(--radius-md);
|
|
866
|
+
corner-shape: squircle;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/* Avatar — centered fallback inside the circle. */
|
|
870
|
+
.vx-avatar {
|
|
871
|
+
align-items: center;
|
|
872
|
+
justify-content: center;
|
|
873
|
+
background-color: var(--color-border);
|
|
874
|
+
}
|
|
875
|
+
.vx-avatar-group {
|
|
876
|
+
flex-direction: row;
|
|
877
|
+
align-items: center;
|
|
878
|
+
}
|
|
879
|
+
/* xplat-web-only:start — display:flex for the div-based flex classes */
|
|
880
|
+
.vx-collapsible,
|
|
881
|
+
.vx-collapsible-content,
|
|
882
|
+
.vx-accordion,
|
|
883
|
+
.vx-accordion-item,
|
|
884
|
+
.vx-checkbox-row,
|
|
885
|
+
.vx-checkbox,
|
|
886
|
+
.vx-radio-group,
|
|
887
|
+
.vx-radio-row,
|
|
888
|
+
.vx-radio,
|
|
889
|
+
.vx-menu-list,
|
|
890
|
+
.vx-menu-item,
|
|
891
|
+
.vx-contextmenu,
|
|
892
|
+
.vx-avatar,
|
|
893
|
+
.vx-avatar-group,
|
|
894
|
+
.vx-avatar-group-item {
|
|
895
|
+
display: flex;
|
|
896
|
+
}
|
|
897
|
+
.vx-checkbox-row,
|
|
898
|
+
.vx-radio-row {
|
|
899
|
+
cursor: pointer;
|
|
900
|
+
}
|
|
901
|
+
.vx-checkbox-check {
|
|
902
|
+
display: block;
|
|
903
|
+
}
|
|
904
|
+
/* xplat-web-only:end */
|
|
905
|
+
|
|
906
|
+
/* Phase-2 form field layer. */
|
|
907
|
+
|
|
908
|
+
/* FormField — label / control / message column. */
|
|
909
|
+
.vx-field {
|
|
910
|
+
flex-direction: column;
|
|
911
|
+
}
|
|
912
|
+
.vx-field-label {
|
|
913
|
+
font-size: 13px;
|
|
914
|
+
line-height: 20px;
|
|
915
|
+
font-weight: 500;
|
|
916
|
+
margin-bottom: 4px;
|
|
917
|
+
}
|
|
918
|
+
.vx-field-required {
|
|
919
|
+
color: var(--color-danger);
|
|
920
|
+
}
|
|
921
|
+
.vx-field-msg {
|
|
922
|
+
font-size: 12px;
|
|
923
|
+
line-height: 16px;
|
|
924
|
+
margin-top: 4px;
|
|
925
|
+
color: var(--color-text-secondary);
|
|
926
|
+
}
|
|
927
|
+
.vx-field-msg--error {
|
|
928
|
+
color: var(--color-danger);
|
|
929
|
+
}
|
|
930
|
+
.vx-fieldgroup {
|
|
931
|
+
flex-direction: column;
|
|
932
|
+
}
|
|
933
|
+
.vx-fieldgroup-label {
|
|
934
|
+
font-size: 13px;
|
|
935
|
+
line-height: 20px;
|
|
936
|
+
font-weight: 600;
|
|
937
|
+
margin-bottom: 8px;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
/* InputNumber — steppers flanking a centered field. */
|
|
941
|
+
.vx-inputnumber {
|
|
942
|
+
flex-direction: row;
|
|
943
|
+
align-items: center;
|
|
944
|
+
}
|
|
945
|
+
.vx-inputnumber-step {
|
|
946
|
+
padding: 4px 10px;
|
|
947
|
+
border-width: 1px;
|
|
948
|
+
border-color: var(--color-border);
|
|
949
|
+
border-radius: var(--radius-sm);
|
|
950
|
+
align-items: center;
|
|
951
|
+
justify-content: center;
|
|
952
|
+
}
|
|
953
|
+
.vx-inputnumber-field {
|
|
954
|
+
width: 64px;
|
|
955
|
+
margin-left: 8px;
|
|
956
|
+
margin-right: 8px;
|
|
957
|
+
text-align: center;
|
|
958
|
+
}
|
|
959
|
+
.vx-inputnumber--disabled {
|
|
960
|
+
opacity: 0.5;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/* PinInput — row of single cells. */
|
|
964
|
+
.vx-pininput {
|
|
965
|
+
flex-direction: row;
|
|
966
|
+
}
|
|
967
|
+
.vx-pininput-cell {
|
|
968
|
+
width: 40px;
|
|
969
|
+
margin-right: 8px;
|
|
970
|
+
text-align: center;
|
|
971
|
+
}
|
|
972
|
+
.vx-pininput--disabled {
|
|
973
|
+
opacity: 0.5;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
/* Select — trigger row + check column inside the anchored listbox. */
|
|
977
|
+
.vx-select-trigger {
|
|
978
|
+
flex-direction: row;
|
|
979
|
+
align-items: center;
|
|
980
|
+
justify-content: space-between;
|
|
981
|
+
padding: 6px 10px;
|
|
982
|
+
border-width: 1px;
|
|
983
|
+
border-color: var(--color-border);
|
|
984
|
+
border-radius: var(--radius-sm);
|
|
985
|
+
}
|
|
986
|
+
.vx-select--disabled {
|
|
987
|
+
opacity: 0.5;
|
|
988
|
+
}
|
|
989
|
+
.vx-select-placeholder {
|
|
990
|
+
color: var(--color-text-secondary);
|
|
991
|
+
}
|
|
992
|
+
.vx-select-caret {
|
|
993
|
+
margin-left: 8px;
|
|
994
|
+
}
|
|
995
|
+
.vx-select-check {
|
|
996
|
+
width: 16px;
|
|
997
|
+
}
|
|
998
|
+
.vx-select-search {
|
|
999
|
+
margin-bottom: 4px;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
/* InputTags — wrapped chip row + trailing field. */
|
|
1003
|
+
.vx-inputtags {
|
|
1004
|
+
flex-direction: row;
|
|
1005
|
+
flex-wrap: wrap;
|
|
1006
|
+
align-items: center;
|
|
1007
|
+
}
|
|
1008
|
+
.vx-inputtags-tag {
|
|
1009
|
+
flex-direction: row;
|
|
1010
|
+
align-items: center;
|
|
1011
|
+
padding: 1px 6px;
|
|
1012
|
+
margin-right: 4px;
|
|
1013
|
+
margin-bottom: 4px;
|
|
1014
|
+
border-radius: var(--radius-sm);
|
|
1015
|
+
background-color: var(--color-border);
|
|
1016
|
+
}
|
|
1017
|
+
.vx-inputtags-remove {
|
|
1018
|
+
margin-left: 4px;
|
|
1019
|
+
}
|
|
1020
|
+
.vx-inputtags-field {
|
|
1021
|
+
flex: 1;
|
|
1022
|
+
min-width: 80px;
|
|
1023
|
+
}
|
|
1024
|
+
.vx-inputtags--disabled {
|
|
1025
|
+
opacity: 0.5;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/* InputRating — glyph row; --on lights the cell. */
|
|
1029
|
+
.vx-rating {
|
|
1030
|
+
flex-direction: row;
|
|
1031
|
+
}
|
|
1032
|
+
.vx-rating-cell {
|
|
1033
|
+
padding: 2px;
|
|
1034
|
+
}
|
|
1035
|
+
.vx-rating-glyph {
|
|
1036
|
+
font-size: 20px;
|
|
1037
|
+
line-height: 24px;
|
|
1038
|
+
color: var(--color-border);
|
|
1039
|
+
}
|
|
1040
|
+
.vx-rating-cell--on .vx-rating-glyph {
|
|
1041
|
+
color: var(--color-primary);
|
|
1042
|
+
}
|
|
1043
|
+
.vx-rating--disabled {
|
|
1044
|
+
opacity: 0.5;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
/* CheckboxGroup — column/row of checkboxes. */
|
|
1048
|
+
.vx-checkbox-group {
|
|
1049
|
+
flex-direction: column;
|
|
1050
|
+
}
|
|
1051
|
+
.vx-checkbox-group--row {
|
|
1052
|
+
flex-direction: row;
|
|
1053
|
+
}
|
|
1054
|
+
/* xplat-web-only:start — display:flex for the div/span flex classes */
|
|
1055
|
+
.vx-field,
|
|
1056
|
+
.vx-fieldgroup,
|
|
1057
|
+
.vx-inputnumber,
|
|
1058
|
+
.vx-inputnumber-step,
|
|
1059
|
+
.vx-select-trigger,
|
|
1060
|
+
.vx-select-list,
|
|
1061
|
+
.vx-inputtags,
|
|
1062
|
+
.vx-inputtags-tag,
|
|
1063
|
+
.vx-rating,
|
|
1064
|
+
.vx-rating-cell,
|
|
1065
|
+
.vx-checkbox-group {
|
|
1066
|
+
display: flex;
|
|
1067
|
+
}
|
|
1068
|
+
.vx-rating-cell {
|
|
1069
|
+
cursor: pointer;
|
|
1070
|
+
}
|
|
1071
|
+
/* xplat-web-only:end */
|
|
1072
|
+
|
|
1073
|
+
/* Phase-3 navigation & wayfinding. */
|
|
1074
|
+
|
|
1075
|
+
/* Breadcrumb — inline trail. */
|
|
1076
|
+
.vx-breadcrumb {
|
|
1077
|
+
flex-direction: row;
|
|
1078
|
+
align-items: center;
|
|
1079
|
+
flex-wrap: wrap;
|
|
1080
|
+
}
|
|
1081
|
+
.vx-breadcrumb-item {
|
|
1082
|
+
flex-direction: row;
|
|
1083
|
+
align-items: center;
|
|
1084
|
+
}
|
|
1085
|
+
.vx-breadcrumb-sep {
|
|
1086
|
+
margin-left: 6px;
|
|
1087
|
+
margin-right: 6px;
|
|
1088
|
+
color: var(--color-text-secondary);
|
|
1089
|
+
}
|
|
1090
|
+
.vx-breadcrumb-link {
|
|
1091
|
+
color: var(--color-primary);
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
/* Pagination — windowed page buttons. */
|
|
1095
|
+
.vx-pagination {
|
|
1096
|
+
flex-direction: row;
|
|
1097
|
+
align-items: center;
|
|
1098
|
+
}
|
|
1099
|
+
.vx-page-btn {
|
|
1100
|
+
min-width: 28px;
|
|
1101
|
+
height: 28px;
|
|
1102
|
+
padding: 0 6px;
|
|
1103
|
+
margin-right: 4px;
|
|
1104
|
+
border-width: 1px;
|
|
1105
|
+
border-color: var(--color-border);
|
|
1106
|
+
border-radius: var(--radius-sm);
|
|
1107
|
+
align-items: center;
|
|
1108
|
+
justify-content: center;
|
|
1109
|
+
}
|
|
1110
|
+
.vx-page-btn--on {
|
|
1111
|
+
background-color: var(--color-primary);
|
|
1112
|
+
border-color: var(--color-primary);
|
|
1113
|
+
color: var(--color-onprimary);
|
|
1114
|
+
}
|
|
1115
|
+
.vx-page-ellipsis {
|
|
1116
|
+
margin-right: 4px;
|
|
1117
|
+
color: var(--color-text-secondary);
|
|
1118
|
+
}
|
|
1119
|
+
.vx-pagination--disabled {
|
|
1120
|
+
opacity: 0.5;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
/* Stepper — dot + label cells joined by a hairline. */
|
|
1124
|
+
.vx-stepper {
|
|
1125
|
+
flex-direction: row;
|
|
1126
|
+
align-items: center;
|
|
1127
|
+
}
|
|
1128
|
+
.vx-stepper-cell {
|
|
1129
|
+
flex-direction: row;
|
|
1130
|
+
align-items: center;
|
|
1131
|
+
}
|
|
1132
|
+
.vx-stepper-line {
|
|
1133
|
+
width: 24px;
|
|
1134
|
+
height: 1px;
|
|
1135
|
+
background-color: var(--color-border);
|
|
1136
|
+
}
|
|
1137
|
+
.vx-stepper-line--done {
|
|
1138
|
+
background-color: var(--color-primary);
|
|
1139
|
+
}
|
|
1140
|
+
.vx-step {
|
|
1141
|
+
flex-direction: row;
|
|
1142
|
+
align-items: center;
|
|
1143
|
+
}
|
|
1144
|
+
.vx-step-dot {
|
|
1145
|
+
width: 24px;
|
|
1146
|
+
height: 24px;
|
|
1147
|
+
border-width: 1px;
|
|
1148
|
+
border-color: var(--color-border);
|
|
1149
|
+
border-radius: 50%;
|
|
1150
|
+
text-align: center;
|
|
1151
|
+
font-size: 12px;
|
|
1152
|
+
line-height: 22px;
|
|
1153
|
+
color: var(--color-text-secondary);
|
|
1154
|
+
}
|
|
1155
|
+
.vx-step--on .vx-step-dot {
|
|
1156
|
+
border-color: var(--color-primary);
|
|
1157
|
+
color: var(--color-primary);
|
|
1158
|
+
}
|
|
1159
|
+
.vx-step--done .vx-step-dot {
|
|
1160
|
+
background-color: var(--color-primary);
|
|
1161
|
+
border-color: var(--color-primary);
|
|
1162
|
+
color: var(--color-onprimary);
|
|
1163
|
+
}
|
|
1164
|
+
.vx-step-label {
|
|
1165
|
+
margin-left: 6px;
|
|
1166
|
+
}
|
|
1167
|
+
.vx-step--disabled {
|
|
1168
|
+
opacity: 0.5;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
/* NavigationMenu — row/column of nav items. */
|
|
1172
|
+
.vx-navmenu,
|
|
1173
|
+
.vx-navmenu--row {
|
|
1174
|
+
flex-direction: row;
|
|
1175
|
+
align-items: center;
|
|
1176
|
+
}
|
|
1177
|
+
.vx-navmenu--col {
|
|
1178
|
+
flex-direction: column;
|
|
1179
|
+
align-items: flex-start;
|
|
1180
|
+
}
|
|
1181
|
+
.vx-navmenu-item {
|
|
1182
|
+
flex-direction: row;
|
|
1183
|
+
align-items: center;
|
|
1184
|
+
padding: 6px 10px;
|
|
1185
|
+
border-radius: var(--radius-sm);
|
|
1186
|
+
}
|
|
1187
|
+
.vx-navmenu-item--on {
|
|
1188
|
+
background-color: var(--color-border);
|
|
1189
|
+
}
|
|
1190
|
+
.vx-navmenu-item--disabled {
|
|
1191
|
+
opacity: 0.5;
|
|
1192
|
+
}
|
|
1193
|
+
.vx-navmenu-label {
|
|
1194
|
+
margin-left: 4px;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
/* CommandPalette — panel centered by the overlay layer. */
|
|
1198
|
+
.vx-commandpalette {
|
|
1199
|
+
width: 360px;
|
|
1200
|
+
max-width: 90%;
|
|
1201
|
+
padding: 8px;
|
|
1202
|
+
border-width: 1px;
|
|
1203
|
+
border-color: var(--color-border);
|
|
1204
|
+
border-radius: var(--radius-md);
|
|
1205
|
+
corner-shape: squircle;
|
|
1206
|
+
background-color: var(--color-surface);
|
|
1207
|
+
color: var(--color-text);
|
|
1208
|
+
}
|
|
1209
|
+
.vx-cmdk-search {
|
|
1210
|
+
margin-bottom: 4px;
|
|
1211
|
+
}
|
|
1212
|
+
/* xplat-web-only:start — display, centering, and cursor are DOM-only */
|
|
1213
|
+
.vx-breadcrumb,
|
|
1214
|
+
.vx-breadcrumb-item,
|
|
1215
|
+
.vx-pagination,
|
|
1216
|
+
.vx-page-btn,
|
|
1217
|
+
.vx-stepper,
|
|
1218
|
+
.vx-stepper-cell,
|
|
1219
|
+
.vx-step,
|
|
1220
|
+
.vx-navmenu,
|
|
1221
|
+
.vx-navmenu-item {
|
|
1222
|
+
display: flex;
|
|
1223
|
+
}
|
|
1224
|
+
.vx-cmdk-layer .vx-overlay-content {
|
|
1225
|
+
position: absolute;
|
|
1226
|
+
top: 15%;
|
|
1227
|
+
left: 50%;
|
|
1228
|
+
transform: translateX(-50%);
|
|
1229
|
+
}
|
|
1230
|
+
.vx-page-btn,
|
|
1231
|
+
.vx-breadcrumb-link,
|
|
1232
|
+
.vx-step,
|
|
1233
|
+
.vx-navmenu-item {
|
|
1234
|
+
cursor: pointer;
|
|
1235
|
+
}
|
|
1236
|
+
/* xplat-web-only:end */
|
|
1237
|
+
|
|
1238
|
+
/* Phase-4 data display. */
|
|
1239
|
+
|
|
1240
|
+
/* Table — header + bounded rows (unvirtualized by design). */
|
|
1241
|
+
.vx-table {
|
|
1242
|
+
flex-direction: column;
|
|
1243
|
+
border-width: 1px;
|
|
1244
|
+
border-color: var(--color-border);
|
|
1245
|
+
border-radius: var(--radius-md);
|
|
1246
|
+
}
|
|
1247
|
+
.vx-table-head,
|
|
1248
|
+
.vx-table-row {
|
|
1249
|
+
flex-direction: row;
|
|
1250
|
+
}
|
|
1251
|
+
.vx-table-th {
|
|
1252
|
+
font-weight: 600;
|
|
1253
|
+
}
|
|
1254
|
+
.vx-table-cell {
|
|
1255
|
+
padding: 8px 12px;
|
|
1256
|
+
}
|
|
1257
|
+
.vx-table-head {
|
|
1258
|
+
border-bottom-width: 1px;
|
|
1259
|
+
border-bottom-color: var(--color-border);
|
|
1260
|
+
}
|
|
1261
|
+
.vx-table-empty {
|
|
1262
|
+
padding: 16px;
|
|
1263
|
+
align-items: center;
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/* Timeline — dot + connector rail beside content. */
|
|
1267
|
+
.vx-timeline {
|
|
1268
|
+
flex-direction: column;
|
|
1269
|
+
}
|
|
1270
|
+
.vx-timeline-item {
|
|
1271
|
+
flex-direction: row;
|
|
1272
|
+
}
|
|
1273
|
+
.vx-timeline-rail {
|
|
1274
|
+
flex-direction: column;
|
|
1275
|
+
align-items: center;
|
|
1276
|
+
width: 20px;
|
|
1277
|
+
}
|
|
1278
|
+
.vx-timeline-dot {
|
|
1279
|
+
width: 10px;
|
|
1280
|
+
height: 10px;
|
|
1281
|
+
margin-top: 5px;
|
|
1282
|
+
border-radius: 50%;
|
|
1283
|
+
background-color: var(--color-primary);
|
|
1284
|
+
align-items: center;
|
|
1285
|
+
justify-content: center;
|
|
1286
|
+
}
|
|
1287
|
+
.vx-timeline-line {
|
|
1288
|
+
width: 1px;
|
|
1289
|
+
flex: 1;
|
|
1290
|
+
background-color: var(--color-border);
|
|
1291
|
+
}
|
|
1292
|
+
.vx-timeline-body {
|
|
173
1293
|
flex-direction: column;
|
|
174
|
-
|
|
1294
|
+
padding-left: 10px;
|
|
1295
|
+
padding-bottom: 16px;
|
|
175
1296
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
1297
|
+
.vx-timeline-time {
|
|
1298
|
+
font-size: 12px;
|
|
1299
|
+
line-height: 16px;
|
|
1300
|
+
color: var(--color-text-secondary);
|
|
180
1301
|
}
|
|
181
|
-
.vx-
|
|
182
|
-
|
|
1302
|
+
.vx-timeline-title {
|
|
1303
|
+
font-weight: 600;
|
|
183
1304
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
opacity: 0.85;
|
|
1305
|
+
.vx-timeline-desc {
|
|
1306
|
+
color: var(--color-text-secondary);
|
|
187
1307
|
}
|
|
188
1308
|
|
|
189
|
-
/*
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
z-index: 1000;
|
|
1309
|
+
/* Tree — indented collapsible rows. */
|
|
1310
|
+
.vx-tree {
|
|
1311
|
+
flex-direction: column;
|
|
193
1312
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
position: absolute;
|
|
197
|
-
inset: 0;
|
|
198
|
-
background-color: rgba(0, 0, 0, 0.4);
|
|
1313
|
+
.vx-tree-node {
|
|
1314
|
+
flex-direction: column;
|
|
199
1315
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
1316
|
+
.vx-tree-row {
|
|
1317
|
+
flex-direction: row;
|
|
1318
|
+
align-items: center;
|
|
1319
|
+
padding: 4px 0;
|
|
204
1320
|
}
|
|
205
|
-
|
|
206
|
-
.
|
|
207
|
-
z-index: 1001;
|
|
1321
|
+
.vx-tree-row--disabled {
|
|
1322
|
+
opacity: 0.5;
|
|
208
1323
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
1324
|
+
.vx-tree-caret {
|
|
1325
|
+
width: 14px;
|
|
1326
|
+
margin-left: 4px;
|
|
212
1327
|
}
|
|
213
1328
|
|
|
214
|
-
.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
1329
|
+
/* Alert — icon + body callout; tone picks border/text colors. */
|
|
1330
|
+
.vx-alert {
|
|
1331
|
+
flex-direction: row;
|
|
1332
|
+
padding: 10px 12px;
|
|
1333
|
+
border-width: 1px;
|
|
1334
|
+
border-radius: var(--radius-md);
|
|
1335
|
+
corner-shape: squircle;
|
|
1336
|
+
border-color: var(--color-border);
|
|
222
1337
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
1338
|
+
.vx-alert-body {
|
|
1339
|
+
flex-direction: column;
|
|
1340
|
+
flex: 1;
|
|
1341
|
+
margin-left: 8px;
|
|
226
1342
|
}
|
|
227
|
-
.vx-
|
|
228
|
-
|
|
1343
|
+
.vx-alert-title {
|
|
1344
|
+
font-weight: 600;
|
|
229
1345
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
pointer-events: auto;
|
|
1346
|
+
.vx-alert--error {
|
|
1347
|
+
border-color: var(--color-danger);
|
|
233
1348
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
1349
|
+
.vx-alert--warning {
|
|
1350
|
+
border-color: var(--color-warning, #d9a400);
|
|
1351
|
+
}
|
|
1352
|
+
.vx-alert--success {
|
|
1353
|
+
border-color: var(--color-success, #2e9e5b);
|
|
1354
|
+
}
|
|
1355
|
+
.vx-alert--info {
|
|
1356
|
+
border-color: var(--color-primary);
|
|
240
1357
|
}
|
|
241
|
-
/* xplat-web-only:end */
|
|
242
1358
|
|
|
243
|
-
/*
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
max-height: 90%;
|
|
250
|
-
padding: 24px;
|
|
251
|
-
border: 1px solid var(--color-border);
|
|
252
|
-
border-radius: var(--radius-xl);
|
|
1359
|
+
/* Card — sectioned container. */
|
|
1360
|
+
.vx-card {
|
|
1361
|
+
flex-direction: column;
|
|
1362
|
+
border-width: 1px;
|
|
1363
|
+
border-color: var(--color-border);
|
|
1364
|
+
border-radius: var(--radius-md);
|
|
253
1365
|
corner-shape: squircle;
|
|
254
|
-
color: var(--color-text);
|
|
255
1366
|
background-color: var(--color-surface);
|
|
256
1367
|
}
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
1368
|
+
.vx-card-header {
|
|
1369
|
+
padding: 12px;
|
|
1370
|
+
border-bottom-width: 1px;
|
|
1371
|
+
border-bottom-color: var(--color-border);
|
|
260
1372
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
1373
|
+
.vx-card-body {
|
|
1374
|
+
padding: 12px;
|
|
1375
|
+
flex-direction: column;
|
|
1376
|
+
}
|
|
1377
|
+
.vx-card-footer {
|
|
1378
|
+
padding: 12px;
|
|
1379
|
+
border-top-width: 1px;
|
|
1380
|
+
border-top-color: var(--color-border);
|
|
265
1381
|
}
|
|
266
1382
|
|
|
267
|
-
.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
border-
|
|
275
|
-
border-top-right-radius: var(--radius-xl);
|
|
1383
|
+
/* Chip — pressable pill with selected + remove states. */
|
|
1384
|
+
.vx-chip {
|
|
1385
|
+
flex-direction: row;
|
|
1386
|
+
align-items: center;
|
|
1387
|
+
padding: 3px 10px;
|
|
1388
|
+
border-width: 1px;
|
|
1389
|
+
border-color: var(--color-border);
|
|
1390
|
+
border-radius: var(--radius-md);
|
|
276
1391
|
corner-shape: squircle;
|
|
1392
|
+
font-size: 13px;
|
|
277
1393
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
1394
|
+
.vx-chip--on {
|
|
1395
|
+
background-color: var(--color-primary);
|
|
1396
|
+
border-color: var(--color-primary);
|
|
1397
|
+
color: var(--color-onprimary);
|
|
1398
|
+
}
|
|
1399
|
+
.vx-chip--disabled {
|
|
1400
|
+
opacity: 0.5;
|
|
1401
|
+
}
|
|
1402
|
+
.vx-chip-remove {
|
|
1403
|
+
margin-left: 6px;
|
|
286
1404
|
}
|
|
287
1405
|
|
|
288
|
-
/*
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
justify-content: stretch;
|
|
1406
|
+
/* Kbd — keycap glyph. */
|
|
1407
|
+
.vx-kbd {
|
|
1408
|
+
padding: 1px 5px;
|
|
1409
|
+
border-width: 1px;
|
|
1410
|
+
border-color: var(--color-border);
|
|
1411
|
+
border-bottom-width: 2px;
|
|
1412
|
+
border-radius: var(--radius-sm);
|
|
1413
|
+
font-size: 12px;
|
|
297
1414
|
}
|
|
298
1415
|
|
|
299
|
-
.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
padding:
|
|
304
|
-
|
|
305
|
-
|
|
1416
|
+
/* Empty — centered placeholder. */
|
|
1417
|
+
.vx-empty {
|
|
1418
|
+
flex-direction: column;
|
|
1419
|
+
align-items: center;
|
|
1420
|
+
padding: 24px;
|
|
1421
|
+
}
|
|
1422
|
+
.vx-empty-title {
|
|
1423
|
+
font-weight: 600;
|
|
1424
|
+
margin-top: 8px;
|
|
1425
|
+
}
|
|
1426
|
+
.vx-empty-desc {
|
|
1427
|
+
color: var(--color-text-secondary);
|
|
1428
|
+
margin-top: 2px;
|
|
306
1429
|
}
|
|
307
1430
|
|
|
308
|
-
.
|
|
309
|
-
|
|
310
|
-
flex:
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
1431
|
+
/* Banner — notice strip. */
|
|
1432
|
+
.vx-banner {
|
|
1433
|
+
flex-direction: row;
|
|
1434
|
+
align-items: center;
|
|
1435
|
+
padding: 8px 12px;
|
|
1436
|
+
border-width: 1px;
|
|
1437
|
+
border-color: var(--color-border);
|
|
1438
|
+
border-radius: var(--radius-md);
|
|
314
1439
|
background-color: var(--color-surface);
|
|
315
1440
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
a typed value); --placeholder-color is the per-field prop escape. */
|
|
321
|
-
input::placeholder,
|
|
322
|
-
textarea::placeholder {
|
|
323
|
-
color: var(--placeholder-color, var(--color-text-secondary));
|
|
1441
|
+
.vx-banner-body {
|
|
1442
|
+
flex-direction: column;
|
|
1443
|
+
flex: 1;
|
|
1444
|
+
margin-left: 8px;
|
|
324
1445
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
/* xplat-web-only:start — form controls don't inherit the body font in the
|
|
328
|
-
DOM (UA stylesheet wins); without this they render in the UA face. */
|
|
329
|
-
input,
|
|
330
|
-
textarea,
|
|
331
|
-
select,
|
|
332
|
-
button {
|
|
333
|
-
font-family: inherit;
|
|
1446
|
+
.vx-banner-dismiss {
|
|
1447
|
+
margin-left: 8px;
|
|
334
1448
|
}
|
|
335
|
-
/* xplat-web-only:end */
|
|
336
1449
|
|
|
337
|
-
/*
|
|
338
|
-
.vx-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
1450
|
+
/* User — avatar + text column. */
|
|
1451
|
+
.vx-user {
|
|
1452
|
+
flex-direction: row;
|
|
1453
|
+
align-items: center;
|
|
1454
|
+
}
|
|
1455
|
+
.vx-user-body {
|
|
1456
|
+
flex-direction: column;
|
|
1457
|
+
margin-left: 10px;
|
|
1458
|
+
}
|
|
1459
|
+
.vx-user-name {
|
|
1460
|
+
font-weight: 600;
|
|
1461
|
+
}
|
|
1462
|
+
.vx-user-desc {
|
|
1463
|
+
font-size: 12px;
|
|
1464
|
+
line-height: 16px;
|
|
1465
|
+
color: var(--color-text-secondary);
|
|
347
1466
|
}
|
|
348
1467
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
1468
|
+
/* ProgressGroup — stacked labeled meters. */
|
|
1469
|
+
.vx-progressgroup {
|
|
1470
|
+
flex-direction: column;
|
|
1471
|
+
}
|
|
1472
|
+
.vx-progressgroup-row {
|
|
1473
|
+
flex-direction: row;
|
|
1474
|
+
align-items: center;
|
|
1475
|
+
}
|
|
1476
|
+
.vx-progressgroup-label {
|
|
1477
|
+
margin-left: 8px;
|
|
1478
|
+
}
|
|
1479
|
+
/* xplat-web-only:start — display:flex for the div-based flex classes */
|
|
1480
|
+
.vx-table,
|
|
1481
|
+
.vx-table-head,
|
|
1482
|
+
.vx-table-row,
|
|
1483
|
+
.vx-timeline,
|
|
1484
|
+
.vx-timeline-item,
|
|
1485
|
+
.vx-timeline-rail,
|
|
1486
|
+
.vx-timeline-body,
|
|
1487
|
+
.vx-tree,
|
|
1488
|
+
.vx-tree-node,
|
|
1489
|
+
.vx-tree-row,
|
|
1490
|
+
.vx-alert,
|
|
1491
|
+
.vx-alert-body,
|
|
1492
|
+
.vx-card,
|
|
1493
|
+
.vx-card-body,
|
|
1494
|
+
.vx-banner,
|
|
1495
|
+
.vx-banner-body,
|
|
1496
|
+
.vx-user,
|
|
1497
|
+
.vx-user-body,
|
|
1498
|
+
.vx-progressgroup,
|
|
1499
|
+
.vx-progressgroup-row {
|
|
1500
|
+
display: flex;
|
|
1501
|
+
}
|
|
1502
|
+
.vx-table-row--pressable,
|
|
1503
|
+
.vx-tree-row,
|
|
1504
|
+
.vx-user--pressable,
|
|
1505
|
+
.vx-banner-dismiss,
|
|
1506
|
+
.vx-chip-remove {
|
|
1507
|
+
cursor: pointer;
|
|
353
1508
|
}
|
|
354
1509
|
/* xplat-web-only:end */
|
|
355
1510
|
|
|
@@ -378,35 +1533,6 @@ button {
|
|
|
378
1533
|
font-weight: bold;
|
|
379
1534
|
}
|
|
380
1535
|
|
|
381
|
-
/* xplat-web-only:start — glass material is real on iOS 26+; web approximates
|
|
382
|
-
with backdrop-filter. The class also lands on native elements (inert) so
|
|
383
|
-
apps can style their own fallback — but these rules are DOM-only. */
|
|
384
|
-
.vx-glass {
|
|
385
|
-
background-color: color-mix(in srgb, var(--color-surface) 30%, transparent);
|
|
386
|
-
border: 1px solid rgba(255, 255, 255, 0.25);
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
390
|
-
.vx-glass {
|
|
391
|
-
background-color: color-mix(in srgb, var(--color-surface) 20%, transparent);
|
|
392
|
-
-webkit-backdrop-filter: blur(20px) saturate(1.6);
|
|
393
|
-
backdrop-filter: blur(20px) saturate(1.6);
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
.vx-glass--clear {
|
|
398
|
-
background-color: color-mix(in srgb, var(--color-surface) 12%, transparent);
|
|
399
|
-
border-color: rgba(255, 255, 255, 0.15);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
|
|
403
|
-
.vx-glass--clear {
|
|
404
|
-
-webkit-backdrop-filter: blur(8px) saturate(1.3);
|
|
405
|
-
backdrop-filter: blur(8px) saturate(1.3);
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
/* xplat-web-only:end */
|
|
409
|
-
|
|
410
1536
|
/* utilities (hand-written subset — do NOT adopt Tailwind until
|
|
411
1537
|
NativeScript/tailwind#226 is resolved; the plugin strips core-supported
|
|
412
1538
|
props incl. gap, drops all @media, and rewrites invisible→collapse) */
|
|
@@ -420,14 +1546,19 @@ button {
|
|
|
420
1546
|
/* Flex divergence guards — NS FlexboxLayout diverges from web flexbox on
|
|
421
1547
|
* shrinkability: grow children never shrink below intrinsic width, fixed
|
|
422
1548
|
* children get crushed, and auto-height rows re-measure grow children at
|
|
423
|
-
* zero height.
|
|
424
|
-
*
|
|
1549
|
+
* zero height. The shared `* { flex-shrink: 0 }` default (RN semantics)
|
|
1550
|
+
* makes .shrink the opt-in for a shrinkable child; min-w-0/min-h-0 lower
|
|
1551
|
+
* the min-content floor so it can actually shrink, and shrink-0 remains
|
|
1552
|
+
* for local overrides. All four are plain CSS on web. */
|
|
425
1553
|
.min-w-0 {
|
|
426
1554
|
min-width: 0;
|
|
427
1555
|
}
|
|
428
1556
|
.min-h-0 {
|
|
429
1557
|
min-height: 0;
|
|
430
1558
|
}
|
|
1559
|
+
.shrink {
|
|
1560
|
+
flex-shrink: 1;
|
|
1561
|
+
}
|
|
431
1562
|
.shrink-0 {
|
|
432
1563
|
flex-shrink: 0;
|
|
433
1564
|
}
|
|
@@ -462,17 +1593,25 @@ button {
|
|
|
462
1593
|
gap: 24px;
|
|
463
1594
|
}
|
|
464
1595
|
|
|
1596
|
+
/* line-height is REQUIRED on native: without it a Label's measured height
|
|
1597
|
+
misses the font's line metrics, and Android clips the descenders/bottom
|
|
1598
|
+
of the glyphs (observed: section-labels 21–29px bounds for 12sp text at
|
|
1599
|
+
3.25x). Tailwind pairs every text-* size with a leading, same here. */
|
|
465
1600
|
.text-2xl {
|
|
466
1601
|
font-size: 28px;
|
|
1602
|
+
line-height: 36px;
|
|
467
1603
|
}
|
|
468
1604
|
.text-xl {
|
|
469
1605
|
font-size: 20px;
|
|
1606
|
+
line-height: 28px;
|
|
470
1607
|
}
|
|
471
1608
|
.text-lg {
|
|
472
1609
|
font-size: 18px;
|
|
1610
|
+
line-height: 28px;
|
|
473
1611
|
}
|
|
474
1612
|
.text-sm {
|
|
475
1613
|
font-size: 13px;
|
|
1614
|
+
line-height: 20px;
|
|
476
1615
|
}
|
|
477
1616
|
.font-bold {
|
|
478
1617
|
font-weight: bold;
|
|
@@ -581,6 +1720,9 @@ a.chip {
|
|
|
581
1720
|
.vx-tab.active {
|
|
582
1721
|
color: var(--color-text);
|
|
583
1722
|
}
|
|
1723
|
+
.vx-tabicon {
|
|
1724
|
+
margin-right: 6px;
|
|
1725
|
+
}
|
|
584
1726
|
|
|
585
1727
|
/* xplat-web-only:start — DOM defaults are display:block (div) and
|
|
586
1728
|
inline-block (button); every flex-bearing vx- class needs an explicit
|
|
@@ -689,10 +1831,6 @@ button.vx-tab {
|
|
|
689
1831
|
border-bottom-color: var(--color-border);
|
|
690
1832
|
}
|
|
691
1833
|
|
|
692
|
-
.vx-list {
|
|
693
|
-
flex-grow: 1;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
1834
|
.gap-2 {
|
|
697
1835
|
gap: 8px;
|
|
698
1836
|
}
|
|
@@ -700,27 +1838,16 @@ button.vx-tab {
|
|
|
700
1838
|
/* In-window sheet — bottom-anchored panel (matches the native RootLayout
|
|
701
1839
|
sheet). Layer is pointer-events:none; backdrop + panel re-enable. */
|
|
702
1840
|
.vx-sheet-layer {
|
|
703
|
-
position: fixed;
|
|
704
|
-
inset: 0;
|
|
705
1841
|
z-index: 1100;
|
|
706
|
-
pointer-events: none;
|
|
707
1842
|
}
|
|
708
1843
|
|
|
709
1844
|
.vx-sheet-backdrop {
|
|
710
|
-
position: absolute;
|
|
711
|
-
inset: 0;
|
|
712
1845
|
background: rgba(0, 0, 0, 0.4);
|
|
713
|
-
pointer-events: auto;
|
|
714
1846
|
}
|
|
715
1847
|
|
|
716
1848
|
.vx-sheet {
|
|
717
|
-
position: absolute;
|
|
718
|
-
left: 0;
|
|
719
|
-
right: 0;
|
|
720
|
-
bottom: 0;
|
|
721
1849
|
max-height: 85%;
|
|
722
1850
|
padding: 24px;
|
|
723
|
-
overflow: auto;
|
|
724
1851
|
border-width: 1px;
|
|
725
1852
|
border-color: var(--color-border);
|
|
726
1853
|
border-top-left-radius: var(--radius-xl);
|
|
@@ -728,5 +1855,58 @@ button.vx-tab {
|
|
|
728
1855
|
corner-shape: squircle;
|
|
729
1856
|
background-color: var(--color-surface);
|
|
730
1857
|
color: var(--color-text);
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
/* xplat-web-only:start — DOM positioning + hit-testing for the sheet.
|
|
1861
|
+
The native leaf renders on RootLayout with its own geometry. */
|
|
1862
|
+
.vx-sheet-layer {
|
|
1863
|
+
position: fixed;
|
|
1864
|
+
inset: 0;
|
|
1865
|
+
pointer-events: none;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
.vx-sheet-backdrop,
|
|
1869
|
+
.vx-sheet {
|
|
1870
|
+
position: absolute;
|
|
1871
|
+
inset: 0;
|
|
731
1872
|
pointer-events: auto;
|
|
732
1873
|
}
|
|
1874
|
+
|
|
1875
|
+
.vx-sheet {
|
|
1876
|
+
top: auto;
|
|
1877
|
+
bottom: 0;
|
|
1878
|
+
overflow: auto;
|
|
1879
|
+
}
|
|
1880
|
+
/* xplat-web-only:end */
|
|
1881
|
+
|
|
1882
|
+
.vx-sheet-grabber {
|
|
1883
|
+
display: flex;
|
|
1884
|
+
align-items: center;
|
|
1885
|
+
justify-content: center;
|
|
1886
|
+
height: 28px;
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
.vx-sheet-grip {
|
|
1890
|
+
width: 36px;
|
|
1891
|
+
height: 4px;
|
|
1892
|
+
border-radius: 999px;
|
|
1893
|
+
background-color: var(--color-text-secondary);
|
|
1894
|
+
opacity: 0.4;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
/* xplat-web-only:start — detents size the panel to the largest fraction
|
|
1898
|
+
(overriding the 85% cap) and overlay the grabber; native stacks it as a
|
|
1899
|
+
top-aligned grid child. touch-action keeps drags off native scroll. */
|
|
1900
|
+
.vx-sheet-detents {
|
|
1901
|
+
max-height: none;
|
|
1902
|
+
}
|
|
1903
|
+
.vx-sheet-detents > .vx-sheet-grabber {
|
|
1904
|
+
position: absolute;
|
|
1905
|
+
top: 0;
|
|
1906
|
+
left: 0;
|
|
1907
|
+
right: 0;
|
|
1908
|
+
z-index: 2;
|
|
1909
|
+
cursor: grab;
|
|
1910
|
+
touch-action: none;
|
|
1911
|
+
}
|
|
1912
|
+
/* xplat-web-only:end */
|