nativescript-web-adapter 0.1.5 → 0.1.6
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 +32 -14
- package/angular/components/absolute-layout.component.ts +18 -0
- package/angular/components/action-bar.component.ts +16 -0
- package/angular/components/action-item.component.ts +22 -0
- package/angular/components/activity-indicator.component.ts +32 -0
- package/angular/components/button.component.ts +45 -0
- package/angular/components/date-picker.component.ts +35 -0
- package/angular/components/directives/absolute-position.directive.ts +31 -0
- package/angular/components/directives/grid-position.directive.ts +43 -0
- package/angular/components/dock-layout.component.ts +46 -0
- package/angular/components/flexbox-layout.component.ts +16 -0
- package/angular/components/frame.component.ts +9 -0
- package/angular/components/grid-layout.component.ts +48 -0
- package/angular/components/html-view.component.ts +23 -0
- package/angular/components/image-cache-it.component.ts +21 -0
- package/angular/components/image.component.ts +22 -0
- package/angular/components/index.ts +156 -0
- package/angular/components/label.component.ts +27 -0
- package/angular/components/list-picker.component.ts +33 -0
- package/angular/components/list-view.component.ts +22 -0
- package/angular/components/navigation-button.component.ts +36 -0
- package/angular/components/page.component.ts +21 -0
- package/angular/components/placeholder.component.ts +16 -0
- package/angular/components/progress.component.ts +20 -0
- package/angular/components/root-layout.component.ts +19 -0
- package/angular/components/scroll-view.component.ts +17 -0
- package/angular/components/search-bar.component.ts +34 -0
- package/angular/components/segmented-bar-item.component.ts +27 -0
- package/angular/components/segmented-bar.component.ts +101 -0
- package/angular/components/slider.component.ts +41 -0
- package/angular/components/stack-layout.component.ts +17 -0
- package/angular/components/switch.component.ts +62 -0
- package/angular/components/tab-view-item.component.ts +27 -0
- package/angular/components/tab-view.component.ts +89 -0
- package/angular/components/text-field.component.ts +38 -0
- package/angular/components/text-view.component.ts +29 -0
- package/angular/components/time-picker.component.ts +27 -0
- package/angular/components/web-view.component.ts +25 -0
- package/angular/components/wrap-layout.component.ts +17 -0
- package/angular/composables/dialogs.ts +54 -0
- package/angular/composables/index.ts +6 -0
- package/angular/composables/ref.ts +8 -0
- package/angular/composables/useActionBar.ts +20 -0
- package/angular/composables/useFrame.ts +26 -0
- package/angular/composables/usePage.ts +26 -0
- package/angular/index.ts +8 -0
- package/core/components/Button.vue +2 -2
- package/core/components/GridLayout.vue +2 -2
- package/core/components/HtmlView.vue +2 -2
- package/core/components/Image.vue +2 -2
- package/core/components/ImageCacheIt.vue +2 -2
- package/core/components/Label.vue +2 -2
- package/core/components/ListPicker.vue +2 -2
- package/core/components/NavigationButton.vue +2 -2
- package/core/components/Progress.vue +2 -2
- package/core/components/SearchBar.vue +2 -2
- package/core/components/Slider.vue +2 -2
- package/core/components/Switch.vue +2 -2
- package/core/components/TextField.vue +2 -2
- package/core/components/TextView.vue +2 -2
- package/core/components/WebView.vue +2 -2
- package/core/composables/dialogs.ts +5 -5
- package/dist/nativescript-web-adapter.es.js +22375 -45
- package/dist/nativescript-web-adapter.umd.js +534 -1
- package/package.json +37 -7
- package/tools/cli.cjs +17 -4
- package/tools/create-web-platform.cjs +40 -18
- package/tools/modules/appPatch.cjs +125 -1
- package/tools/modules/templates.cjs +161 -84
- package/tools/modules/transform.cjs +69 -2
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import {
|
|
3
|
+
AfterContentInit,
|
|
4
|
+
ChangeDetectionStrategy,
|
|
5
|
+
Component,
|
|
6
|
+
ContentChildren,
|
|
7
|
+
Input,
|
|
8
|
+
QueryList,
|
|
9
|
+
} from '@angular/core';
|
|
10
|
+
import { TabViewItemComponent } from './tab-view-item.component';
|
|
11
|
+
|
|
12
|
+
@Component({
|
|
13
|
+
selector: 'TabView, tabview',
|
|
14
|
+
standalone: true,
|
|
15
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
16
|
+
imports: [CommonModule],
|
|
17
|
+
template: `
|
|
18
|
+
<div class="ns-tabview">
|
|
19
|
+
<div class="ns-tabview-header">
|
|
20
|
+
<button
|
|
21
|
+
*ngFor="let title of items; let i = index"
|
|
22
|
+
class="ns-tabview-tab"
|
|
23
|
+
[class.active]="i === currentIndex"
|
|
24
|
+
(click)="select(i)"
|
|
25
|
+
>
|
|
26
|
+
{{ title }}
|
|
27
|
+
</button>
|
|
28
|
+
</div>
|
|
29
|
+
<div class="ns-tabview-body"><ng-content></ng-content></div>
|
|
30
|
+
</div>
|
|
31
|
+
`,
|
|
32
|
+
styles: [
|
|
33
|
+
`
|
|
34
|
+
.ns-tabview {
|
|
35
|
+
display: block;
|
|
36
|
+
}
|
|
37
|
+
.ns-tabview-header {
|
|
38
|
+
display: flex;
|
|
39
|
+
gap: 8px;
|
|
40
|
+
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
|
41
|
+
padding-bottom: 8px;
|
|
42
|
+
}
|
|
43
|
+
.ns-tabview-tab {
|
|
44
|
+
background: transparent;
|
|
45
|
+
border: none;
|
|
46
|
+
color: inherit;
|
|
47
|
+
padding: 8px 12px;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
opacity: 0.7;
|
|
50
|
+
}
|
|
51
|
+
.ns-tabview-tab.active {
|
|
52
|
+
opacity: 1;
|
|
53
|
+
border-bottom: 2px solid currentColor;
|
|
54
|
+
}
|
|
55
|
+
.ns-tabview-body {
|
|
56
|
+
padding-top: 12px;
|
|
57
|
+
}
|
|
58
|
+
`,
|
|
59
|
+
],
|
|
60
|
+
})
|
|
61
|
+
export class TabViewComponent implements AfterContentInit {
|
|
62
|
+
@Input() selectedIndex?: number;
|
|
63
|
+
|
|
64
|
+
@ContentChildren(TabViewItemComponent) private readonly contentItems?: QueryList<TabViewItemComponent>;
|
|
65
|
+
|
|
66
|
+
items: string[] = [];
|
|
67
|
+
currentIndex = 0;
|
|
68
|
+
|
|
69
|
+
ngAfterContentInit(): void {
|
|
70
|
+
this.currentIndex = typeof this.selectedIndex === 'number' ? this.selectedIndex : 0;
|
|
71
|
+
this.refreshItems();
|
|
72
|
+
this.contentItems?.changes.subscribe(() => this.refreshItems());
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
select(i: number) {
|
|
76
|
+
this.currentIndex = i;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
isActive(item: TabViewItemComponent): boolean {
|
|
80
|
+
const list = this.contentItems?.toArray() ?? [];
|
|
81
|
+
const idx = list.indexOf(item);
|
|
82
|
+
if (idx < 0) return true;
|
|
83
|
+
return idx === this.currentIndex;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
private refreshItems() {
|
|
87
|
+
this.items = (this.contentItems?.toArray() ?? []).map((it: TabViewItemComponent) => it.title);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'TextField, textfield',
|
|
5
|
+
standalone: true,
|
|
6
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
7
|
+
template: `
|
|
8
|
+
<input
|
|
9
|
+
class="ns-textfield"
|
|
10
|
+
type="text"
|
|
11
|
+
[value]="text ?? ''"
|
|
12
|
+
(input)="onInput($event)"
|
|
13
|
+
(keyup.enter)="onSubmit($event)"
|
|
14
|
+
/>
|
|
15
|
+
`,
|
|
16
|
+
styles: [
|
|
17
|
+
`
|
|
18
|
+
.ns-textfield {
|
|
19
|
+
width: 100%;
|
|
20
|
+
padding: 6px 8px;
|
|
21
|
+
}
|
|
22
|
+
`,
|
|
23
|
+
],
|
|
24
|
+
})
|
|
25
|
+
export class TextFieldComponent {
|
|
26
|
+
@Input() text?: string;
|
|
27
|
+
@Output() textChange = new EventEmitter<string>();
|
|
28
|
+
@Output() submit = new EventEmitter<string>();
|
|
29
|
+
|
|
30
|
+
onInput(e: Event) {
|
|
31
|
+
this.textChange.emit((e.target as HTMLInputElement).value);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
onSubmit(e: KeyboardEvent) {
|
|
35
|
+
this.submit.emit((e.target as HTMLInputElement).value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'TextView, textview',
|
|
5
|
+
standalone: true,
|
|
6
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
7
|
+
template: `<textarea class="ns-textview" [value]="text ?? ''" (input)="onInput($event)"></textarea>`,
|
|
8
|
+
styles: [
|
|
9
|
+
`
|
|
10
|
+
.ns-textview {
|
|
11
|
+
width: 100%;
|
|
12
|
+
min-height: 80px;
|
|
13
|
+
padding: 6px 8px;
|
|
14
|
+
}
|
|
15
|
+
`,
|
|
16
|
+
],
|
|
17
|
+
})
|
|
18
|
+
export class TextViewComponent {
|
|
19
|
+
@Input() text?: string;
|
|
20
|
+
@Output() textChange = new EventEmitter<string>();
|
|
21
|
+
@Output() change = new EventEmitter<string>();
|
|
22
|
+
|
|
23
|
+
onInput(e: Event) {
|
|
24
|
+
const v = (e.target as HTMLTextAreaElement).value;
|
|
25
|
+
this.textChange.emit(v);
|
|
26
|
+
this.change.emit(v);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'TimePicker, timepicker',
|
|
5
|
+
standalone: true,
|
|
6
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
7
|
+
template: `<input class="ns-timepicker" type="time" [value]="time ?? ''" (input)="onInput($event)" />`,
|
|
8
|
+
styles: [
|
|
9
|
+
`
|
|
10
|
+
.ns-timepicker {
|
|
11
|
+
padding: 6px 8px;
|
|
12
|
+
}
|
|
13
|
+
`,
|
|
14
|
+
],
|
|
15
|
+
})
|
|
16
|
+
export class TimePickerComponent {
|
|
17
|
+
@Input() time?: string;
|
|
18
|
+
@Output() timeChange = new EventEmitter<string>();
|
|
19
|
+
@Output() change = new EventEmitter<string>();
|
|
20
|
+
|
|
21
|
+
onInput(e: Event) {
|
|
22
|
+
const v = (e.target as HTMLInputElement).value;
|
|
23
|
+
this.timeChange.emit(v);
|
|
24
|
+
this.change.emit(v);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
@Component({
|
|
5
|
+
selector: 'WebView, webview',
|
|
6
|
+
standalone: true,
|
|
7
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
8
|
+
imports: [CommonModule],
|
|
9
|
+
template: `
|
|
10
|
+
<iframe class="ns-webview" *ngIf="src; else projected" [src]="src"></iframe>
|
|
11
|
+
<ng-template #projected><div class="ns-webview"><ng-content></ng-content></div></ng-template>
|
|
12
|
+
`,
|
|
13
|
+
styles: [
|
|
14
|
+
`
|
|
15
|
+
.ns-webview {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
border: none;
|
|
19
|
+
}
|
|
20
|
+
`,
|
|
21
|
+
],
|
|
22
|
+
})
|
|
23
|
+
export class WebViewComponent {
|
|
24
|
+
@Input() src?: string;
|
|
25
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
|
2
|
+
|
|
3
|
+
@Component({
|
|
4
|
+
selector: 'WrapLayout, wraplayout',
|
|
5
|
+
standalone: true,
|
|
6
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
7
|
+
template: `<div class="ns-wrap"><ng-content></ng-content></div>`,
|
|
8
|
+
styles: [
|
|
9
|
+
`
|
|
10
|
+
.ns-wrap {
|
|
11
|
+
display: flex;
|
|
12
|
+
flex-wrap: wrap;
|
|
13
|
+
}
|
|
14
|
+
`,
|
|
15
|
+
],
|
|
16
|
+
})
|
|
17
|
+
export class WrapLayoutComponent {}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export async function alert(message: string, title?: string, _okButtonText?: string) {
|
|
2
|
+
window.alert(title ? `${title}\n\n${message}` : message);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export async function confirm(
|
|
6
|
+
message: string,
|
|
7
|
+
title?: string,
|
|
8
|
+
_okButtonText?: string,
|
|
9
|
+
_cancelButtonText?: string
|
|
10
|
+
): Promise<boolean> {
|
|
11
|
+
return window.confirm(title ? `${title}\n\n${message}` : message);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function prompt(
|
|
15
|
+
message: string,
|
|
16
|
+
defaultText = '',
|
|
17
|
+
title?: string,
|
|
18
|
+
_okButtonText?: string,
|
|
19
|
+
_cancelButtonText?: string
|
|
20
|
+
): Promise<{ result: boolean; text: string }> {
|
|
21
|
+
const res = window.prompt(title ? `${title}\n\n${message}` : message, defaultText);
|
|
22
|
+
return { result: res !== null, text: res ?? '' };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function login(
|
|
26
|
+
message = '登录',
|
|
27
|
+
userName = '',
|
|
28
|
+
password = '',
|
|
29
|
+
title?: string,
|
|
30
|
+
_okButtonText?: string,
|
|
31
|
+
_cancelButtonText?: string
|
|
32
|
+
): Promise<{ result: boolean; userName: string; password: string }> {
|
|
33
|
+
const u = window.prompt(title ? `${title}\n\n${message} - 用户名` : `${message} - 用户名`, userName);
|
|
34
|
+
if (u === null) return { result: false, userName: '', password: '' };
|
|
35
|
+
const p = window.prompt(title ? `${title}\n\n${message} - 密码` : `${message} - 密码`, password);
|
|
36
|
+
if (p === null) return { result: false, userName: '', password: '' };
|
|
37
|
+
return { result: true, userName: u, password: p };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export async function action(
|
|
41
|
+
options: string | { message?: string; cancelButtonText?: string; actions?: string[] },
|
|
42
|
+
title?: string
|
|
43
|
+
): Promise<string | undefined> {
|
|
44
|
+
const message = typeof options === 'string' ? options : options.message || '选择一个操作';
|
|
45
|
+
const actions = typeof options === 'string' ? [] : options.actions || [];
|
|
46
|
+
const promptText = title
|
|
47
|
+
? `${title}\n\n${message}${actions.length ? `\n选项: ${actions.join(', ')}` : ''}`
|
|
48
|
+
: `${message}${actions.length ? `\n选项: ${actions.join(', ')}` : ''}`;
|
|
49
|
+
const res = window.prompt(promptText);
|
|
50
|
+
if (!res) return undefined;
|
|
51
|
+
if (!actions.length) return res;
|
|
52
|
+
const match = actions.find((a) => a.toLowerCase() === res.toLowerCase());
|
|
53
|
+
return match ?? undefined;
|
|
54
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ref, type Ref } from './ref';
|
|
2
|
+
|
|
3
|
+
export interface ActionBarState {
|
|
4
|
+
title: Ref<string>;
|
|
5
|
+
setTitle: (value: string) => void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function useActionBar(): ActionBarState {
|
|
9
|
+
const title = ref('');
|
|
10
|
+
|
|
11
|
+
function setTitle(value: string) {
|
|
12
|
+
title.value = value;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
title,
|
|
17
|
+
setTitle,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ref, type Ref } from './ref';
|
|
2
|
+
|
|
3
|
+
export interface FrameState {
|
|
4
|
+
stack: Ref<any[]>;
|
|
5
|
+
push: (page: any) => void;
|
|
6
|
+
pop: () => any;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function useFrame(): FrameState {
|
|
10
|
+
const stack = ref<any[]>([]);
|
|
11
|
+
|
|
12
|
+
function push(page: any) {
|
|
13
|
+
stack.value.push(page);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function pop() {
|
|
17
|
+
return stack.value.pop();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
stack,
|
|
22
|
+
push,
|
|
23
|
+
pop,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ref, type Ref } from './ref';
|
|
2
|
+
|
|
3
|
+
export interface PageState {
|
|
4
|
+
isVisible: Ref<boolean>;
|
|
5
|
+
show: () => void;
|
|
6
|
+
hide: () => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function usePage(): PageState {
|
|
10
|
+
const isVisible = ref(true);
|
|
11
|
+
|
|
12
|
+
function show() {
|
|
13
|
+
isVisible.value = true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function hide() {
|
|
17
|
+
isVisible.value = false;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return {
|
|
21
|
+
isVisible,
|
|
22
|
+
show,
|
|
23
|
+
hide,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
package/angular/index.ts
ADDED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
<script setup lang="ts">
|
|
7
7
|
import { computed } from 'vue';
|
|
8
8
|
defineOptions({ name: 'Button' });
|
|
9
|
-
|
|
9
|
+
defineEmits<{ (e: 'tap', evt: MouseEvent): void }>();
|
|
10
10
|
const props = defineProps<{ horizontalAlignment?: string }>();
|
|
11
11
|
|
|
12
12
|
const btnStyle = computed<Record<string, string>>(() => {
|
|
@@ -38,4 +38,4 @@ const btnStyle = computed<Record<string, string>>(() => {
|
|
|
38
38
|
|
|
39
39
|
<style scoped>
|
|
40
40
|
.ns-button { cursor: pointer; }
|
|
41
|
-
</style>
|
|
41
|
+
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="ns-grid" :style="gridStyle">
|
|
3
|
-
<template v-for="
|
|
3
|
+
<template v-for="child in renderedChildren" :key="(child as any)?.key ?? child">
|
|
4
4
|
<component :is="child" />
|
|
5
5
|
</template>
|
|
6
6
|
</div>
|
|
@@ -82,4 +82,4 @@ const renderedChildren = computed(() => {
|
|
|
82
82
|
/* flex: 1 1 auto;
|
|
83
83
|
gap: 50px; */
|
|
84
84
|
}
|
|
85
|
-
</style>
|
|
85
|
+
</style>
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
defineOptions({ name: 'Image' });
|
|
7
|
-
|
|
7
|
+
defineProps<{ src: string; stretch?: string }>();
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<style scoped>
|
|
11
11
|
.ns-image { display: block; max-width: 100%; height: auto; }
|
|
12
|
-
</style>
|
|
12
|
+
</style>
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
defineOptions({ name: 'ImageCacheIt' });
|
|
7
|
-
|
|
7
|
+
defineProps<{ src: string }>();
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<style scoped>
|
|
11
11
|
.ns-imagecacheit { display: block; max-width: 100%; height: auto; }
|
|
12
|
-
</style>
|
|
12
|
+
</style>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
8
|
defineOptions({ name: 'ListPicker' });
|
|
9
|
-
|
|
9
|
+
defineProps<{ items: string[]; selectedIndex?: number }>();
|
|
10
10
|
const emit = defineEmits<{ (e: 'update:selectedIndex', v: number): void; (e: 'change', v: number): void }>();
|
|
11
11
|
|
|
12
12
|
function onChange(e: Event) {
|
|
@@ -18,4 +18,4 @@ function onChange(e: Event) {
|
|
|
18
18
|
|
|
19
19
|
<style scoped>
|
|
20
20
|
.ns-listpicker { padding: 6px 8px; }
|
|
21
|
-
</style>
|
|
21
|
+
</style>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
<script setup lang="ts">
|
|
8
8
|
import { getCurrentInstance } from 'vue';
|
|
9
|
-
|
|
9
|
+
defineProps<{ text?: string }>();
|
|
10
10
|
const emit = defineEmits<{ (e: 'tap', evt: MouseEvent): void }>();
|
|
11
11
|
defineOptions({ name: 'NavigationButton' });
|
|
12
12
|
|
|
@@ -25,4 +25,4 @@ function onClick(e: MouseEvent) {
|
|
|
25
25
|
|
|
26
26
|
<style scoped>
|
|
27
27
|
.ns-navbutton { background: transparent; border: none; color: inherit; cursor: pointer; padding: 8px; }
|
|
28
|
-
</style>
|
|
28
|
+
</style>
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
defineOptions({ name: 'Progress' });
|
|
7
|
-
|
|
7
|
+
defineProps<{ value?: number; max?: number }>();
|
|
8
8
|
</script>
|
|
9
9
|
|
|
10
10
|
<style scoped>
|
|
11
11
|
.ns-progress { width: 100%; }
|
|
12
|
-
</style>
|
|
12
|
+
</style>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<script setup lang="ts">
|
|
9
9
|
defineOptions({ name: 'SearchBar' });
|
|
10
|
-
|
|
10
|
+
defineProps<{ text?: string }>();
|
|
11
11
|
const emit = defineEmits<{ (e: 'update:text', v: string): void; (e: 'submit', v: string): void }>();
|
|
12
12
|
function onInput(e: Event) {
|
|
13
13
|
emit('update:text', (e.target as HTMLInputElement).value);
|
|
@@ -19,4 +19,4 @@ function onSubmit(e: KeyboardEvent) {
|
|
|
19
19
|
|
|
20
20
|
<style scoped>
|
|
21
21
|
.ns-searchbar input { width: 100%; padding: 6px 8px; }
|
|
22
|
-
</style>
|
|
22
|
+
</style>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
defineOptions({ name: 'Slider' });
|
|
7
|
-
|
|
7
|
+
defineProps<{ value?: number; min?: number; max?: number; step?: number }>();
|
|
8
8
|
const emit = defineEmits<{ (e: 'update:value', v: number): void; (e: 'change', v: number): void }>();
|
|
9
9
|
function onInput(e: Event) {
|
|
10
10
|
const v = Number((e.target as HTMLInputElement).value);
|
|
@@ -15,4 +15,4 @@ function onInput(e: Event) {
|
|
|
15
15
|
|
|
16
16
|
<style scoped>
|
|
17
17
|
.ns-slider { width: 100%; }
|
|
18
|
-
</style>
|
|
18
|
+
</style>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
<script setup lang="ts">
|
|
9
9
|
defineOptions({ name: 'Switch' });
|
|
10
|
-
|
|
10
|
+
defineProps<{ checked?: boolean }>();
|
|
11
11
|
const emit = defineEmits<{ (e: 'update:checked', v: boolean): void; (e: 'change', v: boolean): void }>();
|
|
12
12
|
function onChange(e: Event) {
|
|
13
13
|
const v = (e.target as HTMLInputElement).checked;
|
|
@@ -23,4 +23,4 @@ function onChange(e: Event) {
|
|
|
23
23
|
.ns-switch .thumb { width: 18px; height: 18px; background: rgb(0, 255, 174); border-radius: 50%; position: absolute; top: 2px; left: 2px; transition: left .2s; }
|
|
24
24
|
.ns-switch input:checked + .track { background: currentColor; opacity: .5; }
|
|
25
25
|
.ns-switch input:checked + .track .thumb { left: 20px; }
|
|
26
|
-
</style>
|
|
26
|
+
</style>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
defineOptions({ name: 'TextField' });
|
|
7
|
-
|
|
7
|
+
defineProps<{ text?: string }>();
|
|
8
8
|
const emit = defineEmits<{ (e: 'update:text', v: string): void; (e: 'submit', v: string): void }>();
|
|
9
9
|
function onInput(e: Event) { emit('update:text', (e.target as HTMLInputElement).value); }
|
|
10
10
|
function onSubmit(e: KeyboardEvent) { emit('submit', (e.target as HTMLInputElement).value); }
|
|
@@ -12,4 +12,4 @@ function onSubmit(e: KeyboardEvent) { emit('submit', (e.target as HTMLInputEleme
|
|
|
12
12
|
|
|
13
13
|
<style scoped>
|
|
14
14
|
.ns-textfield { width: 100%; padding: 6px 8px; }
|
|
15
|
-
</style>
|
|
15
|
+
</style>
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
<script setup lang="ts">
|
|
6
6
|
defineOptions({ name: 'TextView' });
|
|
7
|
-
|
|
7
|
+
defineProps<{ text?: string }>();
|
|
8
8
|
const emit = defineEmits<{ (e: 'update:text', v: string): void; (e: 'change', v: string): void }>();
|
|
9
9
|
function onInput(e: Event) {
|
|
10
10
|
const v = (e.target as HTMLTextAreaElement).value;
|
|
@@ -15,4 +15,4 @@ function onInput(e: Event) {
|
|
|
15
15
|
|
|
16
16
|
<style scoped>
|
|
17
17
|
.ns-textview { width: 100%; min-height: 80px; padding: 6px 8px; }
|
|
18
|
-
</style>
|
|
18
|
+
</style>
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
<script setup lang="ts">
|
|
7
7
|
defineOptions({ name: 'WebView' });
|
|
8
|
-
|
|
8
|
+
defineProps<{ src?: string }>();
|
|
9
9
|
</script>
|
|
10
10
|
|
|
11
11
|
<style scoped>
|
|
12
12
|
.ns-webview { width: 100%; height: 100%; border: none; }
|
|
13
|
-
</style>
|
|
13
|
+
</style>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
export async function alert(message: string, title?: string,
|
|
1
|
+
export async function alert(message: string, title?: string, _okButtonText?: string) {
|
|
2
2
|
window.alert(title ? `${title}\n\n${message}` : message);
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
export async function confirm(message: string, title?: string,
|
|
5
|
+
export async function confirm(message: string, title?: string, _okButtonText?: string, _cancelButtonText?: string): Promise<boolean> {
|
|
6
6
|
return window.confirm(title ? `${title}\n\n${message}` : message);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
export async function prompt(message: string, defaultText = '', title?: string,
|
|
9
|
+
export async function prompt(message: string, defaultText = '', title?: string, _okButtonText?: string, _cancelButtonText?: string): Promise<{ result: boolean; text: string }> {
|
|
10
10
|
const res = window.prompt(title ? `${title}\n\n${message}` : message, defaultText);
|
|
11
11
|
return { result: res !== null, text: res ?? '' };
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export async function login(message = '登录', userName = '', password = '', title?: string,
|
|
14
|
+
export async function login(message = '登录', userName = '', password = '', title?: string, _okButtonText?: string, _cancelButtonText?: string): Promise<{ result: boolean; userName: string; password: string }> {
|
|
15
15
|
const u = window.prompt(title ? `${title}\n\n${message} - 用户名` : `${message} - 用户名`, userName);
|
|
16
16
|
if (u === null) return { result: false, userName: '', password: '' };
|
|
17
17
|
const p = window.prompt(title ? `${title}\n\n${message} - 密码` : `${message} - 密码`, password);
|
|
@@ -28,4 +28,4 @@ export async function action(options: string | { message?: string; cancelButtonT
|
|
|
28
28
|
if (!actions.length) return res;
|
|
29
29
|
const match = actions.find(a => a.toLowerCase() === res.toLowerCase());
|
|
30
30
|
return match ?? undefined;
|
|
31
|
-
}
|
|
31
|
+
}
|