@milaboratories/uikit 2.2.0 → 2.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@milaboratories/uikit",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
4
4
  "type": "module",
5
5
  "main": "dist/pl-uikit.umd.js",
6
6
  "module": "dist/pl-uikit.js",
@@ -18,7 +18,7 @@
18
18
  "./*": "./*"
19
19
  },
20
20
  "dependencies": {
21
- "vue": "^3.5.12"
21
+ "vue": "^3.5.13"
22
22
  },
23
23
  "devDependencies": {
24
24
  "@vue/test-utils": "^2.4.6",
@@ -27,13 +27,13 @@
27
27
  "resize-observer-polyfill": "^1.5.1",
28
28
  "@vitejs/plugin-vue": "^5.1.4",
29
29
  "tsc-alias": "^1.8.10",
30
- "vitest": "^2.1.4",
31
- "vite": "^5.4.10",
30
+ "vitest": "^2.1.5",
31
+ "vite": "^5.4.11",
32
32
  "vue-tsc": "^2.1.6",
33
33
  "yarpm": "^1.2.0",
34
34
  "svgo": "^3.3.2",
35
35
  "@milaboratories/helpers": "^1.6.6",
36
- "@platforma-sdk/model": "^1.8.0"
36
+ "@platforma-sdk/model": "^1.8.19"
37
37
  },
