jabroni-outfit 1.6.4 → 2.0.7

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.

Potentially problematic release.


This version of jabroni-outfit might be problematic. Click here for more details.

Files changed (47) hide show
  1. package/README.md +68 -108
  2. package/dist/index.d.ts +148 -62
  3. package/dist/jabroni-outfit.es.js +3804 -2969
  4. package/dist/jabroni-outfit.es.js.map +1 -1
  5. package/dist/jabroni-outfit.umd.js +13 -16
  6. package/dist/jabroni-outfit.umd.js.map +1 -1
  7. package/package.json +18 -18
  8. package/src/app.ts +39 -0
  9. package/src/components/App.vue +40 -0
  10. package/src/components/Badge.vue +30 -0
  11. package/src/components/Chevron.vue +10 -0
  12. package/src/components/Header.vue +38 -0
  13. package/src/components/RowButton.vue +21 -0
  14. package/src/components/Section.vue +66 -0
  15. package/src/components/icons/Check.vue +17 -0
  16. package/src/components/icons/ChevronDown.vue +17 -0
  17. package/src/components/icons/ChevronUp.vue +17 -0
  18. package/src/components/icons/Minus.vue +17 -0
  19. package/src/components/icons/Sun.vue +21 -0
  20. package/src/components/inputs/InputCheckbox.vue +29 -0
  21. package/src/components/inputs/InputNumber.vue +24 -0
  22. package/src/components/inputs/InputRange.vue +66 -0
  23. package/src/components/inputs/InputText.vue +21 -0
  24. package/src/index.ts +4 -17
  25. package/src/scheme/default-scheme.ts +129 -0
  26. package/src/scheme/parser.ts +103 -0
  27. package/src/scheme/scheme-element.ts +93 -0
  28. package/src/store/default-state.ts +8 -37
  29. package/src/store/index.ts +63 -0
  30. package/src/store/persistent-state.ts +45 -17
  31. package/src/style/index.css +30 -0
  32. package/src/test/example.ts +56 -44
  33. package/src/test/umd-example.js +58 -27
  34. package/src/types/index.ts +48 -0
  35. package/src/utils/index.ts +33 -0
  36. package/src/store/store.ts +0 -52
  37. package/src/store/types.ts +0 -16
  38. package/src/style.css +0 -3
  39. package/src/typings/vue.d.ts +0 -6
  40. package/src/ui/default-scheme.ts +0 -76
  41. package/src/ui/index.ts +0 -31
  42. package/src/ui/types.ts +0 -27
  43. package/src/ui/vue-templates/App.vue +0 -48
  44. package/src/ui/vue-templates/Gen.vue +0 -21
  45. package/src/ui/vue-templates/RowElement.vue +0 -66
  46. package/src/ui/vue-templates/icons/Close.vue +0 -7
  47. package/src/ui/vue-templates/icons/Config.vue +0 -7
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jabroni-outfit",
3
- "description": "out-of-the-box gui and persistent-state library based on vue",
4
- "version": "1.6.4",
3
+ "description": "Small GUI and persistent state lib based on Vue.",
4
+ "version": "2.0.7",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "gui",
@@ -14,22 +14,22 @@
14
14
  ],
15
15
  "author": "smartacephale atm.mormon@protonmail.com (https://github.com/smartacephale)",
16
16
  "type": "module",
17
- "homepage": "https://github.com/smartacephale/jabroni-outfit#readme",
17
+ "homepage": "https://github.com/smartacephale/jabroni-outfit-GUI#readme",
18
18
  "main": "dist/jabroni-outfit.umd.js",
19
19
  "module": "dist/jabroni-outfit.es.js",
20
20
  "types": "dist/index.d.ts",
