jabroni-outfit 1.4.9 → 1.6.5
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/LICENSE +21 -21
- package/README.md +131 -126
- package/dist/index.d.ts +14 -4
- package/dist/jabroni-outfit.es.js +1640 -1731
- package/dist/jabroni-outfit.es.js.map +1 -1
- package/dist/jabroni-outfit.umd.js +9 -9
- package/dist/jabroni-outfit.umd.js.map +1 -1
- package/package.json +61 -49
- package/src/index.ts +17 -13
- package/src/store/default-state.ts +39 -33
- package/src/store/persistent-state.ts +35 -35
- package/src/store/store.ts +52 -50
- package/src/store/types.ts +15 -15
- package/src/style.css +2 -2
- package/src/test/example.ts +58 -48
- package/src/test/umd-example.js +30 -30
- package/src/typings/vue.d.ts +5 -5
- package/src/ui/default-scheme.ts +89 -38
- package/src/ui/index.ts +31 -29
- package/src/ui/types.ts +27 -27
- package/src/ui/vue-templates/App.vue +47 -47
- package/src/ui/vue-templates/Gen.vue +20 -20
- package/src/ui/vue-templates/RowElement.vue +65 -64
- package/src/ui/vue-templates/icons/Close.vue +6 -6
- package/src/ui/vue-templates/icons/Config.vue +6 -6
package/src/ui/default-scheme.ts
CHANGED
|
@@ -1,38 +1,89 @@
|
|
|
1
|
-
import type { Scheme } from "./types";
|
|
2
|
-
|
|
3
|
-
export const DefaultScheme: Scheme = {
|
|
4
|
-
excludeFilter: [
|
|
5
|
-
{ type: "checkbox", model: "state.filterExclude", label: "exclude" },
|
|
6
|
-
{ type: "text", model: "state.filterExcludeWords", placeholder: "word, word1|word2, f:full_word..." }
|
|
7
|
-
],
|
|
8
|
-
includeFilter: [
|
|
9
|
-
{ type: "checkbox", model: "state.filterInclude", label: "include" },
|
|
10
|
-
{ type: "text", model: "state.filterIncludeWords", placeholder: "word, word1|word2, f:full_word..." }
|
|
11
|
-
],
|
|
12
|
-
infiniteScroll: [
|
|
13
|
-
{ type: "checkbox", model: "state.infiniteScrollEnabled", label: "infinite scroll" },
|
|
14
|
-
{
|
|
15
|
-
type: "span", innerText:
|
|
16
|
-
"return `${
|
|
17
|
-
}
|
|
18
|
-
],
|
|
19
|
-
durationFilter: [
|
|
20
|
-
{ type: "checkbox", model: "state.filterDuration", label: "duration" },
|
|
21
|
-
{ type: "number", model: "state.filterDurationFrom", step: "10", min: "0", max: "72000", labelBefore: "from" },
|
|
22
|
-
{ type: "number", model: "state.filterDurationTo", step: "10", min: "0", max: "72000", labelBefore: "to" }
|
|
23
|
-
],
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
1
|
+
import type { Scheme } from "./types";
|
|
2
|
+
|
|
3
|
+
export const DefaultScheme: Scheme = {
|
|
4
|
+
excludeFilter: [
|
|
5
|
+
{ type: "checkbox", model: "state.filterExclude", label: "exclude" },
|
|
6
|
+
{ type: "text", model: "state.filterExcludeWords", placeholder: "word, word1|word2, f:full_word..." }
|
|
7
|
+
],
|
|
8
|
+
includeFilter: [
|
|
9
|
+
{ type: "checkbox", model: "state.filterInclude", label: "include" },
|
|
10
|
+
{ type: "text", model: "state.filterIncludeWords", placeholder: "word, word1|word2, f:full_word..." }
|
|
11
|
+
],
|
|
12
|
+
infiniteScroll: [
|
|
13
|
+
{ type: "checkbox", model: "state.infiniteScrollEnabled", label: "infinite scroll" },
|
|
14
|
+
{
|
|
15
|
+
type: "span", innerText:
|
|
16
|
+
"return `${localState.pagIndexCur}/${localState.pagIndexLast}`", "v-if": "return localState.pagIndexLast > 1"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
durationFilter: [
|
|
20
|
+
{ type: "checkbox", model: "state.filterDuration", label: "duration" },
|
|
21
|
+
{ type: "number", model: "state.filterDurationFrom", step: "10", min: "0", max: "72000", labelBefore: "from" },
|
|
22
|
+
{ type: "number", model: "state.filterDurationTo", step: "10", min: "0", max: "72000", labelBefore: "to" }
|
|
23
|
+
],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const customScheme: Scheme = {
|
|
27
|
+
sortFilter: [
|
|
28
|
+
{
|
|
29
|
+
type: "span", innerText: 'sort by:'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
type: 'button',
|
|
33
|
+
innerText: 'views',
|
|
34
|
+
callback: () => {
|
|
35
|
+
//@ts-ignore
|
|
36
|
+
window.sortByViews?.();
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: 'button',
|
|
41
|
+
innerText: 'duration',
|
|
42
|
+
callback: () => {
|
|
43
|
+
//@ts-ignore
|
|
44
|
+
window.sortByDuration?.();
|
|
45
|
+
},
|
|
46
|
+
}],
|
|
47
|
+
|
|
48
|
+
privacyFilter: [
|
|
49
|
+
{ type: "checkbox", model: "state.filterPrivate", label: "private" },
|
|
50
|
+
{ type: "checkbox", model: "state.filterPublic", label: "public" }
|
|
51
|
+
],
|
|
52
|
+
|
|
53
|
+
privacyAccess: [
|
|
54
|
+
{ type: "checkbox", model: "state.autoRequestAccess", label: "auto friend request" },
|
|
55
|
+
{
|
|
56
|
+
type: 'button',
|
|
57
|
+
innerText: 'check access 🔓',
|
|
58
|
+
callback: () => {
|
|
59
|
+
//@ts-ignore
|
|
60
|
+
window.requestAccess?.();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
|
|
65
|
+
hdFilter: [
|
|
66
|
+
{ type: "checkbox", model: "state.filterHD", label: "HD" },
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const extendScheme = (scheme: Scheme, newScheme: Scheme) =>
|
|
71
|
+
Object.entries(scheme).reduce((acc, [k, v], i) => {
|
|
72
|
+
if (i === 2) Object.assign(acc, newScheme);
|
|
73
|
+
Object.assign(acc, { [k]: v });
|
|
74
|
+
return acc;
|
|
75
|
+
}, {});
|
|
76
|
+
|
|
77
|
+
export const defaultSchemeWithPrivacyFilter = extendScheme(DefaultScheme, {
|
|
78
|
+
privacyFilter: customScheme.privacyFilter,
|
|
79
|
+
privacyAccess: customScheme.privacyAccess
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const defaultSchemeWithPrivacyFilterWithHD = extendScheme(defaultSchemeWithPrivacyFilter, {
|
|
83
|
+
hdFilter: customScheme.hdFilter
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
export const defaultSchemeWithPrivacyFilterWithHDwithSort = extendScheme(defaultSchemeWithPrivacyFilterWithHD, {
|
|
87
|
+
sortFilter: customScheme.sortFilter
|
|
88
|
+
});
|
|
89
|
+
|
package/src/ui/index.ts
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
import { createApp } from "vue";
|
|
2
|
-
import { DefaultScheme } from "./default-scheme";
|
|
3
|
-
import type { Scheme, UIPosition } from "./types";
|
|
4
|
-
import type { JabroniOutfitStore } from "../store/store";
|
|
5
|
-
import App from "./vue-templates/App.vue"
|
|
6
|
-
import { parseDom } from "billy-herrington-utils";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
1
|
+
import { createApp } from "vue";
|
|
2
|
+
import { DefaultScheme } from "./default-scheme";
|
|
3
|
+
import type { Scheme, UIPosition } from "./types";
|
|
4
|
+
import type { JabroniOutfitStore } from "../store/store";
|
|
5
|
+
import App from "./vue-templates/App.vue"
|
|
6
|
+
import { parseDom } from "billy-herrington-utils";
|
|
7
|
+
|
|
8
|
+
const DEFAULT_ROOT = 'jabroni-outfit-root';
|
|
9
|
+
|
|
10
|
+
export class JabroniOutfitUI {
|
|
11
|
+
public app: ReturnType<typeof createApp>;
|
|
12
|
+
|
|
13
|
+
private getRoot(rootSelector: string) {
|
|
14
|
+
if (rootSelector === DEFAULT_ROOT) {
|
|
15
|
+
const rootEl = parseDom(`<div id="${rootSelector}" style="position: relative; z-index: 999999;"></div>`);
|
|
16
|
+
document.body.appendChild(rootEl);
|
|
17
|
+
}
|
|
18
|
+
document.getElementById(rootSelector)?.classList.add('taper-class');
|
|
19
|
+
return `#${rootSelector}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
constructor(
|
|
23
|
+
{ state, localState }: JabroniOutfitStore,
|
|
24
|
+
scheme: Scheme = DefaultScheme,
|
|
25
|
+
rootSelector = DEFAULT_ROOT,
|
|
26
|
+
position: UIPosition = { fixed: true, right: true, bottom: true }
|
|
27
|
+
) {
|
|
28
|
+
this.app = createApp(App, { state, localState, scheme, position });
|
|
29
|
+
this.app.mount(this.getRoot(rootSelector));
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/ui/types.ts
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
export interface SchemeRowEl {
|
|
2
|
-
type: 'checkbox' | 'text' | 'number' | 'span' | 'button';
|
|
3
|
-
model?: string,
|
|
4
|
-
label?: string,
|
|
5
|
-
labelBefore?: string,
|
|
6
|
-
innerText?: string,
|
|
7
|
-
max?: string,
|
|
8
|
-
min?: string,
|
|
9
|
-
step?: string,
|
|
10
|
-
"v-if"?: string,
|
|
11
|
-
placeholder?: string
|
|
12
|
-
callback?: () => void
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type SchemeRow = SchemeRowEl[];
|
|
16
|
-
|
|
17
|
-
export interface Scheme {
|
|
18
|
-
[key: string]: SchemeRow
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface UIPosition {
|
|
22
|
-
fixed: boolean,
|
|
23
|
-
left?: boolean,
|
|
24
|
-
right?: boolean,
|
|
25
|
-
top?: boolean,
|
|
26
|
-
bottom?: boolean
|
|
27
|
-
}
|
|
1
|
+
export interface SchemeRowEl {
|
|
2
|
+
type: 'checkbox' | 'text' | 'number' | 'span' | 'button';
|
|
3
|
+
model?: string,
|
|
4
|
+
label?: string,
|
|
5
|
+
labelBefore?: string,
|
|
6
|
+
innerText?: string,
|
|
7
|
+
max?: string,
|
|
8
|
+
min?: string,
|
|
9
|
+
step?: string,
|
|
10
|
+
"v-if"?: string,
|
|
11
|
+
placeholder?: string
|
|
12
|
+
callback?: () => void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type SchemeRow = SchemeRowEl[];
|
|
16
|
+
|
|
17
|
+
export interface Scheme {
|
|
18
|
+
[key: string]: SchemeRow
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface UIPosition {
|
|
22
|
+
fixed: boolean,
|
|
23
|
+
left?: boolean,
|
|
24
|
+
right?: boolean,
|
|
25
|
+
top?: boolean,
|
|
26
|
+
bottom?: boolean
|
|
27
|
+
}
|
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import Config from './icons/Config.vue';
|
|
3
|
-
import Close from './icons/Close.vue';
|
|
4
|
-
import Gen from './Gen.vue';
|
|
5
|
-
import type { Scheme, UIPosition } from '../types';
|
|
6
|
-
import type { Reactive } from 'vue';
|
|
7
|
-
import type { RecordV } from '../../store/types';
|
|
8
|
-
|
|
9
|
-
const { state,
|
|
10
|
-
state: Reactive<RecordV>,
|
|
11
|
-
|
|
12
|
-
scheme?: Scheme,
|
|
13
|
-
position: UIPosition
|
|
14
|
-
}>();
|
|
15
|
-
|
|
16
|
-
const optClasses = {
|
|
17
|
-
fixed: 'fixed',
|
|
18
|
-
right: 'right-0',
|
|
19
|
-
left: 'left-0',
|
|
20
|
-
top: 'top-0',
|
|
21
|
-
bottom: 'bottom-0'
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const pos = Object.entries(position).filter(([_, v]) => v)
|
|
25
|
-
.map(([k, _]) => optClasses[k]).join(' ');
|
|
26
|
-
|
|
27
|
-
</script>
|
|
28
|
-
<template>
|
|
29
|
-
<div class="z-9999 rounded bg-zinc-800 max-w-full p-2 m-2"
|
|
30
|
-
:class="`${state.hidden ? 'hover:bg-gray-600' : ''} ${pos}`" v-if="state.uiEnabled">
|
|
31
|
-
|
|
32
|
-
<div class="flex items-center cursor-pointer py-1 px-2 m-1 rounded"
|
|
33
|
-
:class="!state.hidden ? 'hover:bg-zinc-900' : ''" @click="state.hidden = !state.hidden">
|
|
34
|
-
<span class="m-auto flex mono">
|
|
35
|
-
<span v-if="state.hidden &&
|
|
36
|
-
class="px-3 py-2 mr-2 bg-gray-700 text-zinc-300 font-mono rounded
|
|
37
|
-
{{
|
|
38
|
-
</span>
|
|
39
|
-
<Config v-if="state.hidden" />
|
|
40
|
-
<Close v-if="!state.hidden" />
|
|
41
|
-
</span>
|
|
42
|
-
</div>
|
|
43
|
-
|
|
44
|
-
<Gen :scheme="scheme" :
|
|
45
|
-
</div>
|
|
46
|
-
</template>
|
|
47
|
-
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import Config from './icons/Config.vue';
|
|
3
|
+
import Close from './icons/Close.vue';
|
|
4
|
+
import Gen from './Gen.vue';
|
|
5
|
+
import type { Scheme, UIPosition } from '../types';
|
|
6
|
+
import type { Reactive } from 'vue';
|
|
7
|
+
import type { RecordV } from '../../store/types';
|
|
8
|
+
|
|
9
|
+
const { state, localState, scheme, position } = defineProps<{
|
|
10
|
+
state: Reactive<RecordV>,
|
|
11
|
+
localState: Reactive<RecordV>,
|
|
12
|
+
scheme?: Scheme,
|
|
13
|
+
position: UIPosition
|
|
14
|
+
}>();
|
|
15
|
+
|
|
16
|
+
const optClasses = {
|
|
17
|
+
fixed: 'fixed',
|
|
18
|
+
right: 'right-0',
|
|
19
|
+
left: 'left-0',
|
|
20
|
+
top: 'top-0',
|
|
21
|
+
bottom: 'bottom-0'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const pos = Object.entries(position).filter(([_, v]) => v)
|
|
25
|
+
.map(([k, _]) => optClasses[k]).join(' ');
|
|
26
|
+
|
|
27
|
+
</script>
|
|
28
|
+
<template>
|
|
29
|
+
<div class="z-9999 rounded bg-zinc-800 max-w-full p-2 m-2"
|
|
30
|
+
:class="`${state.hidden ? 'hover:bg-gray-600' : ''} ${pos}`" v-if="state.uiEnabled">
|
|
31
|
+
|
|
32
|
+
<div class="flex items-center cursor-pointer py-1 px-2 m-1 rounded"
|
|
33
|
+
:class="!state.hidden ? 'hover:bg-zinc-900' : ''" @click="state.hidden = !state.hidden">
|
|
34
|
+
<span class="m-auto flex mono">
|
|
35
|
+
<span v-if="state.hidden && localState.pagIndexLast as number > 1"
|
|
36
|
+
class="px-3 py-2 mr-2 bg-gray-700 text-zinc-300 font-mono rounded">
|
|
37
|
+
{{ localState.pagIndexCur }}/{{ localState.pagIndexLast }}
|
|
38
|
+
</span>
|
|
39
|
+
<Config v-if="state.hidden" />
|
|
40
|
+
<Close v-if="!state.hidden" />
|
|
41
|
+
</span>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<Gen :scheme="scheme" :localState="localState" :state="state" v-if="!state.hidden" />
|
|
45
|
+
</div>
|
|
46
|
+
</template>
|
|
47
|
+
|
|
48
48
|
<style scoped></style>
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import type { Reactive } from "vue";
|
|
3
|
-
import type { RecordV } from "../../store/types";
|
|
4
|
-
import type { Scheme } from "../types";
|
|
5
|
-
import RowElement from './RowElement.vue'
|
|
6
|
-
|
|
7
|
-
const { scheme, state,
|
|
8
|
-
state: Reactive<RecordV>,
|
|
9
|
-
|
|
10
|
-
scheme?: Scheme
|
|
11
|
-
}>()
|
|
12
|
-
|
|
13
|
-
const rows = Object.values(scheme as Scheme);
|
|
14
|
-
|
|
15
|
-
</script>
|
|
16
|
-
|
|
17
|
-
<template>
|
|
18
|
-
<div v-for="row in rows" class="flex items-center bg-zinc-900 py-2 px-2 m-1 font-mono rounded">
|
|
19
|
-
<RowElement v-for="r in row" :element="r" :
|
|
20
|
-
</div>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import type { Reactive } from "vue";
|
|
3
|
+
import type { RecordV } from "../../store/types";
|
|
4
|
+
import type { Scheme } from "../types";
|
|
5
|
+
import RowElement from './RowElement.vue'
|
|
6
|
+
|
|
7
|
+
const { scheme, state, localState } = defineProps<{
|
|
8
|
+
state: Reactive<RecordV>,
|
|
9
|
+
localState: Reactive<RecordV>,
|
|
10
|
+
scheme?: Scheme
|
|
11
|
+
}>()
|
|
12
|
+
|
|
13
|
+
const rows = Object.values(scheme as Scheme);
|
|
14
|
+
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<div v-for="row in rows" class="flex items-center bg-zinc-900 py-2 px-2 m-1 font-mono rounded">
|
|
19
|
+
<RowElement v-for="r in row" :element="r" :localState="localState" :state="state" />
|
|
20
|
+
</div>
|
|
21
21
|
</template>
|
|
@@ -1,65 +1,66 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, type Reactive } from "vue";
|
|
3
|
-
import type { RecordV } from "../../store/types";
|
|
4
|
-
import type { SchemeRowEl } from "../types";
|
|
5
|
-
|
|
6
|
-
const props = defineProps<{
|
|
7
|
-
element?: SchemeRowEl,
|
|
8
|
-
state: Reactive<RecordV>,
|
|
9
|
-
|
|
10
|
-
}>();
|
|
11
|
-
|
|
12
|
-
const { element, state,
|
|
13
|
-
|
|
14
|
-
const { type, model, innerText, label, labelBefore, callback, ...rest } = element as SchemeRowEl;
|
|
15
|
-
|
|
16
|
-
const isInput = /checkbox|text|number/.test(type);
|
|
17
|
-
const tag = isInput ? 'input' : type;
|
|
18
|
-
const ctype = isInput ? type : "";
|
|
19
|
-
const id = isInput ? model : (Math.random() * 10000000 | 0).toString(16);
|
|
20
|
-
|
|
21
|
-
const componentStyles = {
|
|
22
|
-
text: "w-full h-8 text-zinc-300 px-3 py-2 mx-2 rounded-sm bg-zinc-700 outline-none focus:outline-gray-600 hover:bg-zinc-600",
|
|
23
|
-
checkbox: "mx-2 size-auto invert checked:invert-0 accent-gray-700",
|
|
24
|
-
number: "w-24 h-8 text-zinc-300 rounded px-3 py-2 bg-gray-700 hover:bg-gray-600 outline-none focus:outline-gray-600",
|
|
25
|
-
button: "mx-2 size-auto text-zinc-300 rounded px-3 py-2 bg-gray-700 hover:bg-gray-600 ml-auto",
|
|
26
|
-
span: "text-zinc-300 ml-auto mr-4",
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const innerTextValue = computed(() => {
|
|
30
|
-
if (!innerText?.includes('return')) return innerText || "";
|
|
31
|
-
const f = new Function('state', '
|
|
32
|
-
return f(state,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const value = new Function('state', '
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
<
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, type Reactive } from "vue";
|
|
3
|
+
import type { RecordV } from "../../store/types";
|
|
4
|
+
import type { SchemeRowEl } from "../types";
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
element?: SchemeRowEl,
|
|
8
|
+
state: Reactive<RecordV>,
|
|
9
|
+
localState: Reactive<RecordV>,
|
|
10
|
+
}>();
|
|
11
|
+
|
|
12
|
+
const { element, state, localState } = props;
|
|
13
|
+
|
|
14
|
+
const { type, model, innerText, label, labelBefore, callback, ...rest } = element as SchemeRowEl;
|
|
15
|
+
|
|
16
|
+
const isInput = /checkbox|text|number/.test(type);
|
|
17
|
+
const tag = isInput ? 'input' : type;
|
|
18
|
+
const ctype = isInput ? type : "";
|
|
19
|
+
const id = isInput ? model : (Math.random() * 10000000 | 0).toString(16);
|
|
20
|
+
|
|
21
|
+
const componentStyles = {
|
|
22
|
+
text: "w-full h-8 text-zinc-300 px-3 py-2 mx-2 rounded-sm bg-zinc-700 outline-none focus:outline-gray-600 hover:bg-zinc-600",
|
|
23
|
+
checkbox: "mx-2 size-auto invert checked:invert-0 accent-gray-700",
|
|
24
|
+
number: "w-24 h-8 text-zinc-300 rounded px-3 py-2 bg-gray-700 hover:bg-gray-600 outline-none focus:outline-gray-600",
|
|
25
|
+
button: "mx-2 size-auto text-zinc-300 rounded px-3 py-2 bg-gray-700 hover:bg-gray-600 ml-auto",
|
|
26
|
+
span: "text-zinc-300 ml-auto mr-4",
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const innerTextValue = computed(() => {
|
|
30
|
+
if (!innerText?.includes('return')) return innerText || "";
|
|
31
|
+
const f = new Function('state', 'localState', `${innerText}`);
|
|
32
|
+
return f(state, localState);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const value = new Function('state', 'localState', `return ${model || ""}`)(state, localState);
|
|
36
|
+
|
|
37
|
+
const updateValue = ({ target: { checked, value } }) => {
|
|
38
|
+
if (!(typeof model === 'string') || !/^state|localState/.test(model)) return;
|
|
39
|
+
const [stateName, stateProp] = (model).split('.');
|
|
40
|
+
const val = type === 'checkbox' ? checked : value;
|
|
41
|
+
props[stateName][stateProp] = val;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const vif = computed(() => {
|
|
45
|
+
if (!element?.['v-if']) return true;
|
|
46
|
+
const f = new Function('state', 'localState', `${element['v-if']}`);
|
|
47
|
+
return f(state, localState);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// button state
|
|
51
|
+
// let callbackWrap: () => Promise<void> | undefined;
|
|
52
|
+
// if (callback) {
|
|
53
|
+
// callbackWrap = async () => {
|
|
54
|
+
// callback();
|
|
55
|
+
// }
|
|
56
|
+
// }
|
|
57
|
+
|
|
58
|
+
</script>
|
|
59
|
+
<template>
|
|
60
|
+
<label v-if="labelBefore" :for="id" class="text-zinc-300 mx-2 font-mono">{{ labelBefore }}</label>
|
|
61
|
+
<component v-if="vif" :id="id" :is="tag" :type="ctype" :class="componentStyles[type]" :checked="!!value"
|
|
62
|
+
:value="value" v-on:change="updateValue" v-on:input="updateValue" @click="callback" v-bind="rest">
|
|
63
|
+
{{ innerTextValue }}
|
|
64
|
+
</component>
|
|
65
|
+
<label v-if="label" :for="id" class="text-zinc-300 flex font-mono">{{ label }}</label>
|
|
65
66
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<svg class="h-7 w-7 fill-gray-600 stroke-gray-400" xmlns="http://www.w3.org/2000/svg"
|
|
3
|
-
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
4
|
-
<path stroke-linecap="round" stroke-linejoin="round"
|
|
5
|
-
d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
|
6
|
-
</svg>
|
|
1
|
+
<template>
|
|
2
|
+
<svg class="h-7 w-7 fill-gray-600 stroke-gray-400" xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
|
4
|
+
<path stroke-linecap="round" stroke-linejoin="round"
|
|
5
|
+
d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
|
6
|
+
</svg>
|
|
7
7
|
</template>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<svg class="h-7 w-7 fill-gray-600 stroke-gray-400" xmlns="http://www.w3.org/2000/svg"
|
|
3
|
-
fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
|
|
4
|
-
<path strokeLinecap="round" strokeLinejoin="round"
|
|
5
|
-
d="M11.42 15.17 17.25 21A2.652 2.652 0 0 0 21 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 1 1-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 0 0 4.486-6.336l-3.276 3.277a3.004 3.004 0 0 1-2.25-2.25l3.276-3.276a4.5 4.5 0 0 0-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437 1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008Z" />
|
|
6
|
-
</svg>
|
|
1
|
+
<template>
|
|
2
|
+
<svg class="h-7 w-7 fill-gray-600 stroke-gray-400" xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
fill="none" viewBox="0 0 24 24" strokeWidth={1.5} stroke="currentColor">
|
|
4
|
+
<path strokeLinecap="round" strokeLinejoin="round"
|
|
5
|
+
d="M11.42 15.17 17.25 21A2.652 2.652 0 0 0 21 17.25l-5.877-5.877M11.42 15.17l2.496-3.03c.317-.384.74-.626 1.208-.766M11.42 15.17l-4.655 5.653a2.548 2.548 0 1 1-3.586-3.586l6.837-5.63m5.108-.233c.55-.164 1.163-.188 1.743-.14a4.5 4.5 0 0 0 4.486-6.336l-3.276 3.277a3.004 3.004 0 0 1-2.25-2.25l3.276-3.276a4.5 4.5 0 0 0-6.336 4.486c.091 1.076-.071 2.264-.904 2.95l-.102.085m-1.745 1.437L5.909 7.5H4.5L2.25 3.75l1.5-1.5L7.5 4.5v1.409l4.26 4.26m-1.745 1.437 1.745-1.437m6.615 8.206L15.75 15.75M4.867 19.125h.008v.008h-.008v-.008Z" />
|
|
6
|
+
</svg>
|
|
7
7
|
</template>
|