@youcan/celeste 0.11.0 → 0.13.0
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/ai/component-registry.json +30 -2
- package/ai/component-registry.md +5 -1
- package/ai/icons.md +1 -1
- package/ai/tokens.md +1 -1
- package/dist/celeste.css +311 -218
- package/dist/cjs/chunks/ConfigProvider.cjs +58 -1
- package/dist/cjs/chunks/calendar.cjs +73 -67
- package/dist/cjs/chunks/combobox-root.cjs +12 -5
- package/dist/cjs/chunks/digit-input.cjs +13 -7
- package/dist/cjs/chunks/dist2.cjs +6 -0
- package/dist/cjs/chunks/dropdown-menu.cjs +10 -4
- package/dist/cjs/chunks/fancy-button.cjs +1 -1
- package/dist/cjs/chunks/radio-group.cjs +9 -3
- package/dist/cjs/chunks/range-calendar.cjs +73 -67
- package/dist/cjs/chunks/scroll-area.cjs +18 -12
- package/dist/cjs/chunks/scroll-bar.cjs +2 -0
- package/dist/cjs/chunks/segmented-control-item.cjs +1 -1
- package/dist/cjs/chunks/segmented-control.cjs +25 -4
- package/dist/cjs/chunks/select.cjs +9 -3
- package/dist/cjs/chunks/slider.cjs +16 -10
- package/dist/cjs/chunks/tab-menu-item.cjs +6 -2
- package/dist/cjs/chunks/tab-menu-list.cjs +53 -9
- package/dist/cjs/chunks/tab-menu.cjs +12 -5
- package/dist/cjs/chunks/text-input.cjs +1 -1
- package/dist/cjs/command-root.cjs +9 -3
- package/dist/cjs/index.cjs +4 -0
- package/dist/cjs/use-direction.cjs +31 -0
- package/dist/cjs/use-tab-observer.cjs +42 -0
- package/dist/components/combobox/combobox-root.d.ts +2 -2
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +2 -2
- package/dist/components/radio-group/radio-group.d.ts +2 -2
- package/dist/components/scroll-area/scroll-area.d.ts +2 -2
- package/dist/components/segmented-control/segmented-control.d.ts +2 -2
- package/dist/components/select/select.d.ts +2 -2
- package/dist/components/tab-menu/tab-menu-list.d.ts +14 -5
- package/dist/components/tab-menu/tab-menu.d.ts +2 -2
- package/dist/composables/index.d.ts +2 -0
- package/dist/composables/use-direction.d.ts +3 -0
- package/dist/composables/use-tab-observer.d.ts +14 -0
- package/dist/es/chunks/BubbleSelect.js +1 -1
- package/dist/es/chunks/CollapsibleRoot.js +1 -1
- package/dist/es/chunks/ComboboxInput.js +1 -1
- package/dist/es/chunks/ComboboxRoot.js +1 -1
- package/dist/es/chunks/ConfigProvider.js +53 -2
- package/dist/es/chunks/DialogRoot.js +1 -1
- package/dist/es/chunks/DropdownMenuRoot.js +1 -1
- package/dist/es/chunks/FocusScope.js +1 -1
- package/dist/es/chunks/MenuRoot.js +1 -1
- package/dist/es/chunks/MenuSub.js +1 -1
- package/dist/es/chunks/PaginationRoot.js +1 -1
- package/dist/es/chunks/PinInputRoot.js +1 -1
- package/dist/es/chunks/PopoverRoot.js +1 -1
- package/dist/es/chunks/ProgressIndicator.js +1 -1
- package/dist/es/chunks/RadioGroupRoot.js +1 -1
- package/dist/es/chunks/RovingFocusGroup.js +1 -1
- package/dist/es/chunks/SelectItemAlignedPosition.js +1 -1
- package/dist/es/chunks/TabsRoot.js +1 -1
- package/dist/es/chunks/Teleport.js +1 -1
- package/dist/es/chunks/ToggleGroupRoot.js +1 -1
- package/dist/es/chunks/TooltipRoot.js +1 -1
- package/dist/es/chunks/bar-chart.js +1 -1
- package/dist/es/chunks/calendar.js +74 -68
- package/dist/es/chunks/checkbox.js +1 -1
- package/dist/es/chunks/combobox-root.js +13 -6
- package/dist/es/chunks/counter-input.js +1 -1
- package/dist/es/chunks/digit-input.js +14 -8
- package/dist/es/chunks/dist2.js +1 -1
- package/dist/es/chunks/dropdown-menu-sub.js +1 -1
- package/dist/es/chunks/dropdown-menu.js +11 -5
- package/dist/es/chunks/fancy-button.js +1 -1
- package/dist/es/chunks/radio-group-item.js +1 -1
- package/dist/es/chunks/radio-group.js +10 -4
- package/dist/es/chunks/range-calendar.js +74 -68
- package/dist/es/chunks/scroll-area.js +19 -13
- package/dist/es/chunks/scroll-bar.js +3 -1
- package/dist/es/chunks/segmented-control-item.js +2 -2
- package/dist/es/chunks/segmented-control.js +27 -5
- package/dist/es/chunks/select.js +10 -4
- package/dist/es/chunks/sidebar-provider.js +1 -1
- package/dist/es/chunks/slider.js +17 -11
- package/dist/es/chunks/switch.js +1 -1
- package/dist/es/chunks/tab-menu-item.js +6 -2
- package/dist/es/chunks/tab-menu-list.js +56 -10
- package/dist/es/chunks/tab-menu.js +13 -6
- package/dist/es/chunks/text-input.js +1 -1
- package/dist/es/chunks/useDirection.js +1 -1
- package/dist/es/chunks/useId.js +1 -1
- package/dist/es/chunks/useLocale.js +1 -1
- package/dist/es/chunks/useNonce.js +1 -1
- package/dist/es/command-root.js +10 -4
- package/dist/es/index.js +3 -1
- package/dist/es/use-direction.js +30 -0
- package/dist/es/use-tab-observer.js +41 -0
- package/package.json +3 -3
- package/src/components/button/fancy-button.vue +14 -4
- package/src/components/calendar/calendar.vue +66 -60
- package/src/components/combobox/combobox-root.vue +9 -4
- package/src/components/command/command-root.vue +13 -8
- package/src/components/digit-input/digit-input.vue +13 -8
- package/src/components/dropdown-menu/dropdown-menu.vue +12 -7
- package/src/components/radio-group/radio-group.vue +12 -7
- package/src/components/range-calendar/range-calendar.vue +67 -61
- package/src/components/scroll-area/scroll-area.vue +17 -18
- package/src/components/segmented-control/segmented-control-item.vue +3 -3
- package/src/components/segmented-control/segmented-control.vue +48 -8
- package/src/components/select/select.vue +12 -7
- package/src/components/slider/slider.vue +19 -14
- package/src/components/switch/switch.vue +19 -18
- package/src/components/tab-menu/stories/tab-menu.stories.ts +39 -0
- package/src/components/tab-menu/tab-menu-item.vue +27 -28
- package/src/components/tab-menu/tab-menu-list.vue +85 -3
- package/src/components/tab-menu/tab-menu.vue +12 -4
- package/src/components/text-input/text-input.vue +11 -29
- package/src/composables/index.ts +2 -0
- package/src/composables/use-direction.ts +40 -0
- package/src/composables/use-tab-observer.ts +50 -0
|
@@ -4,20 +4,50 @@ import type { HTMLAttributes } from 'vue';
|
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
import { TabsList } from 'reka-ui';
|
|
6
6
|
import { useDelegatedProps } from '@/composables/use-delegated-props';
|
|
7
|
+
import { useTabObserver } from '@/composables/use-tab-observer';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
export interface TabMenuListProps extends TabsListProps {
|
|
10
|
+
class?: HTMLAttributes['class'];
|
|
11
|
+
bordered?: boolean;
|
|
12
|
+
scrollable?: boolean;
|
|
13
|
+
fill?: boolean;
|
|
14
|
+
align?: 'start' | 'center';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const props = withDefaults(defineProps<TabMenuListProps>(), {
|
|
18
|
+
bordered: true,
|
|
19
|
+
scrollable: false,
|
|
20
|
+
fill: false,
|
|
21
|
+
align: 'start',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const delegatedProps = useDelegatedProps(props, ['class', 'bordered', 'scrollable', 'fill', 'align']);
|
|
25
|
+
|
|
26
|
+
const { listRef, indicator, ready } = useTabObserver('[data-state="active"]');
|
|
10
27
|
</script>
|
|
11
28
|
|
|
12
29
|
<template>
|
|
13
30
|
<TabsList
|
|
31
|
+
ref="listRef"
|
|
14
32
|
v-bind="delegatedProps"
|
|
33
|
+
:data-bordered="bordered"
|
|
34
|
+
:data-scrollable="scrollable"
|
|
35
|
+
:data-fill="fill"
|
|
36
|
+
:data-align="align"
|
|
15
37
|
:class="clsx(
|
|
16
38
|
'celeste-tab-menu-list',
|
|
17
39
|
props.class,
|
|
18
40
|
)"
|
|
19
41
|
>
|
|
20
42
|
<slot />
|
|
43
|
+
<div
|
|
44
|
+
:hidden="!ready"
|
|
45
|
+
class="celeste-tab-menu-indicator"
|
|
46
|
+
:style="{
|
|
47
|
+
width: `${indicator.width}px`,
|
|
48
|
+
transform: `translate3d(${indicator.left}px, 0, 0)`,
|
|
49
|
+
}"
|
|
50
|
+
/>
|
|
21
51
|
</TabsList>
|
|
22
52
|
</template>
|
|
23
53
|
|
|
@@ -31,14 +61,66 @@ const delegatedProps = useDelegatedProps(props, 'class');
|
|
|
31
61
|
gap: var(--spacing-8);
|
|
32
62
|
|
|
33
63
|
&[data-orientation='horizontal'] {
|
|
64
|
+
position: relative;
|
|
34
65
|
flex-direction: row;
|
|
35
66
|
padding: var(--spacing-0);
|
|
36
|
-
border-block: 1px solid var(--color-stroke-soft-200);
|
|
37
67
|
gap: 24px;
|
|
68
|
+
|
|
69
|
+
&[data-bordered='true'] {
|
|
70
|
+
border-block: 1px solid var(--color-stroke-soft-200);
|
|
71
|
+
}
|
|
38
72
|
}
|
|
39
73
|
|
|
40
74
|
&[data-orientation='vertical'] {
|
|
41
75
|
flex-direction: column;
|
|
42
76
|
}
|
|
77
|
+
|
|
78
|
+
&[data-scrollable='true'] {
|
|
79
|
+
overflow-x: auto;
|
|
80
|
+
scrollbar-width: none;
|
|
81
|
+
|
|
82
|
+
&::-webkit-scrollbar {
|
|
83
|
+
display: none;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&[data-fill='true'] :deep(.celeste-tab-menu-item) {
|
|
88
|
+
flex: 1 1 0;
|
|
89
|
+
width: auto;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&[data-align='center'] :deep(.celeste-tab-menu-item) {
|
|
93
|
+
justify-content: center;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
&[data-align='center'] :deep(.celeste-tab-menu-item-label) {
|
|
97
|
+
flex: 0 1 auto;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.celeste-tab-menu-indicator {
|
|
102
|
+
position: absolute;
|
|
103
|
+
bottom: -1px;
|
|
104
|
+
left: 0;
|
|
105
|
+
height: 2px;
|
|
106
|
+
transition-property: transform, width;
|
|
107
|
+
transition-duration: var(--animation-normal);
|
|
108
|
+
transition-timing-function: cubic-bezier(0.65, 0, 0.35, 1);
|
|
109
|
+
background-color: var(--color-primary-base);
|
|
110
|
+
pointer-events: none;
|
|
111
|
+
|
|
112
|
+
.celeste-tab-menu-list[data-scrollable='true'] > & {
|
|
113
|
+
bottom: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.celeste-tab-menu-list[data-orientation='vertical'] > & {
|
|
117
|
+
display: none;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@media (prefers-reduced-motion: reduce) {
|
|
122
|
+
.celeste-tab-menu-indicator {
|
|
123
|
+
transition-duration: 0s;
|
|
124
|
+
}
|
|
43
125
|
}
|
|
44
126
|
</style>
|
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { TabsRootEmits, TabsRootProps } from 'reka-ui';
|
|
3
|
-
import { TabsRoot, useForwardPropsEmits } from 'reka-ui';
|
|
3
|
+
import { ConfigProvider, TabsRoot, useForwardPropsEmits } from 'reka-ui';
|
|
4
|
+
import { useDirection } from '@/composables/use-direction';
|
|
4
5
|
|
|
5
6
|
const props = defineProps<TabsRootProps>();
|
|
6
7
|
const emits = defineEmits<TabsRootEmits>();
|
|
7
8
|
|
|
8
9
|
const forwarded = useForwardPropsEmits(props, emits);
|
|
10
|
+
|
|
11
|
+
const direction = useDirection();
|
|
9
12
|
</script>
|
|
10
13
|
|
|
11
14
|
<template>
|
|
12
|
-
<
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
+
<ConfigProvider :dir="props.dir ?? direction">
|
|
16
|
+
<TabsRoot
|
|
17
|
+
v-bind="forwarded"
|
|
18
|
+
class="celeste-tab-menu-root"
|
|
19
|
+
>
|
|
20
|
+
<slot />
|
|
21
|
+
</TabsRoot>
|
|
22
|
+
</ConfigProvider>
|
|
15
23
|
</template>
|
|
16
24
|
|
|
17
25
|
<style scoped>
|
|
@@ -270,41 +270,23 @@ function clearInput() {
|
|
|
270
270
|
|
|
271
271
|
:deep(.celeste-text-input-node.celeste-text-input-leading-node),
|
|
272
272
|
:deep(.celeste-text-input-node.celeste-text-input-trailing-node) {
|
|
273
|
-
height: calc(var(--input-height) - var(--spacing-2))
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
[dir='ltr'] & {
|
|
277
|
-
:deep(.celeste-text-input-node.celeste-text-input-leading-node) {
|
|
278
|
-
border-right: 1px solid var(--color-stroke-soft-200) !important;
|
|
279
|
-
border-radius: var(--input-radius) 0 0 var(--input-radius) !important;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
:deep(.celeste-text-input-node.celeste-text-input-trailing-node) {
|
|
283
|
-
border-left: 1px solid var(--color-stroke-soft-200) !important;
|
|
284
|
-
border-radius: 0 var(--input-radius) var(--input-radius) 0 !important;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
[dir='rtl'] & {
|
|
289
|
-
:deep(.celeste-text-input-node.celeste-text-input-leading-node) {
|
|
290
|
-
border-left: 1px solid var(--color-stroke-soft-200) !important;
|
|
291
|
-
border-radius: 0 var(--input-radius) var(--input-radius) 0 !important;
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
:deep(.celeste-text-input-node.celeste-text-input-trailing-node) {
|
|
295
|
-
border-right: 1px solid var(--color-stroke-soft-200) !important;
|
|
296
|
-
border-radius: var(--input-radius) 0 0 var(--input-radius) !important;
|
|
297
|
-
}
|
|
273
|
+
height: calc(var(--input-height) - var(--spacing-2));
|
|
298
274
|
}
|
|
299
275
|
|
|
300
276
|
:deep(.celeste-text-input-node.celeste-text-input-leading-node) {
|
|
301
|
-
border-
|
|
302
|
-
border-radius: var(--input-radius)
|
|
277
|
+
border-inline-end: 1px solid var(--color-stroke-soft-200);
|
|
278
|
+
border-start-start-radius: var(--input-radius);
|
|
279
|
+
border-start-end-radius: 0;
|
|
280
|
+
border-end-end-radius: 0;
|
|
281
|
+
border-end-start-radius: var(--input-radius);
|
|
303
282
|
}
|
|
304
283
|
|
|
305
284
|
:deep(.celeste-text-input-node.celeste-text-input-trailing-node) {
|
|
306
|
-
border-
|
|
307
|
-
border-
|
|
285
|
+
border-inline-start: 1px solid var(--color-stroke-soft-200);
|
|
286
|
+
border-start-start-radius: 0;
|
|
287
|
+
border-start-end-radius: var(--input-radius);
|
|
288
|
+
border-end-end-radius: var(--input-radius);
|
|
289
|
+
border-end-start-radius: 0;
|
|
308
290
|
}
|
|
309
291
|
}
|
|
310
292
|
</style>
|
package/src/composables/index.ts
CHANGED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Direction } from 'reka-ui';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
import { getCurrentInstance, onMounted, ref, watch } from 'vue';
|
|
4
|
+
|
|
5
|
+
const revision = ref(0);
|
|
6
|
+
|
|
7
|
+
let observer: MutationObserver | undefined;
|
|
8
|
+
|
|
9
|
+
function observeDocument(): void {
|
|
10
|
+
if (observer || typeof document === 'undefined')
|
|
11
|
+
return;
|
|
12
|
+
|
|
13
|
+
observer = new MutationObserver(() => revision.value++);
|
|
14
|
+
observer.observe(document.documentElement, { attributeFilter: ['dir'], subtree: true });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function documentDirection(): Direction {
|
|
18
|
+
return typeof document !== 'undefined' && document.documentElement.dir === 'rtl' ? 'rtl' : 'ltr';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function useDirection(): Ref<Direction> {
|
|
22
|
+
const instance = getCurrentInstance();
|
|
23
|
+
const direction = ref<Direction>(documentDirection());
|
|
24
|
+
|
|
25
|
+
observeDocument();
|
|
26
|
+
|
|
27
|
+
function read(): void {
|
|
28
|
+
const node = instance?.vnode.el as Node | null | undefined;
|
|
29
|
+
const element = node instanceof HTMLElement ? node : node?.parentElement;
|
|
30
|
+
|
|
31
|
+
direction.value = element
|
|
32
|
+
? getComputedStyle(element).direction === 'rtl' ? 'rtl' : 'ltr'
|
|
33
|
+
: documentDirection();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
onMounted(read);
|
|
37
|
+
watch(revision, read);
|
|
38
|
+
|
|
39
|
+
return direction;
|
|
40
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { MaybeElement } from '@vueuse/core';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
import { unrefElement, useMutationObserver, useResizeObserver } from '@vueuse/core';
|
|
4
|
+
import { ref, shallowRef } from 'vue';
|
|
5
|
+
|
|
6
|
+
export interface TabIndicator {
|
|
7
|
+
left: number;
|
|
8
|
+
top: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TabObserver {
|
|
14
|
+
listRef: Ref<MaybeElement>;
|
|
15
|
+
indicator: Ref<TabIndicator>;
|
|
16
|
+
ready: Ref<boolean>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function useTabObserver(activeSelector: string): TabObserver {
|
|
20
|
+
const listRef = shallowRef<MaybeElement>(null);
|
|
21
|
+
const indicator = ref<TabIndicator>({ left: 0, top: 0, width: 0, height: 0 });
|
|
22
|
+
const ready = ref(false);
|
|
23
|
+
|
|
24
|
+
function update(): void {
|
|
25
|
+
const active = unrefElement(listRef)?.querySelector<HTMLElement>(activeSelector);
|
|
26
|
+
if (!active) {
|
|
27
|
+
ready.value = false;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
indicator.value = {
|
|
32
|
+
left: active.offsetLeft,
|
|
33
|
+
top: active.offsetTop,
|
|
34
|
+
width: active.offsetWidth,
|
|
35
|
+
height: active.offsetHeight,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
ready.value = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
useResizeObserver(listRef, update);
|
|
42
|
+
useMutationObserver(listRef, update, {
|
|
43
|
+
childList: true,
|
|
44
|
+
subtree: true,
|
|
45
|
+
attributes: true,
|
|
46
|
+
attributeFilter: ['data-state'],
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return { listRef, indicator, ready };
|
|
50
|
+
}
|