21
- "repository": "github:smartacephale/jabroni-outfit",
21
+ "repository": "github:smartacephale/jabroni-outfit-GUI",
22
22
  "bugs": {
23
- "url": "https://github.com/smartacephale/jabroni-outfit/issues",
23
+ "url": "https://github.com/smartacephale/jabroni-outfit-GUI/issues",
24
24
  "email": "atm.mormon@protonmail.com"
25
25
  },
26
26
  "browser": "dist/jabroni-outfit.es.js",
27
27
  "unpkg": "dist/jabroni-outfit.es.js",
28
28
  "exports": {
29
29
  ".": {
30
+ "types": "./dist/index.d.ts",
30
31
  "import": "./dist/jabroni-outfit.es.js",
31
- "require": "./dist/jabroni-outfit.umd.cjs",
32
- "types": "./dist/index.d.ts"
32
+ "require": "./dist/jabroni-outfit.umd.cjs"
33
33
  }
34
34
  },
35
35
  "files": [
@@ -42,19 +42,19 @@
42
42
  "preview": "vite preview"
43
43
  },
44
44
  "devDependencies": {
45
- "@vitejs/plugin-vue": "^5.1.2",
46
- "autoprefixer": "^10.4.20",
47
- "postcss": "^8.4.41",
48
- "tailwindcss": "^3.4.10",
49
- "tailwindcss-scoped-preflight": "^3.4.3",
45
+ "@tailwindcss/postcss": "^4.1.18",
46
+ "@vitejs/plugin-vue": "^6.0.3",
47
+ "autoprefixer": "^10.4.23",
48
+ "postcss": "^8.5.6",
49
+ "tailwindcss": "^4.1.18",
50
50
  "typescript": "^5.5.3",
51
- "vite": "^6.3.5",
52
- "vite-plugin-css-injected-by-js": "^3.5.1",
53
- "vite-plugin-dts": "^4.0.3",
54
- "vue-tsc": "^2.0.29"
51
+ "vite": "^7.3.0",
52
+ "vite-plugin-css-injected-by-js": "^3.5.2",
53
+ "vite-plugin-dts": "^4.5.4",
54
+ "vue-tsc": "^3.2.1"
55
55
  },
56
56
  "dependencies": {
57
- "billy-herrington-utils": "^1.1.1",
58
- "vue": "^3.4.37"
57
+ "billy-herrington-utils": "^1.4.2",
58
+ "vue": "^3.5.26"
59
59
  }
60
60
  }