38
38
  "scripts": {
39
39
  "dev": "vite",
@@ -119,15 +119,13 @@ const query = (handle: StorageHandle, dirPath: string) => {
119
119
 
120
120
  const load = () => {
121
121
  const { storageHandle, dirPath, modelValue } = lookup.value;
122
- if (storageHandle && modelValue && dirPath) {
122
+ if (storageHandle && modelValue) {
123
123
  query(storageHandle, dirPath);
124
124
  }
125
125
  };
126
126
 
127
127
  const updateDirPathDebounced = debounce((v: string) => {
128
- if (v) {
129
- data.dirPath = v;
130
- }
128
+ data.dirPath = v ?? ''; // ???
131
129
  }, 1000);
132
130
 
133
131
  const breadcrumbs = computed(() => getFilePathBreadcrumbs(data.dirPath));
@@ -347,7 +345,7 @@ const vTextOverflown = {
347
345
  <span v-text-overflown :title="file.name">{{ file.name }}</span>
348
346
  </div>
349
347
  <div v-else :class="{ canBeSelected: file.canBeSelected, selected: file.selected }" @click.stop="(ev) => selectFile(ev, file)">
350
- <i class="mask-16 mask-comp isFile" />
348
+ <i class="mask-16 mask-box isFile" />
351
349
  <span v-text-overflown :title="file.name">{{ file.name }}</span>
352
350
  </div>
353
351
  </template>
@@ -0,0 +1,65 @@
1
+ <script lang="ts">
2
+ /**
3
+ * A component for selecting one value from a list of options
4
+ */
5
+ export default {
6
+ name: 'PlTabs',
7
+ };
8
+ </script>
9
+
10
+ <script lang="ts" setup generic="M extends string">
11
+ import style from './pl-tabs.module.scss';
12
+ import type { TabOption } from './types';
13
+ import Tab from './Tab.vue';
14
+
15
+ const emit = defineEmits<{
16
+ /**
17
+ * Emitted when the model value is updated.
18
+ */
19
+ (e: 'update:modelValue', value: M): void;
20
+ }>();
21
+
22
+ const emitModel = (v: M) => emit('update:modelValue', v);
23
+
24
+ defineProps<{
25
+ /**
26
+ * The current selected tab value.
27
+ */
28
+ modelValue?: M;
29
+ /**
30
+ * List of available options for the component
31
+ */
32
+ options: Readonly<TabOption<M>[]>;
33
+ /**
34
+ * If `true`, the component is disabled and cannot be interacted with.
35
+ */
36
+ disabled?: boolean;
37
+ /**
38
+ * If `true`, the `active` line appears on the top of element.
39
+ */
40
+ topLine?: boolean;
41
+ /**
42
+ * Maximum tab width (css value), can be overridden for each option
43
+ */
44
+ maxTabWidth?: string;
45
+ }>();
46
+ </script>
47
+
48
+ <template>
49
+ <div :class="[style.component, { [style.disabled]: disabled, [style.topLine]: topLine }]">
50
+ <Tab
51
+ v-for="(opt, i) in options"
52
+ :key="i"
53
+ :tabindex="modelValue === opt.value || disabled || opt.disabled ? undefined : 0"
54
+ :option="opt"
55
+ :class="[{ [style.active]: modelValue === opt.value, [style.disabled]: opt.disabled }, style.tab]"
56
+ :style="{ '--pl-tabs-item-max-width': opt.maxWidth ?? maxTabWidth }"
57
+ @keydown.enter="emitModel(opt.value)"
58
+ @click="emitModel(opt.value)"
59
+ >
60
+ <slot :name="opt.value" :option="opt">
61
+ <span>{{ opt.label }}</span>
62
+ </slot>
63
+ </Tab>
64
+ </div>
65
+ </template>
@@ -0,0 +1,52 @@
1
+ <script lang="ts" setup>
2
+ import { onMounted, unref, ref, reactive } from 'vue';
3
+ import { PlTooltip } from '../PlTooltip';
4
+ import type { TabOption } from './types';
5
+
6
+ const rootRef = ref<{ $el: HTMLElement }>();
7
+
8
+ defineProps<{
9
+ option: TabOption;
10
+ }>();
11
+
12
+ const data = reactive({
13
+ isOverflown: false,
14
+ });
15
+
16
+ onMounted(() => {
17
+ const root = unref(rootRef);
18
+
19
+ if (!root) {
20
+ return;
21
+ }
22
+
23
+ const el = root.$el.querySelector('span') as HTMLElement | null;
24
+
25
+ if (!el) {
26
+ return;
27
+ }
28
+
29
+ requestAnimationFrame(() => {
30
+ if (el.offsetWidth < el.scrollWidth) {
31
+ data.isOverflown = true;
32
+ }
33
+ console.log('el.offsetWidth, el.scrollWidth', el.offsetWidth, el.scrollWidth);
34
+ });
35
+ });
36
+ </script>
37
+
38
+ <template>
39
+ <PlTooltip
40
+ ref="rootRef"
41
+ element="div"
42
+ position="top"
43
+ :hide="!data.isOverflown"
44
+ :close-delay="300"
45
+ :data-is-overflown="data.isOverflown ? 'true' : 'false'"
46
+ >
47
+ <slot />
48
+ <template #tooltip>
49
+ {{ option.label }}
50
+ </template>
51
+ </PlTooltip>
52
+ </template>
@@ -0,0 +1 @@
1
+ export { default as PlTabs } from './PlTabs.vue';
@@ -0,0 +1,90 @@
1
+ @import "@/assets/mixins";
2
+
3
+ .component {
4
+ --pl-tabs-height: 40px;
5
+ --pl-tabs-item-border-color: var(--border-color-div-grey);
6
+ --pl-tabs-item-border-width: 0 0 2px 0;
7
+ --pl-tabs-item-text-color: var(--txt-03);
8
+ --pl-tabs-item-max-width: 400px;
9
+ --pl-tabs-cursor: pointer;
10
+
11
+ position: relative;
12
+ min-height: var(--pl-tabs-height);
13
+ display: flex;
14
+ flex-direction: row;
15
+ gap: 2px;
16
+
17
+ .tab {
18
+ position: relative;
19
+ display: flex;
20
+ flex-direction: row;
21
+ justify-content: center;
22
+ align-items: center;
23
+ flex-wrap: nowrap;
24
+ gap: 12px;
25
+ padding: 10px 12px;
26
+ cursor: var(--pl-tabs-cursor);
27
+ outline: none;
28
+ position: relative;
29
+
30
+ &.disabled {
31
+ cursor: not-allowed;
32
+ pointer-events: none;
33
+ }
34
+
35
+ > span {
36
+ color: var(--pl-tabs-item-text-color);
37
+ font-size: 13px;
38
+ font-style: normal;
39
+ font-weight: 600;
40
+ line-height: 14px; /* 107.692% */
41
+ letter-spacing: 0.52px;
42
+ text-transform: uppercase;
43
+ overflow: hidden;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ max-width: var(--pl-tabs-item-max-width);
47
+ min-width: 60px;
48
+ }
49
+
50
+ &::after {
51
+ content: '';
52
+ position: absolute;
53
+ top: 0;
54
+ left: 0;
55
+ right: 0;
56
+ bottom: 0;
57
+ pointer-events: none;
58
+ border: solid var(--pl-tabs-item-border-color);
59
+ border-width: var(--pl-tabs-item-border-width);
60
+ }
61
+
62
+ &:hover:not(.active) {
63
+ --pl-tabs-item-border-color: var(--border-color-focus);
64
+ --pl-tabs-item-text-color: var(--txt-01);
65
+ }
66
+
67
+ &:focus-visible {
68
+ --pl-tabs-item-border-color: var(--border-color-focus);
69
+ --pl-tabs-item-border-width: 2px;
70
+ --pl-tabs-item-text-color: var(--txt-01);
71
+ }
72
+
73
+ &.active {
74
+ --pl-tabs-item-border-color: var(--border-color-focus);
75
+ --pl-tabs-item-text-color: var(--txt-01);
76
+ }
77
+ }
78
+
79
+ &.topLine {
80
+ --pl-tabs-item-border-width: 2px 0 0 0;
81
+ }
82
+
83
+ &.disabled {
84
+ --pl-tabs-cursor: not-allowed;
85
+ cursor: not-allowed;
86
+ * {
87
+ pointer-events: none;
88
+ }
89
+ }
90
+ }
@@ -0,0 +1,12 @@
1
+ export type TabOption<T extends string = string> = {
2
+ label: string;
3
+ value: T;
4
+ /**
5
+ * Each option can be disabled
6
+ */
7
+ disabled?: boolean;
8
+ /**
9
+ * Maximum tab width (css value)
10
+ */
11
+ maxWidth?: string;
12
+ };
package/src/index.ts CHANGED
@@ -42,6 +42,7 @@ export * from './components/PlDialogModal';
42
42
  export * from './components/PlSlideModal';
43
43
  export * from './components/PlToggleSwitch';
44
44
  export * from './components/PlLogView';
45
+ export * from './components/PlTabs';
45
46
 
46
47
  export * from './components/PlFileDialog';
47
48
  export * from './components/PlFileInput';