@exakt/ui 0.0.64 → 0.0.67

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/dist/module.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "exakt-ui",
3
3
  "configKey": "exakt",
4
- "version": "0.0.64"
4
+ "version": "0.0.67"
5
5
  }
package/dist/module.mjs CHANGED
@@ -54,7 +54,9 @@ const module = defineNuxtModule({
54
54
  SCSSvariables += `$root-hue: ${options.hue}; `;
55
55
  for (const mode of ["light", "dark"]) {
56
56
  SCSSvariables += `$root-colors-${mode}: (`;
57
- for (const [key, value] of Object.entries(options.colors[mode])) {
57
+ for (const [key, value] of Object.entries(
58
+ options.colors[mode]
59
+ )) {
58
60
  SCSSvariables += `"${key}": ${value}, `;
59
61
  }
60
62
  SCSSvariables += ");";
@@ -15,7 +15,7 @@
15
15
  loading,
16
16
  fab,
17
17
  compact,
18
- ...backgroundClass
18
+ ...backgroundClass,
19
19
  }"
20
20
  >
21
21
  <div
@@ -42,7 +42,7 @@
42
42
  </component>
43
43
  </template>
44
44
  <script lang="ts" setup>
45
- import { computed, useNuxtApp, } from "#imports";
45
+ import { computed, useNuxtApp } from "#imports";
46
46
  const { $exakt } = useNuxtApp();
47
47
  const props = withDefaults(
48
48
  defineProps<{
@@ -71,8 +71,8 @@ const props = withDefaults(
71
71
  compact: false,
72
72
  align: "center",
73
73
  color: undefined,
74
- button: true
75
- }
74
+ button: true,
75
+ },
76
76
  );
77
77
 
78
78
  function parseColor(input: string) {
@@ -93,28 +93,33 @@ const backgroundColorRgb = computed(() => {
93
93
  return parseColor($exakt.parseColor(props.background));
94
94
  });
95
95
 
96
- const isRootColor = computed(() => $exakt && $exakt.rootColors && $exakt.rootColors.includes(props.background))
96
+ const isRootColor = computed(
97
+ () =>
98
+ $exakt && $exakt.rootColors && $exakt.rootColors.includes(props.background),
99
+ );
97
100
  const backgroundClass = computed(() => {
98
- const c: { [key: string]: boolean } = {}
101
+ const c: { [key: string]: boolean } = {};
99
102
 
100
- if (props.background == 'transparent') {
101
- c['transparent'] = true;
103
+ if (props.background == "transparent") {
104
+ c["transparent"] = true;
102
105
  } else if (isRootColor.value) {
103
- c["bg-" + props.background] = true
106
+ c["bg-" + props.background] = true;
104
107
  } else {
105
- c['custom-color'] = true
108
+ c["custom-color"] = true;
106
109
  }
107
110
 
108
- return c
109
- })
111
+ return c;
112
+ });
110
113
  const backgroundColor = computed(() => {
111
- if (isRootColor.value) { return 'unset' } else {
112
- return props.background
114
+ if (isRootColor.value) {
115
+ return "unset";
116
+ } else {
117
+ return props.background;
113
118
  }
114
- })
119
+ });
115
120
  const textColor = computed(() => {
116
121
  if (isRootColor.value) {
117
- return 'unset';
122
+ return "unset";
118
123
  }
119
124
  if (props.color) {
120
125
  return props.color;
@@ -125,7 +130,7 @@ const textColor = computed(() => {
125
130
  const rgb = backgroundColorRgb.value;
126
131
 
127
132
  const brightness = Math.round(
128
- (299 * rgb.r + 224490 + 587 * rgb.g + 114 * rgb.b) / 2000
133
+ (299 * rgb.r + 224490 + 587 * rgb.g + 114 * rgb.b) / 2000,
129
134
  );
130
135
  if (brightness > 150) {
131
136
  // Dark Text
@@ -133,8 +138,6 @@ const textColor = computed(() => {
133
138
  }
134
139
  return "#FFFFFF";
135
140
  });
136
-
137
-
138
141
  </script>
139
142
  <style lang="scss" scoped>
140
143
  .e-btn-content {
@@ -165,7 +168,10 @@ const textColor = computed(() => {
165
168
  cursor: pointer;
166
169
  flex-shrink: 1;
167
170
  position: relative;
168
- transition: background 0.4s, color 0.3s, opacity 0.4s;
171
+ transition:
172
+ background 0.4s,
173
+ color 0.3s,
174
+ opacity 0.4s;
169
175
  white-space: nowrap;
170
176
  font-family: var(--e-font-family);
171
177
  box-sizing: border-box;
@@ -264,7 +270,6 @@ const textColor = computed(() => {
264
270
  }
265
271
  }
266
272
 
267
-
268
273
  .load-overlay {
269
274
  position: absolute;
270
275
  top: 0;
@@ -3,9 +3,14 @@
3
3
  <!-- class="flex-stretch fullwidth" -->
4
4
  <div
5
5
  ref="activator"
6
+ class="flex-1"
6
7
  @click="onActivatorClick"
7
8
  >
8
- <slot />
9
+ <slot
10
+ :current-item="
11
+ typeof currentItem == 'number' ? items[currentItem] : undefined
12
+ "
13
+ />
9
14
  </div>
10
15
  <e-focus-sheet v-model="visibleComputed" />
11
16
  <e-tr-scale>
@@ -15,6 +20,12 @@
15
20
  class="list bg-elev-2 rounded"
16
21
  :style="{ position: fixed ? 'fixed' : undefined }"
17
22
  >
23
+ <div
24
+ v-if="title"
25
+ class="mx-4 my-2 fullwidth text-secondary"
26
+ >
27
+ {{ title }}
28
+ </div>
18
29
  <component
19
30
  :is="item.to ? EUndecoratedLink : item.href ? 'a' : 'div'"
20
31
  v-for="(item, i) in items"
@@ -30,8 +41,8 @@
30
41
  :solid="false"
31
42
  :background="item.background || 'transparent'"
32
43
  :class="{
33
- 'rounded-top': i === 0,
34
- 'rounded-bottom': i === items.length - 1,
44
+ 'rounded-top': i === 0 && !title,
45
+ 'rounded-bottom': i === items.length - 1 && !hint,
35
46
  active: currentItem === i,
36
47
  }"
37
48
  @click="select(i)"
@@ -68,15 +79,18 @@ interface DropdownItem {
68
79
  callback?: () => void;
69
80
  color?: string;
70
81
  background?: string;
82
+ id?: string | number;
71
83
  }
72
84
 
73
85
  const props = withDefaults(
74
86
  defineProps<{
75
- modelValue?: number;
87
+ modelValue?: number | string;
76
88
  width?: string | "100%";
77
89
  center?: boolean;
78
90
  items: DropdownItem[];
79
91
  hint?: string;
92
+ title?: string;
93
+ useIds?: boolean;
80
94
  visible?: boolean | null;
81
95
  fixed?: boolean;
82
96
  }>(),
@@ -87,6 +101,9 @@ const props = withDefaults(
87
101
  modelValue: undefined,
88
102
  position: undefined,
89
103
  width: undefined,
104
+ useIds: false,
105
+ hint: undefined,
106
+ title: undefined,
90
107
  },
91
108
  );
92
109
 
@@ -123,7 +140,6 @@ const updatePosition = async () => {
123
140
  state.x = 0;
124
141
 
125
142
  //Too far right :(
126
- console.log(list.value);
127
143
  if (list.value) {
128
144
  if (window?.innerWidth > list.value?.getBoundingClientRect().right) {
129
145
  state.x = -1 * activatorRect.width;
@@ -153,6 +169,10 @@ watch(
153
169
  state.x =
154
170
  window?.innerWidth - newList.getBoundingClientRect().right - 15;
155
171
  }
172
+ if (window?.innerHeight < newList.getBoundingClientRect().bottom) {
173
+ const { bottom, top } = newList.getBoundingClientRect();
174
+ state.y = window?.innerHeight - bottom;
175
+ }
156
176
  }
157
177
  },
158
178
  );
@@ -171,8 +191,12 @@ watch(visibleComputed, (value) => {
171
191
  const emit = defineEmits(["update:modelValue", "update:visible"]);
172
192
 
173
193
  const currentItem = computed({
174
- get: () => props.modelValue,
175
- set: (value) => emit("update:modelValue", value),
194
+ get: () =>
195
+ props.useIds
196
+ ? props.items.findIndex(({ id }) => props.modelValue == id)
197
+ : props.modelValue,
198
+ set: (value: number) =>
199
+ emit("update:modelValue", props.useIds ? props.items[value]?.id : value),
176
200
  });
177
201
 
178
202
  const select = (i: number) => {
@@ -216,7 +240,7 @@ a {
216
240
  // color: var(--e-color-text);
217
241
  font-size: 1rem;
218
242
  padding: 0.7rem;
219
- text-transform: capitalize;
243
+ // text-transform: capitalize;
220
244
  position: relative;
221
245
  white-space: nowrap;
222
246
  &:hover {
@@ -11,19 +11,22 @@ import { computed } from "#imports";
11
11
 
12
12
  const props = withDefaults(
13
13
  defineProps<{
14
- iconStyle?: 'outlined' | 'rounded' | 'sharp', size?: number|`${number}`, fill?:boolean|"0"|"1"|`${boolean}`, grade?:number|`${number}`, weight?: number|`${number}`
14
+ iconStyle?: "outlined" | "rounded" | "sharp";
15
+ size?: number | `${number}`;
16
+ fill?: boolean | "0" | "1" | `${boolean}`;
17
+ grade?: number | `${number}`;
18
+ weight?: number | `${number}`;
15
19
  }>(),
16
- { iconStyle: 'outlined', size: 24, fill:true, weight: 400, grade:0}
20
+ { iconStyle: "outlined", size: 24, fill: true, weight: 400, grade: 0 },
17
21
  );
18
22
 
19
- const sizePx = computed(() => props.size + "px")
20
- const fillNum = computed(()=> {
21
- if([true, "true", "1"].includes(props.fill)){
23
+ const sizePx = computed(() => props.size + "px");
24
+ const fillNum = computed(() => {
25
+ if ([true, "true", "1"].includes(props.fill)) {
22
26
  return 1;
23
27
  }
24
28
  return 0;
25
- })
26
-
29
+ });
27
30
  </script>
28
31
  <style lang="scss">
29
32
  .material-symbol {
@@ -37,26 +40,30 @@ const fillNum = computed(()=> {
37
40
  word-wrap: normal;
38
41
  white-space: nowrap;
39
42
  direction: ltr;
40
-
43
+ user-select: none;
41
44
  }
42
45
 
43
46
  .material-symbol[icon-style="outlined"] {
44
- font-family: 'Material Symbols Outlined';
47
+ font-family: "Material Symbols Outlined";
45
48
  }
46
49
 
47
50
  .material-symbol[icon-style="rounded"] {
48
- font-family: 'Material Symbols Rounded';
51
+ font-family: "Material Symbols Rounded";
49
52
  }
50
53
 
51
54
  .material-symbol[icon-style="sharp"] {
52
- font-family: 'Material Symbols Sharp';
55
+ font-family: "Material Symbols Sharp";
53
56
  }
54
57
  </style>
55
58
  <style scoped lang="scss">
56
59
  .material-symbol {
57
- font-size: v-bind('sizePx');
58
- width: v-bind('sizePx');
59
- height: v-bind('sizePx');
60
- font-variation-settings: 'FILL' v-bind('fillNum'), 'wght' v-bind('props.weight'), 'GRAD' v-bind('props.grade'), 'opsz' v-bind('props.size');
60
+ font-size: v-bind("sizePx");
61
+ width: v-bind("sizePx");
62
+ height: v-bind("sizePx");
63
+ font-variation-settings:
64
+ "FILL" v-bind("fillNum"),
65
+ "wght" v-bind("props.weight"),
66
+ "GRAD" v-bind("props.grade"),
67
+ "opsz" v-bind("props.size");
61
68
  }
62
- </style>
69
+ </style>
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <e-input-text
3
+ type="number"
4
+ v-bind="{ ...props, modelValue: props.modelValue?.toString() }"
5
+ @update:model-value="updateNum($event)"
6
+ />
7
+ </template>
8
+ <script lang="ts" setup>
9
+ const props = withDefaults(
10
+ defineProps<{
11
+ icon?: string;
12
+ label?: string;
13
+ placeholder?: string;
14
+ name?: string;
15
+ modelValue?: number;
16
+ defaultValue?: string;
17
+ solid?: boolean;
18
+ rounded?: boolean;
19
+ autocomplete?: string;
20
+ disabled?: boolean;
21
+ required?: boolean;
22
+ focus?: boolean;
23
+ spellcheck?: boolean;
24
+ height?: string;
25
+ width?: string;
26
+ compact?: boolean;
27
+ }>(),
28
+ {
29
+ icon: undefined,
30
+ label: "",
31
+ solid: true,
32
+ modelValue: undefined,
33
+ autocomplete: "off",
34
+ height: "unset",
35
+ width: "100%",
36
+ compact: false,
37
+ rounded: undefined,
38
+ placeholder: undefined,
39
+ name: undefined,
40
+ defaultValue: undefined,
41
+ },
42
+ );
43
+
44
+ const emit = defineEmits(["update:model-value", "update:validity"]);
45
+ const updateNum = (newValue: string) => {
46
+ const parsed = Number.parseInt(newValue);
47
+ if (Number.isNaN(parsed)) {
48
+ emit("update:validity", false);
49
+ return;
50
+ }
51
+
52
+ emit("update:validity", true);
53
+ emit("update:model-value", parsed);
54
+ };
55
+ </script>
@@ -0,0 +1,95 @@
1
+ <template>
2
+ <div
3
+ v-if="label"
4
+ class="my-3"
5
+ >
6
+ <label> {{ label }} </label>
7
+ </div>
8
+ <e-dropdown
9
+ v-slot="{ currentItem }"
10
+ :items="items"
11
+ :visible="focus"
12
+ :width="width"
13
+ :model-value="props.modelValue"
14
+ :use-ids="useIds"
15
+ @update:model-value="emit('update:modelValue', $event)"
16
+ @update:visible="focus = $event"
17
+ >
18
+ <div
19
+ :class="{ focus }"
20
+ class="btn rounded"
21
+ >
22
+ <div class="d-flex justify-space-between">
23
+ <div
24
+ v-if="currentItem"
25
+ class="flex-center"
26
+ >
27
+ <e-icon
28
+ v-if="currentItem?.icon"
29
+ size="20"
30
+ class="mr-2"
31
+ >
32
+ {{ currentItem?.icon }}
33
+ </e-icon>
34
+ {{ currentItem?.name }}
35
+ </div>
36
+ <div v-else />
37
+ <e-icon
38
+ class="text-secondary ml-1"
39
+ size="20"
40
+ >
41
+ arrow_drop_down
42
+ </e-icon>
43
+ </div>
44
+ </div>
45
+ </e-dropdown>
46
+ </template>
47
+ <script setup lang="ts">
48
+ import { ref } from "#imports";
49
+ const focus = ref(false);
50
+
51
+ interface DropdownItem {
52
+ name: string;
53
+ icon?: string;
54
+ href?: string;
55
+ to?: string;
56
+ callback?: () => void;
57
+ color?: string;
58
+ background?: string;
59
+ }
60
+
61
+ const emit = defineEmits(["update:modelValue"]);
62
+
63
+ const props = withDefaults(
64
+ defineProps<{
65
+ items: DropdownItem[] | [];
66
+ label?: string;
67
+ useIds?: boolean;
68
+ modelValue: number | undefined;
69
+ width?: string | "100%";
70
+ }>(),
71
+ {
72
+ items: () => [],
73
+ modelValue: undefined,
74
+ label: undefined,
75
+ useIds: false,
76
+ },
77
+ );
78
+ </script>
79
+ <style lang="scss" scoped>
80
+ .btn {
81
+ outline: var(--e-color-i-outline) solid 0.1rem;
82
+ transition:
83
+ outline ease-in-out 0.15s,
84
+ background-color ease-in-out 0.15s;
85
+ margin: 0.125rem;
86
+ user-select: none;
87
+ cursor: pointer;
88
+ padding: 0.7rem 0.9rem;
89
+ width: v-bind("props.width");
90
+ background-color: var(--e-color-i-depressed);
91
+ &.focus {
92
+ outline: var(--e-color-primary) solid 0.125rem;
93
+ }
94
+ }
95
+ </style>
@@ -11,8 +11,6 @@ defineProps<{
11
11
  //const colorFromScriptSetup = "green";
12
12
  </script>
13
13
  <style lang="scss" scoped>
14
-
15
-
16
14
  nav {
17
15
  z-index: 5;
18
16
  min-height: 3.5rem;
@@ -21,7 +19,9 @@ nav {
21
19
  overflow-y: none;
22
20
  display: flex;
23
21
  align-items: center;
24
- // position: sticky;
22
+ gap: 0.4rem;
23
+
24
+ // position: sticky;
25
25
  top: 0;
26
26
  left: 0;
27
27
  }
@@ -31,7 +31,6 @@ nav.fixed {
31
31
  width: 100%;
32
32
  }
33
33
 
34
-
35
34
  @media screen and (max-width: exakt.$e-md-screen-breakpoint) {
36
35
  nav {
37
36
  position: fixed;
@@ -41,9 +40,9 @@ nav.fixed {
41
40
  width: 100%;
42
41
  justify-content: stretch;
43
42
  margin: 0 !important;
44
- padding: 0.2rem 0.6rem calc(0.2rem + env(safe-area-inset-bottom)) 0.6rem ;
43
+ padding: 0.2rem 0.6rem calc(0.2rem + env(safe-area-inset-bottom)) 0.6rem;
44
+ gap: 0.2rem;
45
45
  background: var(--e-color-elev);
46
46
  }
47
47
  }
48
-
49
48
  </style>
@@ -23,8 +23,9 @@
23
23
  >
24
24
  <e-icon
25
25
  class="icon"
26
- :size="label ? 20 : 25"
27
26
  :fill="active"
27
+ icon-style="outlined"
28
+ :size="label ? 20 : 25"
28
29
  >
29
30
  {{ icon }}
30
31
  </e-icon>
@@ -54,6 +55,7 @@ const props = withDefaults(
54
55
  icon?: string;
55
56
  alert?: boolean;
56
57
  responsive?: boolean;
58
+ excludeActive?: string[];
57
59
  }>(),
58
60
  { to: "", label: "", icon: "", responsive: true },
59
61
  );
@@ -61,7 +63,23 @@ const props = withDefaults(
61
63
  const route = useRoute();
62
64
 
63
65
  const active = computed(() => {
64
- return route && route.path && route.path.startsWith(props.to);
66
+ if (props.to == "/") {
67
+ return route.path == "/";
68
+ }
69
+ if (!route || !route.path) {
70
+ return false;
71
+ }
72
+
73
+ let excluded = false;
74
+ if (props.excludeActive) {
75
+ for (const e of props.excludeActive) {
76
+ if (route.path.startsWith(e)) {
77
+ excluded = true;
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ return !excluded && route.path.startsWith(props.to);
65
83
  });
66
84
  </script>
67
85
 
@@ -126,7 +144,7 @@ a {
126
144
  p {
127
145
  margin: 0px;
128
146
  white-space: nowrap;
129
- font-size: small;
147
+ font-size: 0.6rem;
130
148
  }
131
149
  }
132
150
  }
@@ -9,8 +9,8 @@ b, u, i, center,
9
9
  dl, dt, dd, ol, ul, li,
10
10
  fieldset, form, label, legend,
11
11
  table, caption, tbody, tfoot, thead, tr, th, td,
12
- article, aside, canvas, details, embed,
13
- figure, figcaption, footer, header, hgroup,
12
+ article, aside, canvas, details, embed,
13
+ figure, figcaption, footer, header, hgroup,
14
14
  menu, nav, output, ruby, section, summary,
15
15
  time, mark, audio, video {
16
16
  margin: 0;
@@ -103,10 +103,13 @@ a {
103
103
 
104
104
  $full: 0;
105
105
  $factor: 1;
106
+ $elev-factor: 1;
106
107
 
107
108
  @if $light ==1 {
108
109
  $full: 100;
109
110
  $factor: -1;
111
+ $elev-factor: -0.1;
112
+
110
113
  }
111
114
  $color-map: map.set($color-map, "source", $source);
112
115
 
@@ -125,9 +128,9 @@ a {
125
128
  $color-map: map.set($color-map, "fg", color.adjust($source, $lightness: 2%));
126
129
 
127
130
 
128
- $color-map: map.set($color-map, "elev", color.scale(map.get($color-map, "fg"), $lightness: $lightness*0.25));
129
- $color-map: map.set($color-map, "elev-2", color.scale(map.get($color-map, "fg"), $lightness: $lightness*0.5));
130
- $color-map: map.set($color-map, "elev-3", color.scale(map.get($color-map, "fg"), $lightness: $lightness));
131
+ $color-map: map.set($color-map, "elev", color.scale(map.get($color-map, "fg"), $lightness: $lightness*$elev-factor*0.25));
132
+ $color-map: map.set($color-map, "elev-2", color.scale(map.get($color-map, "fg"), $lightness: $lightness*$elev-factor*0.5));
133
+ $color-map: map.set($color-map, "elev-3", color.scale(map.get($color-map, "fg"), $lightness: $lightness*$elev-factor));
131
134
 
132
135
 
133
136
 
@@ -144,7 +147,7 @@ a {
144
147
  color-scheme: light;
145
148
  }
146
149
 
147
- @include elev(95%,1, 1, exakt.$root-colors-light);
150
+ @include elev(98%,1, 1, exakt.$root-colors-light);
148
151
 
149
152
 
150
153
  @media (prefers-color-scheme: dark) {
@@ -155,4 +158,4 @@ a {
155
158
  @include elev(8%,1,0, exakt.$root-colors-dark);
156
159
 
157
160
 
158
- }
161
+ }
@@ -33,7 +33,15 @@ export default defineNuxtPlugin(() => {
33
33
  }
34
34
  return p;
35
35
  },
36
- rootColors: ["primary", "red", "text", "yellow", "elev", "i"],
36
+ rootColors: [
37
+ "primary",
38
+ "red",
39
+ "text",
40
+ "yellow",
41
+ "elev",
42
+ "i",
43
+ "i-depressed"
44
+ ],
37
45
  isRootColor: (c) => ["primary", "red", "text", "yellow", "elev", "i"].includes(c),
38
46
  /**
39
47
  * Generates an alphanumeric ID of a given length.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@exakt/ui",
3
- "version": "0.0.64",
3
+ "version": "0.0.67",
4
4
  "description": "A UI library for Nuxt.js",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -34,9 +34,9 @@
34
34
  },
35
35
  "devDependencies": {
36
36
  "@nuxt/eslint-config": "^0.1.1",
37
- "@nuxt/kit": "^3.16.2",
37
+ "@nuxt/kit": "^4.1.3",
38
38
  "@nuxt/module-builder": "^0.2.1",
39
- "@nuxt/schema": "^3.16.2",
39
+ "@nuxt/schema": "^4.1.3",
40
40
  "@nuxt/test-utils": "^3.2.3",
41
41
  "@types/lodash": "^4.14.191",
42
42
  "@types/lodash-es": "^4.17.9",
@@ -45,7 +45,7 @@
45
45
  "eslint": "^8.35.0",
46
46
  "eslint-plugin-unused-imports": "^3.0.0",
47
47
  "mkdist": "^1.2.0",
48
- "nuxt": "^3.16.2",
48
+ "nuxt": "^4.1.3",
49
49
  "vitest": "^0.29.2"
50
50
  },
51
51
  "directories": {