@stackflow/plugin-basic-ui 0.21.1 → 0.21.3-alpha.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.
@@ -7,7 +7,7 @@ import { useGlobalOptions } from "../basicUIPlugin";
7
7
  import { useMaxWidth, useNullableActivity } from "../hooks";
8
8
  import type { GlobalVars } from "../theme.css";
9
9
  import { globalVars } from "../theme.css";
10
- import { compactMap, noop } from "../utils";
10
+ import { compactMap } from "../utils";
11
11
  import * as css from "./AppBar.css";
12
12
  import * as appScreenCss from "./AppScreen.css";
13
13
 
@@ -46,6 +46,7 @@ type AppBarProps = Partial<
46
46
  };
47
47
  closeButtonLocation?: "left" | "right";
48
48
  border?: boolean;
49
+ modalPresentationStyle?: "fullScreen";
49
50
  onTopClick?: (e: React.MouseEvent) => void;
50
51
  };
51
52
  const AppBar = React.forwardRef<HTMLDivElement, AppBarProps>(
@@ -58,6 +59,7 @@ const AppBar = React.forwardRef<HTMLDivElement, AppBarProps>(
58
59
  closeButton,
59
60
  closeButtonLocation = "left",
60
61
  border = true,
62
+ modalPresentationStyle,
61
63
  iconColor,
62
64
  textColor,
63
65
  borderColor,
@@ -83,6 +85,8 @@ const AppBar = React.forwardRef<HTMLDivElement, AppBarProps>(
83
85
  enable: globalOptions.theme === "cupertino",
84
86
  });
85
87
 
88
+ const presentModalFullScreen = modalPresentationStyle === "fullScreen";
89
+
86
90
  const onBackClick = (e: React.MouseEvent<HTMLButtonElement>) => {
87
91
  if (backButton && "onClick" in backButton && backButton.onClick) {
88
92
  backButton.onClick(e);
@@ -153,6 +157,10 @@ const AppBar = React.forwardRef<HTMLDivElement, AppBarProps>(
153
157
  return globalBackButton.renderIcon();
154
158
  }
155
159
 
160
+ if (presentModalFullScreen) {
161
+ return <IconClose />;
162
+ }
163
+
156
164
  return <IconBack />;
157
165
  })()}
158
166
  </button>