package/src/app.ts ADDED
@@ -0,0 +1,39 @@
1
+ import './style/index.css';
2
+ import { parseDom } from 'billy-herrington-utils';
3
+ import { createApp } from 'vue';
4
+ import App from './components/App.vue';
5
+ import { SchemeParser } from './scheme/parser';
6
+ import type { JabronioStore } from './store';
7
+ import type { SchemeInput } from './types';
8
+
9
+ const DEFAULT_ROOT = 'jabroni-outfit-root';
10
+
11
+ export class JabronioGUI {
12
+ public app: ReturnType<typeof createApp>;
13
+
14
+ private getRoot(rootSelector: string) {
15
+ if (rootSelector === DEFAULT_ROOT) {
16
+ const rootEl = parseDom(
17
+ `<div id="${rootSelector}" style="position: relative; z-index: 999999;"></div>`,
18
+ );
19
+ document.body.appendChild(rootEl);
20
+ }
21
+ document.getElementById(rootSelector)?.classList.add('taper-class');
22
+ return `#${rootSelector}`;
23
+ }
24
+
25
+ constructor(
26
+ scheme: SchemeInput,
27
+ store: JabronioStore,
28
+ rootSelector = DEFAULT_ROOT,
29
+ position = 'fixed right-0 bottom-0',
30
+ ) {
31
+ const parsed = SchemeParser.parse(scheme, store);
32
+ this.app = createApp(App, {
33
+ state: store.state,
34
+ scheme: parsed.scheme,
35
+ position,
36
+ });
37
+ this.app.mount(this.getRoot(rootSelector));
38
+ }
39
+ }
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeParsed, StoreState } from '../types';
4
+ import Header from './Header.vue';
5
+ import Section from './Section.vue';
6
+
7
+ const props = defineProps<{
8
+ state: StoreState;
9
+ scheme: SchemeParsed;
10
+ position: string;
11
+ }>();
12
+
13
+ const scheme = computed(() => {
14
+ return props.scheme.filter((g) => g.title !== 'Badge');
15
+ });
16
+ </script>
17
+ <template>
18
+ <div
19
+ v-if="props.state.uiEnabled"
20
+ id="jabroni-app"
21
+ :data-theme="props.state.darkmode ? 'dark' : 'bright'"
22
+ :class="`isolate ${props.position}
23
+ w-85 max-h-118 flex flex-col m-2
24
+ bg-white border-2 border-black dark:border-gray-700 dark:bg-zinc-800 dark:text-zinc-300
25
+ shadow-[4px_4px_0px_0px_rgba(0,0,0,1)]
26
+ text-black text-xs font-light`"
27
+ >
28
+ <Header :state="props.state" :scheme="props.scheme"/>
29
+
30
+ <div class="flex-1 overflow-y-auto p-2 space-y-2" v-if="props.state.hidden">
31
+ <Section :state="props.state" :group="group" v-for="group in scheme"/>
32
+ </div>
33
+ </div>
34
+ </template>
35
+
36
+ <style scoped>
37
+ #jabroni-app {
38
+ font-family: monospace;
39
+ }
40
+ </style>
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeElement } from '../scheme/scheme-element';
4
+ import type { SchemeGroup, StoreState } from '../types';
5
+
6
+ const props = defineProps<{
7
+ state: StoreState;
8
+ group: SchemeGroup<SchemeElement>;
9
+ }>();
10
+
11
+ const el = computed(() => props.group.content[0]);
12
+
13
+ function computedExpression(expr: string) {
14
+ return computed(() => {
15
+ const f = new Function('state', `${expr}`);
16
+ return f(props.state);
17
+ });
18
+ }
19
+
20
+ const vif = computedExpression(el.value?.vif || '');
21
+ const textContent = computedExpression(el.value?.text || '');
22
+ </script>
23
+ <template>
24
+ <span
25
+ v-if="vif"
26
+ class="bg-black text-white px-1.5 py-1 text-[11px] font-semibold dark:border-2 dark:border-zinc-700 dark:bg-gray-600 dark:text-zinc-300"
27
+ >
28
+ {{ textContent }}</span
29
+ >
30
+ </template>
@@ -0,0 +1,10 @@
1
+ <script setup lang="ts">
2
+ import ChevronDown from './icons/ChevronDown.vue';
3
+ import ChevronUp from './icons/ChevronUp.vue';
4
+
5
+ const props = defineProps<{ collapsed: boolean }>();
6
+ </script>
7
+ <template>
8
+ <ChevronUp class="text-(--muted-foreground)" v-if="!props.collapsed"/>
9
+ <ChevronDown class="text-(--muted-foreground)" v-if="props.collapsed"/>
10
+ </template>
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeParsed, StoreState } from '../types';
4
+ import Badge from './Badge.vue';
5
+ import Minus from './icons/Minus.vue';
6
+ import Sun from './icons/Sun.vue';
7
+
8
+ const props = defineProps<{
9
+ state: StoreState;
10
+ scheme: SchemeParsed;
11
+ }>();
12
+
13
+ const badge = computed(() => {
14
+ return props.scheme.find((g) => g.title === 'Badge');
15
+ });
16
+ </script>
17
+ <template>
18
+ <div
19
+ class="flex items-center justify-between p-2 border-b-2 border-black
20
+ bg-white hover:bg-gray-200 select-none
21
+ dark:border-gray-700 dark:bg-zinc-800 dark:hover:bg-gray-600"
22
+ >
23
+ <div class="flex items-center gap-2">
24
+ <Badge :state="props.state" :group="badge" v-if="!!badge"/>
25
+ <span class="font-medium tracking-widest text-[14px]">Config</span>
26
+ </div>
27
+ <div class="flex gap-2 items-center">
28
+ <Sun
29
+ class="text-lg hover:text-gray-500 cursor-pointer"
30
+ @click="props.state.darkmode = !props.state.darkmode"
31
+ />
32
+ <Minus
33
+ class="text-lg hover:text-gray-500 cursor-pointer"
34
+ @click="props.state.hidden = !props.state.hidden"
35
+ />
36
+ </div>
37
+ </div>
38
+ </template>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import type { SchemeElement } from '../scheme/scheme-element';
3
+ import type { StoreState } from '../types';
4
+
5
+ const props = defineProps<{
6
+ state: StoreState;
7
+ element: SchemeElement;
8
+ }>();
9
+ </script>
10
+ <template>
11
+ <div class="col-span-2 pt-1">
12
+ <button
13
+ @click="props.element.callback"
14
+ class="w-full box-border border-2 border-black py-1 font-semibold text-[11px]
15
+ hover:bg-black hover:text-white transition-colors
16
+ dark:bg-gray-600 dark:border-zinc-800 dark:hover:bg-gray-500"
17
+ >
18
+ {{ props.element.name }}
19
+ </button>
20
+ </div>
21
+ </template>
@@ -0,0 +1,66 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeElement } from '../scheme/scheme-element';
4
+ import type { SchemeGroup, StoreState } from '../types';
5
+ import Chevron from './Chevron.vue';
6
+ import InputCheckbox from './inputs/InputCheckbox.vue';
7
+ import InputNumber from './inputs/InputNumber.vue';
8
+ import InputRange from './inputs/InputRange.vue';
9
+ import InputText from './inputs/InputText.vue';
10
+ import RowButton from './RowButton.vue';
11
+
12
+ const props = defineProps<{
13
+ state: StoreState;
14
+ group: SchemeGroup<SchemeElement>;
15
+ }>();
16
+
17
+ function switchCollapsed() {
18
+ props.state[props.group.id] = !props.state[props.group.id];
19
+ }
20
+
21
+ const collapsed = computed(() => !!props.state[props.group.id]);
22
+ </script>
23
+ <template>
24
+ <div
25
+ class="border-2 border-black
26
+ dark:border-gray-700 "
27
+ >
28
+ <div
29
+ @click="switchCollapsed"
30
+ class="border-b-2 border-black px-2 py-1 flex items-center gap-1
31
+ cursor-pointer bg-gray-50 hover:bg-gray-200
32
+ dark:border-gray-700 dark:bg-zinc-800 dark:hover:bg-gray-600"
33
+ >
34
+ <Chevron :collapsed="!collapsed" class="text-sm"/>
35
+ <span class="font-medium">{{ props.group.title }}</span>
36
+ </div>
37
+
38
+ <div
39
+ v-if="!collapsed"
40
+ class="p-2 grid grid-cols-[90px_1fr] gap-y-2 gap-x-2 items-center"
41
+ v-for="se in props.group.content"
42
+ >
43
+ <InputText :state="props.state" :element="se" v-if="se.type === 'text'"/>
44
+ <InputNumber
45
+ :state="props.state"
46
+ :element="se"
47
+ v-if="se.type === 'number'"
48
+ />
49
+ <InputCheckbox
50
+ :state=" props.state"
51
+ :element="se"
52
+ v-if="se.type === 'checkbox'"
53
+ />
54
+ <InputRange
55
+ :state="props.state"
56
+ :element="se"
57
+ v-if="se.type === 'range'"
58
+ />
59
+ <RowButton
60
+ :state="props.state"
61
+ :element="se"
62
+ v-if="se.type === 'button'"
63
+ />
64
+ </div>
65
+ </div>
66
+ </template>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ >
8
+ <path
9
+ fill="none"
10
+ stroke="currentColor"
11
+ strokeLinecap="round"
12
+ strokeLinejoin="round"
13
+ strokeWidth="2"
14
+ d="M20 6L9 17l-5-5"
15
+ ></path>
16
+ </svg>
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ >
8
+ <path
9
+ fill="none"
10
+ stroke="currentColor"
11
+ strokeLinecap="round"
12
+ strokeLinejoin="round"
13
+ strokeWidth="2"
14
+ d="m6 9l6 6l6-6"
15
+ ></path>
16
+ </svg>
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ >
8
+ <path
9
+ fill="none"
10
+ stroke="currentColor"
11
+ strokeLinecap="round"
12
+ strokeLinejoin="round"
13
+ strokeWidth="2"
14
+ d="m18 15l-6-6l-6 6"
15
+ ></path>
16
+ </svg>
17
+ </template>
@@ -0,0 +1,17 @@
1
+ <template>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ >
8
+ <path
9
+ fill="none"
10
+ stroke="currentColor"
11
+ stroke-linecap="round"
12
+ stroke-linejoin="round"
13
+ stroke-width="2"
14
+ d="M5 12h14"
15
+ />
16
+ </svg>
17
+ </template>
@@ -0,0 +1,21 @@
1
+ <template>
2
+ <svg
3
+ xmlns="http://www.w3.org/2000/svg"
4
+ width="24"
5
+ height="24"
6
+ viewBox="0 0 24 24"
7
+ >
8
+ <g
9
+ fill="none"
10
+ stroke="currentColor"
11
+ stroke-linecap="round"
12
+ stroke-linejoin="round"
13
+ stroke-width="2"
14
+ >
15
+ <circle cx="12" cy="12" r="4"/>
16
+ <path
17
+ d="M12 2v2m0 16v2M4.93 4.93l1.41 1.41m11.32 11.32l1.41 1.41M2 12h2m16 0h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"
18
+ />
19
+ </g>
20
+ </svg>
21
+ </template>
@@ -0,0 +1,29 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeElement } from '../../scheme/scheme-element';
4
+ import type { StoreState } from '../../types';
5
+ import Check from '../icons/Check.vue';
6
+
7
+ const props = defineProps<{
8
+ state: StoreState;
9
+ element: SchemeElement;
10
+ }>();
11
+
12
+ const name = computed(() => props.element.name as string);
13
+ </script>
14
+ <template>
15
+ <label>{{ props.element.label }}</label>
16
+ <label class="relative inline-flex items-center cursor-pointer">
17
+ <input type="checkbox" v-model="props.state[name]" class="peer sr-only">
18
+ <span
19
+ class="h-4 w-4 border-2 border-black flex items-center justify-center
20
+ peer-checked:bg-black
21
+ dark:peer-checked:bg-gray-600 dark:bg-zinc-700"
22
+ >
23
+ <Check
24
+ v-if="props.state[name]"
25
+ class="peer-checked:block text-black text-[12px] stroke-2"
26
+ />
27
+ </span>
28
+ </label>
29
+ </template>
@@ -0,0 +1,24 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeElement } from '../../scheme/scheme-element';
4
+ import type { StoreState } from '../../types';
5
+
6
+ const props = defineProps<{
7
+ state: StoreState;
8
+ element: SchemeElement;
9
+ }>();
10
+
11
+ const name = computed(() => props.element.name as string);
12
+ </script>
13
+ <template>
14
+ <label>{{ props.element.label }}</label>
15
+ <input
16
+ type="number"
17
+ v-model="props.state[name]"
18
+ class="w-full box-border border-2 px-1 py-1 focus:outline-none tw-input-colors"
19
+ :placeholder="props.element.placeholder || ''"
20
+ :min="props.element.min || ''"
21
+ :max="props.element.max || ''"
22
+ :step="props.element.step || ''"
23
+ >
24
+ </template>
@@ -0,0 +1,66 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeElement } from '../../scheme/scheme-element';
4
+ import type { StoreState } from '../../types';
5
+
6
+ const props = defineProps<{
7
+ state: StoreState;
8
+ element: SchemeElement;
9
+ }>();
10
+
11
+ const name = computed(() => props.element.name as string);
12
+ </script>
13
+ <template>
14
+ <label>{{ props.element.label }}</label>
15
+ <div class="flex items-center gap-1 w-full">
16
+ <input
17
+ type="range"
18
+ min="0"
19
+ max="100"
20
+ v-model="props.state[name]"
21
+ class="custom-range"
22
+ style="width: calc(100% - 30px);"
23
+ oninput="this.nextElementSibling.value = this.value"
24
+ >
25
+
26
+ <input
27
+ type="number"
28
+ v-model="props.state[name]"
29
+ class="w-20 box-border border-2 px-1 py-1 text-center focus:outline-none tw-input-colors"
30
+ oninput="this.previousElementSibling.value = this.value"
31
+ >
32
+ </div>
33
+ </template>
34
+
35
+ <style scoped>
36
+ .custom-range {
37
+ -webkit-appearance: none;
38
+ appearance: none;
39
+ height: 5px;
40
+ background: black;
41
+ cursor: pointer;
42
+ }
43
+
44
+ .custom-range::-webkit-slider-thumb {
45
+ -webkit-appearance: none;
46
+ appearance: none;
47
+ width: 12px;
48
+ height: 12px;
49
+ background: black;
50
+ border: 2px solid black;
51
+ cursor: pointer;
52
+ }
53
+
54
+ .custom-range::-moz-range-thumb {
55
+ width: 13px;
56
+ height: 13px;
57
+ background: black;
58
+ border: none;
59
+ border-radius: 0;
60
+ cursor: pointer;
61
+ }
62
+
63
+ input[type="number"]::-webkit-inner-spin-button {
64
+ -webkit-appearance: none;
65
+ }
66
+ </style>
@@ -0,0 +1,21 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+ import type { SchemeElement } from '../../scheme/scheme-element';
4
+ import type { StoreState } from '../../types';
5
+
6
+ const props = defineProps<{
7
+ state: StoreState;
8
+ element: SchemeElement;
9
+ }>();
10
+
11
+ const name = computed(() => props.element.name as string);
12
+ </script>
13
+ <template>
14
+ <label>{{ props.element.label }}</label>
15
+ <input
16
+ type="text"
17
+ v-model="props.state[name]"
18
+ class="w-full box-border border-2 px-1 py-1 focus:outline-none tw-input-colors"
19
+ :placeholder="props.element.placeholder || ''"
20
+ >
21
+ </template>
package/src/index.ts CHANGED
@@ -1,17 +1,4 @@
1
- import './style.css'
2
- export { JabroniOutfitStore } from "./store/store";
3
- export {
4
- defaultStateWithDurationAndPrivacy,
5
- defaultStateInclExclMiscPagination,
6
- defaultStateWithDuration,
7
- defaultStateWithDurationAndHD,
8
- defaultStateWithDurationAndPrivacyAndHD,
9
- } from "./store/default-state";
10
- export { JabroniOutfitUI } from "./ui";
11
- export {
12
- defaultSchemeWithPrivacyFilter,
13
- defaultSchemeWithPrivacyFilterWithHD,
14
- defaultSchemeWithPrivacyFilterWithHDwithSort,
15
- DefaultScheme,
16
- extendScheme
17
- } from "./ui/default-scheme";
1
+ export { JabronioGUI } from './app';
2
+ export { setupScheme } from './scheme/default-scheme';
3
+ export { JabronioStore } from './store';
4
+ export type { SchemeInput } from './types';