create-lupine 1.0.17 → 1.0.18
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/package.json
CHANGED
|
@@ -563,3 +563,31 @@ For interactive lists, `createDragUtil()` from `lupine.components` handles compl
|
|
|
563
563
|
- `ActionSheetMultiSelectPromise`: For multiple checkbox selections.
|
|
564
564
|
- `ActionSheetTimePicker`: For selecting a time.
|
|
565
565
|
- `ActionSheetDatePicker`: For selecting a date.
|
|
566
|
+
|
|
567
|
+
### F. Hardware Back Button Handling (`data-back-action`)
|
|
568
|
+
|
|
569
|
+
When building mobile interfaces, users expect the physical hardware "Back" button (or swipe-from-edge gesture) to gracefully dismiss overlays, dialogs, sliders, or menus—similar to pressing the `ESC` key on a desktop.
|
|
570
|
+
|
|
571
|
+
**The Rule**: Whenever you implement a cancel button, a close icon (`X`), or a back chevron (`<`) in a mobile overlay or frame, you **MUST** attach the `data-back-action` attribute using the `backActionHelper`.
|
|
572
|
+
|
|
573
|
+
```typescript
|
|
574
|
+
import { backActionHelper } from 'lupine.components';
|
|
575
|
+
|
|
576
|
+
export const MyCloseButton = ({ onClose }) => {
|
|
577
|
+
return (
|
|
578
|
+
<i
|
|
579
|
+
class="ifc-icon ma-close"
|
|
580
|
+
// Generate a unique ID for the back stack
|
|
581
|
+
data-back-action={backActionHelper.genBackActionId()}
|
|
582
|
+
onClick={onClose}
|
|
583
|
+
></i>
|
|
584
|
+
);
|
|
585
|
+
};
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
**How it works**:
|
|
589
|
+
- When the hardware back button is pressed, the underlying system automatically queries the DOM for all elements with `[data-back-action^="bb-"]`.
|
|
590
|
+
- It finds the most recently created component (the top-most overlay) and automatically triggers a `.click()` event on it.
|
|
591
|
+
- **Dynamic Mounting vs Static**:
|
|
592
|
+
- For components that are injected and removed dynamically (like `<ActionSheet />` or `<FloatWindow />`), simply attaching the property to the React/JSX node is sufficient.
|
|
593
|
+
- For static components that always remain in the DOM but toggle visibility (like an off-canvas sidebar), you must dynamically add/remove the attribute in Javascript (`el.setAttribute` / `el.removeAttribute`) to prevent the back button from intercepting events when the menu is actually closed.
|
package/templates/lupine-template-responsive-starter/web/src/frames/app-responsive-frame.tsx
CHANGED
|
@@ -9,12 +9,18 @@ const getSiteFooter = async () => '© 2026 My Note App';
|
|
|
9
9
|
// 'sidemenu' | 'tabs', this will be replaced by create-lupine
|
|
10
10
|
const DEFAULT_LAYOUT = 'tabs';
|
|
11
11
|
export const AppResponsiveFrame = async (placeholderClassname: string, vnode: VNode<any>) => {
|
|
12
|
+
// special login for github pages
|
|
13
|
+
let subDir = '';
|
|
14
|
+
if (typeof window !== 'undefined' && window.location.hostname === 'uuware.github.io') {
|
|
15
|
+
// first section is subDir
|
|
16
|
+
subDir = '/' + window.location.pathname.split('/')[1];
|
|
17
|
+
}
|
|
12
18
|
const mobileBottomMenu = [
|
|
13
|
-
{ icon: 'ma-home-outline', url: '/', text: 'Notes' },
|
|
14
|
-
{ icon: 'icon-finance', url: '/finance', text: 'Finance' },
|
|
15
|
-
{ icon: 'ma-book-outline', url: '/about', text: 'About', topout: true },
|
|
16
|
-
{ icon: 'ma-tools', url: '/tools', text: 'Tools' },
|
|
17
|
-
{ icon: 'ma-account-cog-outline', url: '/mine', text: 'Mine' },
|
|
19
|
+
{ icon: 'ma-home-outline', url: subDir + '/', text: 'Notes' },
|
|
20
|
+
{ icon: 'icon-finance', url: subDir + '/finance', text: 'Finance' },
|
|
21
|
+
{ icon: 'ma-book-outline', url: subDir + '/about', text: 'About', topout: true },
|
|
22
|
+
{ icon: 'ma-tools', url: subDir + '/tools', text: 'Tools' },
|
|
23
|
+
{ icon: 'ma-account-cog-outline', url: subDir + '/mine', text: 'Mine' },
|
|
18
24
|
];
|
|
19
25
|
|
|
20
26
|
const layout: 'sidemenu' | 'tabs' = (localStorage.getItem('app-layout') as any) || DEFAULT_LAYOUT;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<title><!--META-TITLE--></title>
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover, user-scalable=no" />
|
|
7
7
|
<!--META-ENV-START-->
|
|
8
8
|
<!--META-ENV-END-->
|
|
9
9
|
<link rel="shortcut icon" href="{SUBDIR}/assets/favicon.ico?t={hash}" type="image/x-icon" />
|