@@ -176,7 +184,20 @@ const AppBar = React.forwardRef<HTMLDivElement, AppBarProps>(
176
184
  const renderCloseButton = () => {
177
185
  const isRoot = !activity || activity.isRoot;
178
186
 
179
- if ((!closeButton && !globalOptions.appBar?.closeButton) || !isRoot) {
187
+ const showCloseButton = (closeButton: AppBarProps["closeButton"]) =>
188
+ (closeButton && "render" in closeButton && closeButton.render) ||
189
+ (closeButton &&
190
+ "renderIcon" in closeButton &&
191
+ closeButton.renderIcon) ||
192
+ (closeButton && "onClick" in closeButton && closeButton.onClick);
193
+
194
+ if (
195
+ !(
196
+ showCloseButton(closeButton) ||
197
+ showCloseButton(globalOptions.appBar?.closeButton)
198
+ ) ||
199
+ !isRoot
200
+ ) {
180
201
  return null;
181
202
  }
182
203
  if (closeButton && "render" in closeButton && closeButton.render) {
@@ -236,6 +257,7 @@ const AppBar = React.forwardRef<HTMLDivElement, AppBarProps>(
236
257
  ref={ref}
237
258
  className={css.appBar({
238
259
  border,
260
+ presentModalFullScreen,
239
261
  })}
240
262
  style={assignInlineVars(
241
263
  compactMap({
@@ -65,20 +65,23 @@ export const dim = style([
65
65
  zIndex: vars.zIndexes.dim,
66
66
  willChange: "opacity",
67
67
  selectors: {
68
- [`${android} &, ${rootAndroid} &`]: {
68
+ [`
69
+ ${android} &,
70
+ ${rootAndroid} &
71
+ `]: {
69
72
  height: "10rem",
70
73
  background: `linear-gradient(${globalVars.dimBackgroundColor}, rgba(0, 0, 0, 0))`,
71
74
  },
72
- [`${enterActive} &`]: {
75
+ [`
76
+ ${enterActive} &,
77
+ ${enterDone} &
78
+ `]: {
73
79
  opacity: 1,
74
80
  },
75
- [`${enterDone} &`]: {
76
- opacity: 1,
77
- },
78
- [`${exitActive} &`]: {
79
- opacity: 0,
80
- },
81
- [`${exitDone} &`]: {
81
+ [`
82
+ ${exitActive} &,
83
+ ${exitDone} &
84
+ `]: {
82
85
  opacity: 0,
83
86
  },
84
87
  },
@@ -99,24 +102,33 @@ export const paper = recipe({
99
102
  zIndex: vars.zIndexes.paper,
100
103
  willChange: "transform",
101
104
  selectors: {
102
- [`${cupertino} &, ${rootCupertino} &`]: {
105
+ [`
106
+ ${cupertino} &,
107
+ ${rootCupertino} &
108
+ `]: {
103
109
  transform: "translate3d(100%, 0, 0)",
104
110
  },
105
- [`${cupertino} ${enterActive} &, ${rootCupertino} ${enterActive} &`]: {
111
+ [`
112
+ ${cupertino} ${enterActive} &,
113
+ ${rootCupertino} ${enterActive} &,
114
+ ${cupertino} ${enterDone} &,
115
+ ${rootCupertino} ${enterDone} &
116
+ `]: {
106
117
  transform: "translate3d(0, 0, 0)",
107
118
  },
108
- [`${cupertino} ${enterDone} &, ${rootCupertino} ${enterDone} &`]: {
109
- transform: "translate3d(0, 0, 0)",
110
- },
111
- [`${android} &, ${rootAndroid} &`]: {
119
+ [`
120
+ ${android} &,
121
+ ${rootAndroid} &
122
+ `]: {
112
123
  opacity: 0,
113
124
  transform: "translate3d(0, 10rem, 0)",
114
125
  },
115
- [`${android} ${enterActive} &, ${rootAndroid} ${enterActive} &`]: {
116
- opacity: 1,
117
- transform: "translate3d(0, 0, 0)",
118
- },
119
- [`${android} ${enterDone} &, ${rootAndroid} ${enterDone} &`]: {
126
+ [`
127
+ ${android} ${enterActive} &,
128
+ ${rootAndroid} ${enterActive} &,
129
+ ${android} ${enterDone} &,
130
+ ${rootAndroid} ${enterDone} &
131
+ `]: {
120
132
  opacity: 1,
121
133
  transform: "translate3d(0, 0, 0)",
122
134
  },
@@ -136,6 +148,18 @@ export const paper = recipe({
136
148
  },
137
149
  ],
138
150
  },
151
+ presentModalFullScreen: {
152
+ true: {
153
+ selectors: {
154
+ [`
155
+ ${cupertino} &,
156
+ ${rootCupertino} &
157
+ `]: {
158
+ transform: "translate3d(0, 100%, 0)",
159
+ },
160
+ },
161
+ },
162
+ },
139
163
  },
140
164
  });
141
165
 
@@ -33,6 +33,7 @@ export type AppScreenProps = Partial<
33
33
  > & {
34
34
  appBar?: Omit<PropOf<typeof AppBar>, "theme" | "ref" | "key">;
35
35
  preventSwipeBack?: boolean;
36
+ modalPresentationStyle?: "fullScreen";
36
37
  children: React.ReactNode;
37
38
  };
38
39
  const AppScreen: React.FC<AppScreenProps> = ({
@@ -40,10 +41,12 @@ const AppScreen: React.FC<AppScreenProps> = ({
40
41
  dimBackgroundColor,
41
42
  appBar,
42
43
  preventSwipeBack,
44
+ modalPresentationStyle,
43
45
  children,
44
46
  }) => {
45
47
  const globalOptions = useGlobalOptions();
46
48
  const activity = useNullableActivity();
49
+
47
50
  const { pop } = useActions();
48
51
 
49
52
  const appScreenRef = useRef<HTMLDivElement>(null);
@@ -52,6 +55,9 @@ const AppScreen: React.FC<AppScreenProps> = ({
52
55
  const edgeRef = useRef<HTMLDivElement>(null);
53
56
  const appBarRef = useRef<HTMLDivElement>(null);
54
57
 
58
+ const presentModalFullScreen = modalPresentationStyle === "fullScreen";
59
+ const swipeBackPrevented = preventSwipeBack || presentModalFullScreen;
60
+
55
61
  useStyleEffectHide({
56
62
  refs: [appScreenRef],
57
63
  hasEffect: true,
@@ -60,7 +66,7 @@ const AppScreen: React.FC<AppScreenProps> = ({
60
66
  theme: globalOptions.theme,
61
67
  refs:
62
68
  globalOptions.theme === "cupertino" ? [paperRef] : [paperRef, appBarRef],
63
- hasEffect: true,
69
+ hasEffect: !presentModalFullScreen,
64
70
  });
65
71
  useStyleEffectSwipeBack({
66
72
  theme: globalOptions.theme,
@@ -68,7 +74,7 @@ const AppScreen: React.FC<AppScreenProps> = ({
68
74
  edgeRef,
69
75
  paperRef,
70
76
  hasEffect: true,
71
- preventSwipeBack,
77
+ prevented: swipeBackPrevented,
72
78
  onSwiped() {
73
79
  pop();
74
80
  },
@@ -81,7 +87,8 @@ const AppScreen: React.FC<AppScreenProps> = ({
81
87
  const zIndexPaper =
82
88
  zIndexBase + (globalOptions.theme === "cupertino" && hasAppBar ? 1 : 3);
83
89
  const zIndexEdge = zIndexBase + 4;
84
- const zIndexAppBar = zIndexBase + 7;
90
+ const zIndexAppBar =
91
+ globalOptions.theme === "cupertino" ? zIndexBase + 7 : zIndexBase + 4;
85
92
 
86
93
  const transitionState = activity?.transitionState ?? "enter-done";
87
94
  const lazyTransitionState = useLazy(transitionState);
@@ -140,12 +147,18 @@ const AppScreen: React.FC<AppScreenProps> = ({
140
147
  >
141
148
  <div className={css.dim} ref={dimRef} />
142
149
  {appBar && (
143
- <AppBar {...appBar} ref={appBarRef} onTopClick={onAppBarTopClick} />
150
+ <AppBar
151
+ {...appBar}
152
+ ref={appBarRef}
153
+ modalPresentationStyle={modalPresentationStyle}
154
+ onTopClick={onAppBarTopClick}
155
+ />
144
156
  )}
145
157
  <div
146
158
  key={activity?.id}
147
159
  className={css.paper({
148
160
  hasAppBar,
161
+ presentModalFullScreen,
149
162
  })}
150
163
  ref={paperRef}
151
164
  >
@@ -153,7 +166,7 @@ const AppScreen: React.FC<AppScreenProps> = ({
153
166
  </div>
154
167
  {!activity?.isRoot &&
155
168
  globalOptions.theme === "cupertino" &&
156
- !preventSwipeBack && (
169
+ !swipeBackPrevented && (
157
170
  <div className={css.edge({ hasAppBar })} ref={edgeRef} />
158
171
  )}
159
172
  </div>
@@ -10,7 +10,7 @@ export function useStyleEffectSwipeBack({
10
10
  edgeRef,
11
11
  paperRef,
12
12
  hasEffect,
13
- preventSwipeBack,
13
+ prevented,
14
14
  onSwiped,
15
15
  }: {
16
16
  theme: "android" | "cupertino";
@@ -18,7 +18,7 @@ export function useStyleEffectSwipeBack({
18
18
  edgeRef: React.RefObject<HTMLDivElement>;
19
19
  paperRef: React.RefObject<HTMLDivElement>;
20
20
  hasEffect?: boolean;
21
- preventSwipeBack?: boolean;
21
+ prevented?: boolean;
22
22
  onSwiped?: () => void;
23
23
  }) {
24
24
  useStyleEffect({
@@ -238,6 +238,6 @@ export function useStyleEffectSwipeBack({
238
238
  };
239
239
  }
240
240
  : undefined,
241
- effectDeps: [preventSwipeBack],
241
+ effectDeps: [prevented],
242
242
  });
243
243
  }