@meistrari/tela-build 1.47.1 → 1.47.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/components/tela/combobox/combobox-input.vue +1 -1
- package/components/tela/combobox/combobox-label.vue +1 -1
- package/components/tela/combobox/combobox.vue +29 -29
- package/components/tela/complex-table/complex-table-header-cell.vue +3 -3
- package/components/tela/complex-table/complex-table-header.vue +7 -7
- package/components/tela/expandable-input.vue +4 -5
- package/components/tela/icon-button/icon-button.vue +3 -3
- package/components/tela/segment-toggle/segment-toggle.vue +95 -21
- package/components/tela/select-menu/select-menu-item.vue +2 -2
- package/components/tela/select-menu/select-menu-trigger.vue +3 -3
- package/components/tela/select-menu/select-menu.vue +4 -4
- package/components/tela/tabs/tabs-indicator.vue +1 -1
- package/components/tela/tabs/tabs-list.vue +1 -1
- package/components/tela/tabs/tabs-trigger.vue +1 -1
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
|
|
22
22
|
<template>
|
|
23
23
|
<ComboboxInput
|
|
24
24
|
v-bind="forwarded"
|
|
25
|
-
:class="cn('flex h-10 w-full bg
|
|
25
|
+
:class="cn('flex h-10 w-full bg border-b-[0.5px] border-border rounded-xl px-3 py-1 body-14-regular text-primary transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-tertiary focus-visible:bg focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50', props.class)"
|
|
26
26
|
>
|
|
27
27
|
<slot />
|
|
28
28
|
</ComboboxInput>
|
|
@@ -15,7 +15,7 @@ const forwarded = useForwardProps(delegatedProps)
|
|
|
15
15
|
<template>
|
|
16
16
|
<ComboboxLabel
|
|
17
17
|
v-bind="forwarded"
|
|
18
|
-
:class="cn('px-2 py-1 body-12-semibold text-
|
|
18
|
+
:class="cn('px-2 py-1 body-12-semibold text-secondary', props.class)"
|
|
19
19
|
>
|
|
20
20
|
<slot />
|
|
21
21
|
</ComboboxLabel>
|
|
@@ -366,7 +366,7 @@ watch(innerValue, (raw) => {
|
|
|
366
366
|
<ComboboxList :class="cn('z-999', compact ? 'w-440px' : 'w-327px', props.contentClass)" :disable-portal="props.disablePortal" align="start">
|
|
367
367
|
<div v-if="hasSearchbar" class="relative">
|
|
368
368
|
<span class="absolute inset-y-0 start-0 flex items-center justify-center px-2.5">
|
|
369
|
-
<TelaIcon name="i-ph-magnifying-glass" :size="compact ? '12px' : '14px'" class="text-
|
|
369
|
+
<TelaIcon name="i-ph-magnifying-glass" :size="compact ? '12px' : '14px'" class="text-tertiary" />
|
|
370
370
|
</span>
|
|
371
371
|
<ComboboxInput
|
|
372
372
|
v-model="search" :class="cn('rounded-b-none', compact ? 'pl-7' : 'pl-8')"
|
|
@@ -374,7 +374,7 @@ watch(innerValue, (raw) => {
|
|
|
374
374
|
/>
|
|
375
375
|
<div v-if="search.length > 0" class="absolute inset-y-0 end-0 flex items-center justify-center px-2.5">
|
|
376
376
|
<button class="flex items-center justify-center" @click="handleDeleteSearchValue">
|
|
377
|
-
<TelaIcon name="i-ph-x-circle" size="16px" class="text-
|
|
377
|
+
<TelaIcon name="i-ph-x-circle" size="16px" class="text-tertiary" />
|
|
378
378
|
</button>
|
|
379
379
|
</div>
|
|
380
380
|
</div>
|
|
@@ -392,17 +392,17 @@ watch(innerValue, (raw) => {
|
|
|
392
392
|
class="flex flex-col items-center justify-center gap-5 px-7"
|
|
393
393
|
>
|
|
394
394
|
<div class="flex flex-col items-center justify-center gap-3">
|
|
395
|
-
<TelaIcon name="i-ph-smiley-sad" size="24px" class="text-
|
|
395
|
+
<TelaIcon name="i-ph-smiley-sad" size="24px" class="text-tertiary" />
|
|
396
396
|
<span class="text-xl font-medium leading-none">
|
|
397
397
|
{{ search.trim() && labelNoResultsWithSearch ? labelNoResultsWithSearch(search) : labelNoResults }}
|
|
398
398
|
</span>
|
|
399
|
-
<span v-if="search.trim()" class="inline-flex items-center gap-1.5 text-md text-
|
|
399
|
+
<span v-if="search.trim()" class="inline-flex items-center gap-1.5 text-md text-secondary">
|
|
400
400
|
{{ labelPress }}
|
|
401
401
|
<div class="flex items-center gap-1">
|
|
402
|
-
<div class="p-2px bg-
|
|
402
|
+
<div class="p-2px bg-lowered rounded">
|
|
403
403
|
<TelaIcon name="i-ph-command" size="16px" />
|
|
404
404
|
</div>
|
|
405
|
-
<div class="p-2px bg-
|
|
405
|
+
<div class="p-2px bg-lowered rounded">
|
|
406
406
|
<TelaIcon name="i-ph-backspace" size="16px" />
|
|
407
407
|
</div>
|
|
408
408
|
</div>
|
|
@@ -441,15 +441,15 @@ watch(innerValue, (raw) => {
|
|
|
441
441
|
<div class="flex flex-col">
|
|
442
442
|
<div class="flex items-center gap-1">
|
|
443
443
|
<span :class="cn('font-medium truncate max-w-140px', compact ? 'text-sm font-580' : 'text-body-14-regular', labelItemClass)">{{ item.label }}</span>
|
|
444
|
-
<TelaBadge v-if="item.isMultiModal" variant="filled" class="py-[2px] bg-
|
|
444
|
+
<TelaBadge v-if="item.isMultiModal" variant="filled" class="py-[2px] bg-muted" text-class="leading-none">
|
|
445
445
|
{{ labelMultimodal }}
|
|
446
446
|
</TelaBadge>
|
|
447
447
|
<span v-if="item.cost !== undefined" class="text-10px font-580 ml-1px">
|
|
448
|
-
<span class="text-
|
|
449
|
-
<span class="text-
|
|
448
|
+
<span class="text-primary">{{ renderCostIndicator(item.cost)?.blackSymbols }}</span>
|
|
449
|
+
<span class="text-neutral-300">{{ renderCostIndicator(item.cost)?.graySymbols }}</span>
|
|
450
450
|
</span>
|
|
451
451
|
</div>
|
|
452
|
-
<span v-if="item.description" :class="cn('font-normal text-sm text-balance leading-none text-
|
|
452
|
+
<span v-if="item.description" :class="cn('font-normal text-sm text-balance leading-none text-secondary', descriptionClass)">
|
|
453
453
|
{{ item.description }}
|
|
454
454
|
</span>
|
|
455
455
|
<slot name="tags" :option="item" />
|
|
@@ -457,18 +457,18 @@ watch(innerValue, (raw) => {
|
|
|
457
457
|
</div>
|
|
458
458
|
<div class="flex gap-3">
|
|
459
459
|
<div v-if="item.maxInputTokens" class="flex flex-col gap-1.5">
|
|
460
|
-
<span class="text-
|
|
460
|
+
<span class="text-tertiary leading-none text-9px uppercase tracking-wider font-semibold">
|
|
461
461
|
{{ labelInputMax }}
|
|
462
462
|
</span>
|
|
463
|
-
<span class="text-
|
|
463
|
+
<span class="text-tertiary leading-none text-11px uppercase font-semibold group-data-[highlighted]:text-neutral-700">
|
|
464
464
|
{{ handleFormatNumber(item.maxInputTokens) }}
|
|
465
465
|
</span>
|
|
466
466
|
</div>
|
|
467
467
|
<div v-if="item.maxOutputTokens" class="flex flex-col gap-1.5">
|
|
468
|
-
<span class="text-
|
|
468
|
+
<span class="text-tertiary leading-none text-9px uppercase tracking-wider font-semibold">
|
|
469
469
|
{{ labelOutputMax }}
|
|
470
470
|
</span>
|
|
471
|
-
<span class="text-
|
|
471
|
+
<span class="text-tertiary leading-none text-11px uppercase font-semibold group-data-[highlighted]:text-neutral-700">
|
|
472
472
|
{{ handleFormatNumber(item.maxOutputTokens) }}
|
|
473
473
|
</span>
|
|
474
474
|
</div>
|
|
@@ -492,17 +492,17 @@ watch(innerValue, (raw) => {
|
|
|
492
492
|
class="flex flex-col items-center justify-center gap-5 px-7"
|
|
493
493
|
>
|
|
494
494
|
<div class="flex flex-col items-center justify-center gap-3">
|
|
495
|
-
<TelaIcon name="i-ph-smiley-sad" size="24px" class="text-
|
|
495
|
+
<TelaIcon name="i-ph-smiley-sad" size="24px" class="text-tertiary" />
|
|
496
496
|
<span class="text-xl font-medium leading-none">
|
|
497
497
|
{{ search.trim() && labelNoResultsWithSearch ? labelNoResultsWithSearch(search) : labelNoResults }}
|
|
498
498
|
</span>
|
|
499
|
-
<span v-if="search.trim()" class="inline-flex gap-1.5 text-md text-
|
|
499
|
+
<span v-if="search.trim()" class="inline-flex gap-1.5 text-md text-secondary">
|
|
500
500
|
{{ labelPress }}
|
|
501
501
|
<div class="flex items-center gap-1">
|
|
502
|
-
<div class="p-2px bg-
|
|
502
|
+
<div class="p-2px bg-lowered rounded">
|
|
503
503
|
<TelaIcon name="i-ph-command" size="16px" />
|
|
504
504
|
</div>
|
|
505
|
-
<div class="p-2px bg-
|
|
505
|
+
<div class="p-2px bg-lowered rounded">
|
|
506
506
|
<TelaIcon name="i-ph-backspace" size="16px" />
|
|
507
507
|
</div>
|
|
508
508
|
</div>
|
|
@@ -548,15 +548,15 @@ watch(innerValue, (raw) => {
|
|
|
548
548
|
<div class="flex flex-col">
|
|
549
549
|
<div class="flex items-center gap-1">
|
|
550
550
|
<span :class="cn('font-medium truncate max-w-140px', compact ? 'text-sm font-580' : 'text-body-14-regular', labelItemClass)">{{ item.label }}</span>
|
|
551
|
-
<TelaBadge v-if="item.isMultiModal" variant="filled" class="py-[2px] bg-
|
|
551
|
+
<TelaBadge v-if="item.isMultiModal" variant="filled" class="py-[2px] bg-muted" text-class="leading-none">
|
|
552
552
|
{{ labelMultimodal }}
|
|
553
553
|
</TelaBadge>
|
|
554
554
|
<span v-if="item.cost !== undefined" class="text-10px font-580 ml-1px">
|
|
555
|
-
<span class="text-
|
|
556
|
-
<span class="text-
|
|
555
|
+
<span class="text-primary">{{ renderCostIndicator(item.cost)?.blackSymbols }}</span>
|
|
556
|
+
<span class="text-neutral-300">{{ renderCostIndicator(item.cost)?.graySymbols }}</span>
|
|
557
557
|
</span>
|
|
558
558
|
</div>
|
|
559
|
-
<span v-if="item.description" :class="cn('font-normal text-sm leading-none text-
|
|
559
|
+
<span v-if="item.description" :class="cn('font-normal text-sm leading-none text-secondary', descriptionClass)">
|
|
560
560
|
{{ item.description }}
|
|
561
561
|
</span>
|
|
562
562
|
<slot name="tags" :option="item" />
|
|
@@ -564,25 +564,25 @@ watch(innerValue, (raw) => {
|
|
|
564
564
|
</div>
|
|
565
565
|
<div v-if="item.maxInputTokens || item.maxOutputTokens" class="flex gap-3">
|
|
566
566
|
<div class="flex flex-col gap-1.5">
|
|
567
|
-
<span class="text-
|
|
567
|
+
<span class="text-tertiary leading-none text-9px uppercase tracking-wider font-semibold">
|
|
568
568
|
{{ labelInputMax }}
|
|
569
569
|
</span>
|
|
570
|
-
<span class="text-
|
|
570
|
+
<span class="text-tertiary leading-none text-11px uppercase font-semibold group-data-[highlighted]:text-neutral-700">
|
|
571
571
|
{{ handleFormatNumber(item.maxInputTokens) }}
|
|
572
572
|
</span>
|
|
573
573
|
</div>
|
|
574
574
|
<div class="flex flex-col gap-1.5">
|
|
575
|
-
<span class="text-
|
|
575
|
+
<span class="text-tertiary leading-none text-9px uppercase tracking-wider font-semibold">
|
|
576
576
|
{{ labelOutputMax }}
|
|
577
577
|
</span>
|
|
578
|
-
<span class="text-
|
|
578
|
+
<span class="text-tertiary leading-none text-11px uppercase font-semibold group-data-[highlighted]:text-neutral-700">
|
|
579
579
|
{{ handleFormatNumber(item.maxOutputTokens) }}
|
|
580
580
|
</span>
|
|
581
581
|
</div>
|
|
582
582
|
</div>
|
|
583
583
|
</div>
|
|
584
584
|
<div class="flex gap-2 items-center">
|
|
585
|
-
<TelaIcon v-if="item.children?.length" name="i-ph-caret-right" size="14px"
|
|
585
|
+
<TelaIcon v-if="item.children?.length" name="i-ph-caret-right" size="14px" color="icon-tertiary" />
|
|
586
586
|
<ComboboxItemIndicator v-else>
|
|
587
587
|
<TelaIcon name="i-ph-check" size="14px" />
|
|
588
588
|
</ComboboxItemIndicator>
|
|
@@ -602,7 +602,7 @@ watch(innerValue, (raw) => {
|
|
|
602
602
|
v-for="child in item.children"
|
|
603
603
|
:key="child.value"
|
|
604
604
|
:class="cn(
|
|
605
|
-
'relative flex cursor-pointer select-none justify-between items-center rounded-lg px-2 py-2 text-sm font-medium text-
|
|
605
|
+
'relative flex cursor-pointer select-none justify-between items-center rounded-lg px-2 py-2 text-sm font-medium text-primary outline-none hover:bg-muted',
|
|
606
606
|
!compact && '!px-1.5',
|
|
607
607
|
)"
|
|
608
608
|
@click.stop="handleChildSelect(child, $event)"
|
|
@@ -617,7 +617,7 @@ watch(innerValue, (raw) => {
|
|
|
617
617
|
</div>
|
|
618
618
|
<div class="flex flex-col">
|
|
619
619
|
<span :class="cn('font-medium truncate max-w-140px', compact ? 'text-sm font-580' : 'text-body-14-regular', labelItemClass)">{{ child.label }}</span>
|
|
620
|
-
<span v-if="child.description" :class="cn('font-normal text-sm leading-none text-
|
|
620
|
+
<span v-if="child.description" :class="cn('font-normal text-sm leading-none text-secondary', descriptionClass)">
|
|
621
621
|
{{ child.description }}
|
|
622
622
|
</span>
|
|
623
623
|
</div>
|
|
@@ -28,7 +28,7 @@ const size = computed(() => ({
|
|
|
28
28
|
<div
|
|
29
29
|
v-if="type === 'default' && column"
|
|
30
30
|
w-full
|
|
31
|
-
min-w-52px pr-12px text-start h-full flex items-center
|
|
31
|
+
min-w-52px pr-12px text-start h-full flex items-center overflow-hidden
|
|
32
32
|
bg-white whitespace-nowrap
|
|
33
33
|
body-12-medium gap-4px
|
|
34
34
|
:class="[column.isDefault && 'text-gray-400 italic', column.class]"
|
|
@@ -38,8 +38,8 @@ const size = computed(() => ({
|
|
|
38
38
|
paddingLeft: `${size}px`,
|
|
39
39
|
}"
|
|
40
40
|
>
|
|
41
|
-
<TelaIcon v-if="column.icon" :name="column.icon.name" :size="column.icon.size" :style="column.icon.style" />
|
|
42
|
-
{{ column.title }}
|
|
41
|
+
<TelaIcon v-if="column.icon" :name="column.icon.name" :size="column.icon.size" :style="column.icon.style" shrink-0 />
|
|
42
|
+
<span min-w-0 flex-1 truncate>{{ column.title }}</span>
|
|
43
43
|
</div>
|
|
44
44
|
|
|
45
45
|
<div v-else-if="type === 'checkbox' && rows" flex="~" justify-center h-full items-center bg-white z-2>
|
|
@@ -26,12 +26,12 @@ const emit = defineEmits(['selectAll'])
|
|
|
26
26
|
body-12-medium text="gray-800" h-56px px-12px py-10px
|
|
27
27
|
bg-white :class="headerClass"
|
|
28
28
|
>
|
|
29
|
-
<th v-if="allowSelect && rows?.length" class="sticky left-0 top-0 bg-white h-
|
|
30
|
-
<div flex="~" justify-center h-
|
|
29
|
+
<th v-if="allowSelect && rows?.length" class="sticky left-0 top-0 bg-white h-full z-30 w-32px p-0px" :class="headerClass">
|
|
30
|
+
<div flex="~" justify-center h-full items-center bg-white z-2 border-b-0.5px border-gray-200 :class="headerClass">
|
|
31
31
|
<TelaCheckbox v-if="rows.length" :model-value="selectedRows?.length === rows.length" @update:model-value="emit('selectAll', $event)" />
|
|
32
32
|
</div>
|
|
33
33
|
</th>
|
|
34
|
-
<th v-if="allowRowIndex" class="sticky top-0 h-
|
|
34
|
+
<th v-if="allowRowIndex" class="sticky top-0 h-full bg-white z-30 p-0px" :style="{ left: (allowSelect && rows?.length) ? '32px' : '0', width: '48px', minWidth: '48px', maxWidth: '48px' }" :class="headerClass">
|
|
35
35
|
<TelaTableHeaderCell type="default" :column="{ title: 'ID' }" />
|
|
36
36
|
</th>
|
|
37
37
|
<slot name="leading-header" />
|
|
@@ -39,7 +39,7 @@ const emit = defineEmits(['selectAll'])
|
|
|
39
39
|
v-for="column in columns"
|
|
40
40
|
:key="column.key"
|
|
41
41
|
z-11
|
|
42
|
-
sticky top-0px h-
|
|
42
|
+
sticky top-0px h-full
|
|
43
43
|
p-0px
|
|
44
44
|
:class="headerClass"
|
|
45
45
|
:style="column.style"
|
|
@@ -50,11 +50,11 @@ const emit = defineEmits(['selectAll'])
|
|
|
50
50
|
</th>
|
|
51
51
|
<th v-for="(_, idx) in (rows?.length ? 0 : 3)" :key="idx" sticky top-0px p-0px />
|
|
52
52
|
<th sticky top-0px z-10 w-full p-0px>
|
|
53
|
-
<div h-
|
|
53
|
+
<div h-full bg-white border-b-0.5px border-gray-200 rounded-tr-8px :class="headerClass" />
|
|
54
54
|
</th>
|
|
55
|
-
<th v-if="allowRowAction && rows?.length" sticky right-0px top-0px h-
|
|
55
|
+
<th v-if="allowRowAction && rows?.length" sticky right-0px top-0px h-full rounded-tr-8px p-0px :class="headerClass">
|
|
56
56
|
<div
|
|
57
|
-
w-full h-
|
|
57
|
+
w-full h-full rounded-tr-8px class="shadow"
|
|
58
58
|
bg-white b="b-0.5px l-0.5px gray-200"
|
|
59
59
|
/>
|
|
60
60
|
</th>
|
|
@@ -39,7 +39,7 @@ function onStopEditing() {
|
|
|
39
39
|
rounded-4px
|
|
40
40
|
px-8px
|
|
41
41
|
mr-24px
|
|
42
|
-
class="hover:bg-
|
|
42
|
+
class="hover:bg-muted"
|
|
43
43
|
:tabindex="isEditing ? 1 : 0"
|
|
44
44
|
@click="onStartEditing"
|
|
45
45
|
@focus="onStartEditing"
|
|
@@ -73,18 +73,17 @@ function onStopEditing() {
|
|
|
73
73
|
:style="{ width: `${containerWidth}px`, height: type === 'textarea' ? '100px' : 'auto', overflow: type === 'textarea' ? 'auto' : 'hidden' }"
|
|
74
74
|
absolute
|
|
75
75
|
z-3
|
|
76
|
-
rounded-
|
|
76
|
+
rounded-6px
|
|
77
77
|
top--19.5px
|
|
78
78
|
left--2.5px
|
|
79
79
|
px-10px
|
|
80
80
|
py-10px
|
|
81
81
|
resize-none
|
|
82
82
|
autoresize
|
|
83
|
-
bg-
|
|
83
|
+
bg-muted
|
|
84
84
|
font-inherit
|
|
85
85
|
tabindex="0"
|
|
86
|
-
|
|
87
|
-
shadow-flying
|
|
86
|
+
border-0.5px border
|
|
88
87
|
:spellcheck="false"
|
|
89
88
|
v-bind="$attrs"
|
|
90
89
|
@keydown.enter="onStopEditing"
|
|
@@ -39,11 +39,11 @@ const style = computed(() => {
|
|
|
39
39
|
} as Record<typeof props.size, string>)[props.size]
|
|
40
40
|
|
|
41
41
|
const color = ({
|
|
42
|
-
primary: 'bg
|
|
43
|
-
secondary: 'bg-transparent text-icon-tertiary hover:bg-muted hover:text-
|
|
42
|
+
primary: 'bg-neutral-900 !text-white hover:bg-neutral-800',
|
|
43
|
+
secondary: 'bg-transparent text-icon-tertiary hover:bg-muted hover:text-primary active:text-primary disabled:bg-muted disabled:!text-subtle',
|
|
44
44
|
} as Record<typeof props.color, string>)[props.color]
|
|
45
45
|
|
|
46
|
-
const disabled = props.disabled && 'cursor-not-allowed !bg
|
|
46
|
+
const disabled = props.disabled && 'cursor-not-allowed !bg-muted !text-subtle !b-0'
|
|
47
47
|
|
|
48
48
|
const outline = props.outline && ({
|
|
49
49
|
primary: 'b-0.7px !b-#011D21',
|
|
@@ -19,41 +19,115 @@ const emit = defineEmits<{
|
|
|
19
19
|
(e: 'update:modelValue', value: string): void
|
|
20
20
|
}>()
|
|
21
21
|
|
|
22
|
-
const
|
|
22
|
+
const wrapperRef = ref<HTMLElement>()
|
|
23
|
+
const baseListRef = ref<HTMLElement>()
|
|
24
|
+
const clipRef = ref<HTMLElement>()
|
|
25
|
+
|
|
26
|
+
const clipPath = ref('inset(2px 100% 2px 0 round 17px)')
|
|
27
|
+
const enableTransition = ref(false)
|
|
28
|
+
|
|
29
|
+
const buttonClass = computed(() => cn(
|
|
30
|
+
'relative text-14px leading-18px tracking--0.15px font-580 rounded-full flex items-center justify-center',
|
|
31
|
+
props.size === 'small' ? 'h-24px px-12px min-w-50px' : 'h-28px px-24px min-w-115px',
|
|
32
|
+
props.buttonsClass,
|
|
33
|
+
))
|
|
23
34
|
|
|
24
35
|
function selectTab(value: string) {
|
|
25
36
|
emit('update:modelValue', value)
|
|
26
37
|
}
|
|
38
|
+
|
|
39
|
+
function updateClip() {
|
|
40
|
+
const clip = clipRef.value
|
|
41
|
+
const list = baseListRef.value
|
|
42
|
+
|
|
43
|
+
if (!clip || !list)
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
const active = list.querySelector<HTMLElement>(`[data-value="${CSS.escape(props.modelValue)}"]`)
|
|
47
|
+
|
|
48
|
+
if (!active)
|
|
49
|
+
return
|
|
50
|
+
|
|
51
|
+
const total = clip.offsetWidth
|
|
52
|
+
|
|
53
|
+
if (!total)
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
const { offsetLeft, offsetWidth } = active
|
|
57
|
+
|
|
58
|
+
const left = (offsetLeft / total) * 100
|
|
59
|
+
const right = 100 - ((offsetLeft + offsetWidth) / total) * 100
|
|
60
|
+
|
|
61
|
+
clipPath.value = `inset(2px ${right}% 2px ${left}% round 17px)`
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
watch(() => [props.modelValue, props.options, props.size], () => nextTick(updateClip), { deep: true })
|
|
65
|
+
|
|
66
|
+
let resizeObserver: ResizeObserver | undefined
|
|
67
|
+
|
|
68
|
+
onMounted(() => {
|
|
69
|
+
nextTick(() => {
|
|
70
|
+
updateClip()
|
|
71
|
+
requestAnimationFrame(() => {
|
|
72
|
+
enableTransition.value = true
|
|
73
|
+
})
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
if (wrapperRef.value) {
|
|
77
|
+
resizeObserver = new ResizeObserver(() => updateClip())
|
|
78
|
+
resizeObserver.observe(wrapperRef.value)
|
|
79
|
+
}
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
onBeforeUnmount(() => {
|
|
83
|
+
resizeObserver?.disconnect()
|
|
84
|
+
})
|
|
27
85
|
</script>
|
|
28
86
|
|
|
29
87
|
<template>
|
|
30
88
|
<div
|
|
31
|
-
|
|
89
|
+
ref="wrapperRef"
|
|
90
|
+
relative rounded-full select-none p-2px min-w-68px bg-muted
|
|
32
91
|
:class="[
|
|
33
92
|
props.size === 'small' ? 'min-h-24px' : 'min-h-28px',
|
|
34
93
|
props.disabled && 'opacity-50 pointer-events-none cursor-not-allowed',
|
|
35
94
|
props.class,
|
|
36
95
|
]"
|
|
37
96
|
>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
97
|
+
<!-- Base layer: inactive segments -->
|
|
98
|
+
<div ref="baseListRef" flex items-center gap-2px>
|
|
99
|
+
<button
|
|
100
|
+
v-for="option in options"
|
|
101
|
+
:key="option.value"
|
|
102
|
+
type="button"
|
|
103
|
+
:data-value="option.value"
|
|
104
|
+
:class="buttonClass"
|
|
105
|
+
:disabled="props.disabled"
|
|
106
|
+
@click="selectTab(option.value)"
|
|
107
|
+
>
|
|
108
|
+
<span text-tertiary>{{ option.label }}</span>
|
|
109
|
+
</button>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<!-- Overlay layer: active appearance, clipped to the active segment -->
|
|
113
|
+
<div
|
|
114
|
+
ref="clipRef"
|
|
115
|
+
aria-hidden="true"
|
|
116
|
+
absolute inset-0 p-2px overflow-hidden pointer-events-none
|
|
117
|
+
:class="enableTransition ? '[transition:clip-path_250ms_ease]' : ''"
|
|
118
|
+
:style="{ clipPath }"
|
|
49
119
|
>
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
120
|
+
<div flex items-center gap-2px size-full bg>
|
|
121
|
+
<button
|
|
122
|
+
v-for="option in options"
|
|
123
|
+
:key="option.value"
|
|
124
|
+
type="button"
|
|
125
|
+
tabindex="-1"
|
|
126
|
+
:class="cn(buttonClass)"
|
|
127
|
+
>
|
|
128
|
+
<span text-primary>{{ option.label }}</span>
|
|
129
|
+
</button>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
58
132
|
</div>
|
|
59
133
|
</template>
|
|
@@ -21,7 +21,7 @@ const forwardedProps = useForwardProps(delegatedProps)
|
|
|
21
21
|
v-bind="forwardedProps"
|
|
22
22
|
:class="
|
|
23
23
|
cn(
|
|
24
|
-
'relative flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-[12px] pl-[10px] pr-[8px] py-[7px]
|
|
24
|
+
'relative flex w-full cursor-pointer select-none items-center justify-between gap-2 rounded-[12px] pl-[10px] pr-[8px] py-[7px] body-14-medium outline-none focus:bg-muted data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
|
|
25
25
|
props.class,
|
|
26
26
|
)
|
|
27
27
|
"
|
|
@@ -32,7 +32,7 @@ const forwardedProps = useForwardProps(delegatedProps)
|
|
|
32
32
|
|
|
33
33
|
<span class="relative flex h-3.5 w-3.5 items-center justify-center">
|
|
34
34
|
<SelectItemIndicator>
|
|
35
|
-
<TelaIcon name="i-ph-check-bold" size="14px" color="
|
|
35
|
+
<TelaIcon name="i-ph-check-bold" size="14px" color="icon-secondary" />
|
|
36
36
|
</SelectItemIndicator>
|
|
37
37
|
</span>
|
|
38
38
|
</SelectItem>
|
|
@@ -20,9 +20,9 @@ const forwardedProps = useForwardProps(delegatedProps)
|
|
|
20
20
|
<SelectTrigger
|
|
21
21
|
v-bind="forwardedProps"
|
|
22
22
|
:class="cn(
|
|
23
|
-
'group flex h-32px min-w-0 max-w-full w-full items-center gap-[12px] justify-between rounded-[10px] border-[0.5px] border-
|
|
24
|
-
'data-[placeholder]:text-
|
|
25
|
-
'focus-visible:ring-[0.5px] focus-visible:ring-cyan-600 disabled:cursor-not-allowed disabled:bg-
|
|
23
|
+
'group flex h-32px min-w-0 max-w-full w-full items-center gap-[12px] justify-between rounded-[10px] border-[0.5px] border-border bg pl-[12px] pr-[8px] py-[7px] body-14-semibold select-none text-start',
|
|
24
|
+
'data-[placeholder]:text-primary data-[state=open]:text-secondary hover:bg-subtle data-[state=open]:bg-subtle data-[state=open]:border-strong focus-visible:outline-none',
|
|
25
|
+
'focus-visible:ring-[0.5px] focus-visible:ring-cyan-600 disabled:cursor-not-allowed disabled:bg-muted disabled:border-border disabled:text-tertiary',
|
|
26
26
|
'[box-shadow:0_1px_6px_0_rgba(103,127,148,0.05)] [&>span]:truncate',
|
|
27
27
|
props.class,
|
|
28
28
|
)"
|
|
@@ -137,9 +137,9 @@ function handleOpenChange(open: boolean) {
|
|
|
137
137
|
</template>
|
|
138
138
|
<div
|
|
139
139
|
v-if="option.icon" mr-12px rounded-4px w-40px h-40px flex items-center justify-center
|
|
140
|
-
|
|
141
|
-
text
|
|
142
|
-
bg
|
|
140
|
+
border-0.5px border
|
|
141
|
+
text-icon
|
|
142
|
+
bg flex-none
|
|
143
143
|
>
|
|
144
144
|
<TelaIcon v-if="iconWithBackground" :name="option.icon" :size="iconWithBackground?.size" :background-class="iconWithBackground?.backgroundClass" />
|
|
145
145
|
<TelaIcon v-else-if="typeof option.icon === 'string'" size="sm" :name="option.icon" />
|
|
@@ -150,7 +150,7 @@ function handleOpenChange(open: boolean) {
|
|
|
150
150
|
</div>
|
|
151
151
|
<div flex="~ col" text-start min-w-0 flex-1>
|
|
152
152
|
{{ option.label }}
|
|
153
|
-
<span v-if="option.description" text
|
|
153
|
+
<span v-if="option.description" text-secondary body-12-regular text-start>
|
|
154
154
|
{{ option.description }}
|
|
155
155
|
</span>
|
|
156
156
|
</div>
|
|
@@ -15,6 +15,6 @@ const delegatedProps = reactiveOmit(props, 'class')
|
|
|
15
15
|
v-bind="delegatedProps"
|
|
16
16
|
:class="cn('absolute left-0 h-[1.5px] bottom-0 w-[--reka-tabs-indicator-size] translate-x-[--reka-tabs-indicator-position] translate-y-[1px] rounded-full transition-[width,transform] duration-300', props.class)"
|
|
17
17
|
>
|
|
18
|
-
<div class="bg-
|
|
18
|
+
<div class="bg-neutral-900 w-full h-full" />
|
|
19
19
|
</TabsIndicator>
|
|
20
20
|
</template>
|
|
@@ -13,7 +13,7 @@ const delegatedProps = reactiveOmit(props, 'class')
|
|
|
13
13
|
<TabsList
|
|
14
14
|
v-bind="delegatedProps"
|
|
15
15
|
:class="cn(
|
|
16
|
-
'relative inline-flex border-b-[0.5px] border-
|
|
16
|
+
'relative inline-flex border-b-[0.5px] border-border items-center bg px-2 py-0.5',
|
|
17
17
|
props.class,
|
|
18
18
|
)"
|
|
19
19
|
>
|
|
@@ -15,7 +15,7 @@ const forwardedProps = useForwardProps(delegatedProps)
|
|
|
15
15
|
<TabsTrigger
|
|
16
16
|
v-bind="forwardedProps"
|
|
17
17
|
:class="cn(
|
|
18
|
-
'inline-flex cursor-pointer items-center justify-center whitespace-nowrap px-[6px] py-1 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none text-
|
|
18
|
+
'inline-flex cursor-pointer items-center justify-center whitespace-nowrap px-[6px] py-1 text-sm font-medium transition-all focus-visible:outline-none disabled:pointer-events-none text-tertiary hover:text-primary disabled:opacity-50 data-[state=active]:text-primary',
|
|
19
19
|
props.class,
|
|
20
20
|
)"
|
|
21
21
|
>
|