@exakt/ui 0.0.1 → 0.0.3

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.d.ts CHANGED
@@ -14,6 +14,7 @@ interface ModuleOptions {
14
14
  xl?: string;
15
15
  };
16
16
  borderRadius: string;
17
+ corePaddingX: string;
17
18
  font: string;
18
19
  }
19
20
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions>;
package/dist/module.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "exakt-ui",
3
3
  "configKey": "exakt",
4
- "version": "0.0.1"
4
+ "version": "0.0.3"
5
5
  }
package/dist/module.mjs CHANGED
@@ -15,6 +15,7 @@ const defaults = {
15
15
  xl: "60em"
16
16
  },
17
17
  borderRadius: "8px",
18
+ corePaddingX: "1rem",
18
19
  font: "Roboto, sans-serif"
19
20
  };
20
21
  const module = defineNuxtModule({
@@ -27,21 +28,30 @@ const module = defineNuxtModule({
27
28
  async setup(options, nuxt) {
28
29
  const resolver = createResolver(import.meta.url);
29
30
  addPlugin(resolver.resolve("./runtime/plugin"));
30
- await fs.promises.mkdir("node_modules/.cache/exakt-ui", {
31
- recursive: true
32
- });
33
- let variables = "";
31
+ await fs.promises.mkdir(
32
+ resolver.resolve("../node_modules/.cache/exakt-ui"),
33
+ {
34
+ recursive: true
35
+ }
36
+ );
37
+ let SCSSvariables = "";
38
+ let CSSvariables = ":root{";
34
39
  for (const [key, value] of Object.entries(options.colors)) {
35
- variables += `$root-${key}: ${value}; `;
40
+ SCSSvariables += `$root-${key}: ${value}; `;
36
41
  }
37
42
  for (const [key, value] of Object.entries(options.breakpoints)) {
38
- variables += `$${key}-screen-breakpoint: ${value}; `;
43
+ CSSvariables += `--e-${key}-screen-breakpoint: ${value}; `;
39
44
  }
40
- variables += `$font-family: ${options.font}; `;
41
- variables += `$rounded-border-radius: ${options.borderRadius}; `;
45
+ CSSvariables += `--e-font-family: ${options.font}; `;
46
+ CSSvariables += `--e-rounded-border-radius: ${options.borderRadius}; `;
47
+ CSSvariables += `--e-core-padding-x: ${options.corePaddingX}; `;
48
+ await fs.promises.writeFile(
49
+ resolver.resolve("../node_modules/.cache/exakt-ui/variables.scss"),
50
+ new Uint8Array(Buffer.from(SCSSvariables))
51
+ );
42
52
  await fs.promises.writeFile(
43
- "node_modules/.cache/exakt-ui/variables.scss",
44
- new Uint8Array(Buffer.from(variables))
53
+ resolver.resolve("../node_modules/.cache/exakt-ui/variables.css"),
54
+ new Uint8Array(Buffer.from(CSSvariables + "}"))
45
55
  );
46
56
  extendViteConfig((config) => {
47
57
  Object.assign(config, {
@@ -56,8 +66,18 @@ const module = defineNuxtModule({
56
66
  }
57
67
  });
58
68
  });
59
- nuxt.options.css.push(resolver.resolve("./css/main.scss"));
60
- addComponentsDir({ path: resolver.resolve("./components") });
69
+ await fs.promises.copyFile(
70
+ resolver.resolve("./runtime/css/main.scssx"),
71
+ resolver.resolve("../node_modules/.cache/exakt-ui/main.scss")
72
+ );
73
+ nuxt.options.css.push(
74
+ resolver.resolve("../node_modules/.cache/exakt-ui/main.scss")
75
+ );
76
+ nuxt.options.css.push(resolver.resolve("./runtime/css/util.css"));
77
+ nuxt.options.css.push(
78
+ resolver.resolve("../node_modules/.cache/exakt-ui/variables.css")
79
+ );
80
+ addComponentsDir({ path: resolver.resolve("./runtime/components") });
61
81
  }
62
82
  });
63
83
 
@@ -0,0 +1,9 @@
1
+ <template>
2
+ <div class="flex-center color-red">
3
+ <e-icon :icon="mdiAlert" size="19" class="mr-2"></e-icon
4
+ ><small><slot /></small>
5
+ </div>
6
+ </template>
7
+ <script setup lang="ts">
8
+ import { mdiAlert } from "@mdi/js";
9
+ </script>
@@ -0,0 +1,116 @@
1
+ <template>
2
+
3
+ <div class="title-bar">
4
+ <e-progress-linear :model-value="props.loading" />
5
+ <div class="pf-wrap">
6
+ <slot name="left"></slot>
7
+ </div>
8
+ <slot name="center"></slot>
9
+
10
+ <div class="pf-wrap">
11
+ <slot name="right"></slot>
12
+ </div>
13
+ </div>
14
+
15
+ <div class="bar-container">
16
+ <e-container class="bar-e-container" :forceFullWidth="true">
17
+ <div class="rounded bar">
18
+ <e-progress-linear :model-value="props.loading" class="md-and-up-only" />
19
+
20
+ <div class="md-and-up-only flex-stretch">
21
+ <slot name="center"></slot>
22
+ </div>
23
+ <slot name="nav-items"></slot>
24
+ <div class="md-and-up-only flex-stretch">
25
+ <slot name="right" class="fullwidth"></slot>
26
+ </div>
27
+ </div>
28
+ </e-container>
29
+ </div>
30
+
31
+ </template>
32
+ <script setup lang="ts">
33
+
34
+ const props = withDefaults(
35
+ defineProps<{
36
+ loading?: boolean
37
+ }>(),
38
+ { loading:false }
39
+ );
40
+
41
+ const { $store, $platform } = useNuxtApp();
42
+
43
+ </script>
44
+
45
+ <style scoped>
46
+ .title-bar {
47
+ display: none;
48
+ position: relative;
49
+ }
50
+
51
+ .bar {
52
+ display: flex;
53
+ justify-content: flex-start;
54
+ justify-items: flex-start;
55
+ background-color: var(--e-color-elev-2);
56
+ width: 100%;
57
+ overflow: clip;
58
+ position: relative;
59
+ }
60
+
61
+ .bar-container {
62
+ width: 100%;
63
+ top: 1rem;
64
+ height: 4rem;
65
+ padding-bottom: 1rem;
66
+ display: flex;
67
+ justify-content: center;
68
+ position: sticky;
69
+ align-self: flex-start;
70
+ z-index: 4;
71
+ }
72
+
73
+ @media screen and (max-width: var(--e-md-screen-breakpoint)) {
74
+ .title-bar {
75
+ display: unset;
76
+ top: 0px;
77
+ left: 0px;
78
+ height: 4rem;
79
+ width: 100%;
80
+ z-index: 4;
81
+ background-color: var(--e-color-elev-2);
82
+ position: fixed;
83
+ display: flex;
84
+ justify-content: space-between;
85
+ align-content: stretch;
86
+ justify-items: space-between;
87
+ align-items: stretch;
88
+ }
89
+ .title-bar .pf-wrap {
90
+ display: flex;
91
+ align-items: stretch;
92
+ width: 5rem;
93
+ }
94
+ .md-and-up-only {
95
+ display: none;
96
+ }
97
+ .bar-container {
98
+ bottom: 0px;
99
+ left: 0px;
100
+ top: unset;
101
+ position: fixed;
102
+ padding: 0px;
103
+ z-index: 3;
104
+ }
105
+ .bar-e-container {
106
+ padding: 0px;
107
+ margin: 0px;
108
+ }
109
+ .bar {
110
+ border-radius: 0px;
111
+ width: 100%;
112
+ height: 100%;
113
+ padding-bottom: calc(env(safe-area-insee-bottom));
114
+ }
115
+ }
116
+ </style>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div class="flex-center a-container">
3
+ <slot />
4
+ <e-image-lazy-view
5
+ v-if="src"
6
+ class="avatar"
7
+ :width="size"
8
+ :height="size"
9
+ :contain="true"
10
+ :immediate-render="true"
11
+ :src="src"
12
+ border-radius="100%"
13
+ />
14
+ <div v-else><e-icon :size="size" :icon="mdiAccountCircle"></e-icon></div>
15
+ </div>
16
+ </template>
17
+ <script setup lang="ts">
18
+ import { mdiAccountCircle } from "@mdi/js";
19
+ const size = 120;
20
+
21
+ defineProps<{
22
+ src?: string;
23
+ }>();
24
+ </script>
25
+ <style scoped>
26
+ .avatar {
27
+ border-radius: 100%;
28
+ width: fie-content;
29
+ height: fie-content;
30
+ background-color: var(--e-color-elev);
31
+ }
32
+
33
+ .a-container {
34
+ position: relative;
35
+ }
36
+ </style>
@@ -0,0 +1,232 @@
1
+ <template>
2
+ <button class="e-btn " :style="{ width, justifyContent: justifyWrapper }" :type="type" :disabled="disabled || loading"
3
+ :class="{
4
+ active,
5
+ inactive,
6
+ solid,
7
+ block,
8
+ rounded: solid,
9
+ 'e-disabled': disabled,
10
+ 'my-2':solid,
11
+ loading,
12
+ fab,
13
+ loadingGradient,
14
+ colored: background !== 'transparent' || color || solid,
15
+ }">
16
+ <e-progress-gradient class="prog-grad" color="primary" v-if="loading && loadingGradient" />
17
+
18
+ <div ref="content" class="e-btn-content" :style="contentStyles">
19
+
20
+ <div class="load-overlay" v-if="loading && !loadingGradient">
21
+ <e-loading-spinner />
22
+
23
+ </div>
24
+ <span class="actual-content flex-center">
25
+
26
+ <slot />
27
+ </span>
28
+ </div>
29
+ </button>
30
+ </template>
31
+ <script lang="ts" setup>
32
+ import { computed, reactive, ref, onMounted } from "vue";
33
+ //import { IonSpinner } from "@ionic/vue";
34
+ const { $exakt } = useNuxtApp();
35
+ const props = withDefaults(
36
+ defineProps<{
37
+ width?: number | string;
38
+ justify?: string;
39
+ active?: boolean;
40
+ inactive?: boolean;
41
+ solid?: boolean;
42
+ color?: string;
43
+ background?: string;
44
+ block?: boolean;
45
+ loading?: boolean;
46
+ loadingGradient?: boolean;
47
+ fab?: boolean;
48
+ disabled?: boolean;
49
+ to?: string;
50
+ type?: "button" | "submit" | "reset";
51
+ }>(),
52
+ { type: "button", background: "primary", solid: true }
53
+ );
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ const justifyWrapper = computed(() => {
62
+ if (props.justify === "space-between") {
63
+ return "stretch";
64
+ }
65
+ return props.justify;
66
+ });
67
+
68
+ const contentStyles = computed(() => {
69
+ if (props.justify === "space-between") {
70
+ return "justify-content:space-between; flex-grow: 1";
71
+ }
72
+
73
+ return "";
74
+ });
75
+
76
+ function parseColor(input: string) {
77
+ const div = document.createElement("div");
78
+ document.body.appendChild(div);
79
+ div.style.color = input;
80
+ const c = getComputedStyle(div).color as any;
81
+ const res = c.match(/[.\d]+/g).map(Number);
82
+
83
+ div.remove();
84
+ return { r: res[0], g: res[1], b: res[2] };
85
+ }
86
+
87
+ const backgroundColorRgb = computed(() => {
88
+ if (!props.background || process.server) {
89
+ return { r: 0, g: 0, b: 0 };
90
+ }
91
+ return parseColor(parsedBackgroundProp.value);
92
+ });
93
+
94
+ const parsedBackgroundProp = computed(() => $exakt.parseColor(props.background));
95
+
96
+ const textColor = computed(() => {
97
+ if (props.color) {
98
+ return props.color;
99
+ }
100
+
101
+ const rgb = backgroundColorRgb.value;
102
+
103
+ const brightness = Math.round(
104
+ (299 * rgb.r + 224490 + 587 * rgb.g + 114 * rgb.b) / 2000
105
+ );
106
+ if (brightness > 150) {
107
+ // Dark Text
108
+ return "#000000";
109
+ }
110
+ return "#FFFFFF";
111
+ });
112
+
113
+ const hoverColor = computed(() => {
114
+ if (parsedBackgroundProp.value === 'transparent') {
115
+ return 'rgba(98, 98, 98, 0.15)';
116
+ }
117
+
118
+ const rgb = backgroundColorRgb.value;
119
+ return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, 0.9)`;
120
+ });
121
+ </script>
122
+ <style scoped>
123
+ .prog-grad {
124
+ position: absolute;
125
+ top: 0;
126
+ left: 0;
127
+ }
128
+
129
+ .e-btn-content {
130
+ transition: transform 0.1s ease-in-out;
131
+ flex-direction: row;
132
+ display: flex;
133
+ position: relative;
134
+ align-content: center;
135
+ align-items: center;
136
+ justify-content: center;
137
+ }
138
+
139
+ .e-btn {
140
+ user-select: none;
141
+ background: rgba(0, 0, 0, 0);
142
+ display: flex;
143
+ font-size: 1rem;
144
+ justify-content: center;
145
+ align-content: center;
146
+ align-items: center;
147
+ padding: 0.3rem var(--e-core-padding-x);
148
+ overflow: hidden;
149
+ color: var(--e-color-dark);
150
+ outline: none;
151
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
152
+ border: none;
153
+ text-decoration: none;
154
+ cursor: pointer;
155
+ position: relative;
156
+ flex-shrink: 1;
157
+ transition: background 0.4s, color 0.3s, opacity 0.4s;
158
+ font-family: var(--e-font-family);
159
+ }
160
+ .e-btn.loading {
161
+ pointer-events: none;
162
+ }
163
+ .e-btn.loading.loadingGradient {
164
+ background: rgba(0, 0, 0, 0) !important;
165
+ color: var(--e-color-dark) !important;
166
+ transition: background 0.8s, color 0.5s, opacity 0.4s;
167
+ }
168
+ .e-btn.loading.loadingGradient .actual-content {
169
+ opacity: 0.8;
170
+ transition: opacity 0.5s;
171
+ }
172
+ .e-btn.loading .actual-content {
173
+ opacity: 0;
174
+ }
175
+ .e-btn:hover {
176
+ background: rgba(98, 98, 98, 0.15);
177
+ }
178
+ .e-btn:active .e-btn-content {
179
+ transform: scale(0.85);
180
+ }
181
+ .e-btn.fab {
182
+ position: fixed;
183
+ right: 5rem;
184
+ bottom: 5rem;
185
+ aspect-ratio: 1;
186
+ border-radius: 100%;
187
+ height: 4.2rem;
188
+ z-index: 3;
189
+ }
190
+ .e-btn.block {
191
+ width: 100%;
192
+ }
193
+ .e-btn.colored {
194
+ background-color: v-bind(parsedBackgroundProp);
195
+ color: v-bind(textColor);
196
+ }
197
+ .e-btn.colored:hover {
198
+ background-color: v-bind(hoverColor);
199
+ }
200
+ .e-btn.solid {
201
+ padding: 0.7rem 0.9rem;
202
+ }
203
+ .e-btn.active {
204
+ color: var(--e-color-primary);
205
+ }
206
+ .e-btn.inactive {
207
+ color: var(--e-color-dark);
208
+ opacity: 80%;
209
+ }
210
+
211
+ @media screen and (max-width: var(--e-md-screen-breakpoint)) {
212
+ .e-btn.fab {
213
+ right: 1rem;
214
+ }
215
+ }
216
+ .loading-spinner {
217
+ max-height: 1rem;
218
+ }
219
+
220
+ .load-overlay {
221
+ position: absolute;
222
+ top: 0;
223
+ left: 0;
224
+ right: 0;
225
+ bottom: 0;
226
+ width: 100%;
227
+ display: flex;
228
+ justify-content: center;
229
+ align-items: center;
230
+ z-index: 1;
231
+ }
232
+ </style>
@@ -0,0 +1,48 @@
1
+ <template>
2
+ <div class="container" :class="{ 'no-btn-padding': noBtnPadding }">
3
+ <div class="content" :class="{ forceFullWidth }">
4
+ <slot />
5
+ </div>
6
+ </div>
7
+ </template>
8
+ <script setup lang="ts">
9
+ defineProps(["noBtnPadding", "forceFullWidth"]);
10
+ </script>
11
+ <style scoped>
12
+ .content {
13
+ word-wrap: break-word;
14
+ width: 95%;
15
+ }
16
+ @media (max-width: var(--e-md-screen-breakpoint)) {
17
+ .content.forceFullWidth {
18
+ width: 100%;
19
+ }
20
+ }
21
+ @media (min-width: var(--e-md-screen-breakpoint)) {
22
+ .content {
23
+ width: calc(85% - 0rem);
24
+ }
25
+ }
26
+ @media (min-width: var(--e-l-screen-breakpoint)) {
27
+ .content {
28
+ width: calc(65% - 0rem);
29
+ }
30
+ }
31
+
32
+ .container.no-btn-padding {
33
+ padding: 0px 0px;
34
+ }
35
+ .container.no-btn-padding .content {
36
+ margin: 0px 0px;
37
+ }
38
+
39
+ .container {
40
+ width: 100%;
41
+ display: flex;
42
+ height: 100%;
43
+ justify-content: center;
44
+ word-wrap: break-word;
45
+ box-sizing: border-box; /* Opera/IE 8+ */
46
+ padding: 0px var(--e-core-padding-x);
47
+ }
48
+ </style>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <div>
3
+ <e-focus-sheet :model-value="modelValue" :opaque-on-desktop="true"
4
+ @update:model-value="emit('update:modelValue', $event)" />
5
+
6
+ <e-tr-scale :multiplier="1.3">
7
+ <div class="dialog-wrap flex-center" v-if="modelValue">
8
+ <div class="dialog rounded px-6 pe-6 pb-2">
9
+ <div class="mb-4">
10
+ <h2 class="ma-0 pa-0">
11
+ <slot name="title" />
12
+ </h2>
13
+ </div>
14
+ <slot />
15
+ <div class="button-bar me-4 mb-3">
16
+ <slot name="buttons"></slot>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </e-tr-scale>
21
+ </div>
22
+ </template>
23
+
24
+ <script setup lang="ts">
25
+ const props = defineProps<{
26
+ modelValue: boolean;
27
+ }>();
28
+ const emit = defineEmits(["update:modelValue"]);
29
+ const state = reactive({ active: false });
30
+ </script>
31
+ <style scoped>
32
+ .dialog-wrap {
33
+ position: fixed;
34
+ pointer-events: none;
35
+ z-index: 4;
36
+ width: 100%;
37
+ height: 100%;
38
+ top: 0px;
39
+ left: 0px;
40
+ }
41
+
42
+ .dialog {
43
+ min-width: 25rem;
44
+ pointer-events: all;
45
+ background-color: var(--e-color-elev);
46
+ color: var(--e-color-dark);
47
+ position: relative;
48
+ overflow: clip;
49
+ }
50
+
51
+ @media (max-width: var(--e-md-screen-breakpoint)) {
52
+ .dialog {
53
+ width: 100%;
54
+ max-width: 100vw;
55
+ min-width: unset;
56
+ }
57
+ .dialog-wrap {
58
+ align-content: flex-end;
59
+ align-items: flex-end;
60
+ }
61
+ }
62
+ .button-bar {
63
+ display: flex;
64
+ align-items: stretch;
65
+ justify-content: space-between;
66
+ width: 100%;
67
+ }
68
+ </style>