tera-system-ui 0.0.22 → 0.0.24

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.
Files changed (35) hide show
  1. package/dist/components/dialog/Dialog.astro +2 -1
  2. package/dist/components/dialog/Dialog.d.ts +2 -0
  3. package/dist/components/dialog/Dialog.svelte +8 -8
  4. package/dist/components/dialog/Dialog.svelte.d.ts +1 -1
  5. package/dist/components/slider/Slider.d.ts +9 -0
  6. package/dist/components/slider/Slider.js +7 -0
  7. package/dist/components/slider/Slider.svelte +228 -0
  8. package/dist/components/slider/Slider.svelte.d.ts +3 -0
  9. package/dist/components/slider/index.d.ts +1 -0
  10. package/dist/components/slider/index.js +1 -0
  11. package/dist/components/tabs/Tabs.d.ts +17 -0
  12. package/dist/components/tabs/Tabs.js +15 -0
  13. package/dist/components/tabs/components/Tabs.svelte +48 -0
  14. package/dist/components/tabs/components/Tabs.svelte.d.ts +3 -0
  15. package/dist/components/tabs/components/TabsContent.svelte +36 -0
  16. package/dist/components/tabs/components/TabsContent.svelte.d.ts +6 -0
  17. package/dist/components/tabs/components/TabsItem.svelte +32 -0
  18. package/dist/components/tabs/components/TabsItem.svelte.d.ts +6 -0
  19. package/dist/components/tabs/components/TabsList.svelte +42 -0
  20. package/dist/components/tabs/components/TabsList.svelte.d.ts +5 -0
  21. package/dist/components/tabs/index.d.ts +4 -0
  22. package/dist/components/tabs/index.js +4 -0
  23. package/dist/components/tabs/tabs.svelte.d.ts +3 -0
  24. package/dist/components/tabs/tabs.svelte.js +11 -0
  25. package/dist/components/text-area/TextArea.d.ts +145 -0
  26. package/dist/components/text-area/TextArea.js +39 -0
  27. package/dist/components/text-area/TextArea.svelte +89 -0
  28. package/dist/components/text-area/TextArea.svelte.d.ts +3 -0
  29. package/dist/components/text-area/index.d.ts +1 -0
  30. package/dist/components/text-area/index.js +1 -0
  31. package/dist/components/user-avatar-with-menu/UserAvatarWithMenu.svelte +3 -3
  32. package/dist/index.d.ts +3 -0
  33. package/dist/index.js +3 -0
  34. package/dist/themes/tera-ui-base.css +2 -4
  35. package/package.json +22 -22
@@ -11,6 +11,7 @@ const {
11
11
  class: className,
12
12
  position = 'center',
13
13
  padding,
14
+ containerClass,
14
15
  focusTriggerAfterClose,
15
16
  ...props
16
17
  }: DialogPropsAstro = Astro.props
@@ -44,7 +45,7 @@ const hasFooterSlot = !!Astro.slots["footer"];
44
45
  </form>
45
46
  }
46
47
 
47
- <div class={"dialog-box " + dialogContainer()}>
48
+ <div class={"dialog-box " + dialogContainer({className: containerClass})}>
48
49
  {hasHeaderSlot &&
49
50
  <header class={headerStyle()}>
50
51
  <slot name="header"/>
@@ -198,6 +198,7 @@ type DialogPropsCommon = {
198
198
  position?: 'top' | 'center';
199
199
  focusTriggerAfterClose?: boolean;
200
200
  padding?: 'none' | undefined;
201
+ containerClass?: string;
201
202
  };
202
203
  export type DialogProps = DialogVariants & DialogPropsCommon & {
203
204
  children?: any;
@@ -206,6 +207,7 @@ export type DialogProps = DialogVariants & DialogPropsCommon & {
206
207
  open?: boolean;
207
208
  staticRender?: boolean;
208
209
  triggerRef?: HTMLElement;
210
+ ref?: any;
209
211
  };
210
212
  export type DialogPropsAstro = DialogVariants & DialogPropsCommon & {};
211
213
  export {};
@@ -7,6 +7,7 @@
7
7
 
8
8
  let {
9
9
  children, open = $bindable(),
10
+ ref = $bindable(),
10
11
  closeOnClickOutside = true,
11
12
  closeButton = true,
12
13
  size = 'sm',
@@ -18,23 +19,22 @@
18
19
  staticRender = false,
19
20
  triggerRef,
20
21
  focusTriggerAfterClose,
22
+ containerClass,
21
23
  ...props
22
24
  }: DialogProps = $props();
23
25
 
24
- let dialog;
25
-
26
26
  let hasOpened = $state(false);
27
27
 
28
28
  // Watch for prop changes to open/close the dialog
29
29
  $effect(() => {
30
30
  if (open) {
31
31
  stillAnimating = open
32
- dialog?.showModal();
32
+ ref?.showModal();
33
33
 
34
34
  if (!hasOpened)
35
35
  hasOpened = true
36
36
  } else {
37
- dialog?.close()
37
+ ref?.close()
38
38
  sleep(200).then(() => {
39
39
  stillAnimating = open
40
40
  console.log('stillAnimating', stillAnimating)
@@ -48,8 +48,8 @@
48
48
 
49
49
  // Close dialog on clicking outside (optional)
50
50
  function handleClickOutside(e) {
51
- if (closeOnClickOutside && e.target === dialog) {
52
- dialog?.close();
51
+ if (closeOnClickOutside && e.target === ref) {
52
+ ref?.close();
53
53
  }
54
54
  }
55
55
 
@@ -72,7 +72,7 @@
72
72
  {#if staticRender || (!staticRender && (open || stillAnimating))}
73
73
  <dialog class={dialogStyle() + ` ${className}`}
74
74
  data-position={position}
75
- bind:this={dialog}
75
+ bind:this={ref}
76
76
  onclose={handleClose}
77
77
  onmousedown={handleClickOutside}
78
78
  size={size}
@@ -90,7 +90,7 @@
90
90
  </form>
91
91
  {/if}
92
92
 
93
- <div class={"dialog-box " + dialogContainer()}>
93
+ <div class={"dialog-box " + dialogContainer({className: containerClass})}>
94
94
  {#if header}
95
95
  <header class={headerStyle()}>
96
96
  {@render header?.()}
@@ -1,4 +1,4 @@
1
1
  import { type DialogProps } from "./Dialog";
2
2
  import './dialog.scss';
3
- declare const Dialog: import("svelte").Component<DialogProps, {}, "open">;
3
+ declare const Dialog: import("svelte").Component<DialogProps, {}, "ref" | "open">;
4
4
  export default Dialog;
@@ -0,0 +1,9 @@
1
+ import { type VariantProps } from "tailwind-variants";
2
+ export declare const styles: import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, {}, undefined, import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, unknown, unknown, undefined>>;
3
+ type SliderVariants = VariantProps<typeof styles>;
4
+ export interface SliderProps extends SliderVariants {
5
+ children?: any;
6
+ class?: string;
7
+ }
8
+ export type SliderContextProps = {};
9
+ export {};
@@ -0,0 +1,7 @@
1
+ import { tv } from "tailwind-variants";
2
+ export const styles = tv({
3
+ base: '',
4
+ variants: {},
5
+ compoundVariants: [],
6
+ defaultVariants: {},
7
+ });
@@ -0,0 +1,228 @@
1
+ <script lang="ts">
2
+ import {type SliderProps} from "./Slider";
3
+
4
+ let {
5
+ children,
6
+ min = 0,
7
+ max = 100,
8
+ step = 1,
9
+ value = $bindable(),
10
+ showTicks = false,
11
+ onchange,
12
+ ...props
13
+ }: SliderProps = $props();
14
+
15
+
16
+ let slider = $state<HTMLElement>()
17
+ let sliderHandle = $state<HTMLElement>()
18
+ let sliderTrack = $state<HTMLElement>()
19
+ let sliderRail = $state<HTMLElement>()
20
+ let sliderTooltip = $state<HTMLElement>()
21
+
22
+
23
+ $effect(() => {
24
+ if (!slider || !sliderHandle || !sliderTrack || !sliderRail) return
25
+ slider.addEventListener('pointerdown', (e) => {
26
+ sliderHandle.setAttribute('data-state', 'dragging');
27
+ onDrag(e)
28
+ document.addEventListener('pointermove', onDrag);
29
+ document.addEventListener('pointerup', () => {
30
+ document.removeEventListener('pointermove', onDrag);
31
+ sliderHandle.removeAttribute('data-state');
32
+ toggleToolTip(false)
33
+
34
+ }, {once: true});
35
+ });
36
+
37
+ // For touch support
38
+ slider.addEventListener('touchstart', (e) => {
39
+ sliderHandle.setAttribute('data-state', 'dragging');
40
+ onDrag(e)
41
+ document.addEventListener('touchmove', onDrag);
42
+ document.addEventListener('touchend', () => {
43
+ document.removeEventListener('touchmove', onDrag);
44
+ toggleToolTip(false)
45
+ sliderHandle.removeAttribute('data-state');
46
+ }, {once: true});
47
+ });
48
+
49
+ sliderHandle.addEventListener('pointerenter', (e) => {
50
+ toggleToolTip(true)
51
+ sliderHandle.addEventListener('pointerleave', (e) => {
52
+ toggleToolTip(false)
53
+ }, {once: true});
54
+ })
55
+
56
+ })
57
+
58
+ let tooltipInterval
59
+
60
+ function toggleToolTip(open) {
61
+ if (tooltipInterval) clearInterval(tooltipInterval)
62
+
63
+ if (open) {
64
+ sliderTooltip.classList.add('show');
65
+ } else {
66
+ tooltipInterval = setTimeout(() => {
67
+ sliderTooltip.classList.remove('show');
68
+ }, 300)
69
+
70
+ }
71
+ }
72
+
73
+ const calculateValue = (position) => {
74
+ const sliderWidth = sliderRail.offsetWidth;
75
+
76
+ // calculate step size in px
77
+ const stepSize = sliderWidth / ((max - min) / step)
78
+
79
+ // Clamp position within the slider width
80
+ const clampedPosition = Math.max(0, Math.min(position, sliderWidth));
81
+ // Calculate nearest step position
82
+ const stepCount = Math.round(clampedPosition / stepSize);
83
+
84
+ console.log(stepCount)
85
+ return min + stepCount
86
+ };
87
+
88
+ const onDrag = (event) => {
89
+ event.preventDefault();
90
+ event.stopPropagation();
91
+ toggleToolTip(true)
92
+
93
+ let position
94
+
95
+ if (event.type.startsWith('touch')) {
96
+ const touch = event.touches[0];
97
+ position = touch.clientX - slider.getBoundingClientRect().left;
98
+ } else {
99
+ position = event.clientX - slider.getBoundingClientRect().left;
100
+ }
101
+ let newValue = calculateValue(position);
102
+
103
+ if (newValue !== value) {
104
+ value = newValue;
105
+ onchange?.(value);
106
+ }
107
+
108
+ updateSliderByValue(newValue)
109
+ };
110
+
111
+
112
+ $effect(() => {
113
+ if (value == undefined) {
114
+ value = min
115
+ }
116
+ updateSliderByValue(value)
117
+ })
118
+
119
+ function updateSliderByValue(v: number) {
120
+ const percentage = ((value - min) / (max - min)) * 100
121
+
122
+ // Update the position of the handle and track width
123
+ sliderHandle.style.left = `${percentage}%`;
124
+ sliderTooltip.style.left = `${percentage}%`;
125
+ sliderTrack.style.width = `${percentage}%`;
126
+ }
127
+ </script>
128
+
129
+
130
+ <div bind:this={slider} class="cursor-pointer w-full relative mx-1 py-2.5">
131
+ <div data-slider-rail bind:this={sliderRail} class="w-full h-1.5 bg-neutral-token-4 rounded-full overflow-hidden">
132
+ <div data-slider-track bind:this={sliderTrack} class="rounded-full w-full h-full bg-primary-token-4"></div>
133
+ </div>
134
+
135
+ <div
136
+ bind:this={sliderHandle}
137
+ data-slider-handle
138
+ tabindex="0"
139
+ role="slider"
140
+ aria-valuemin={`${(min ?? 0)}`}
141
+ aria-valuemax={`${(max ?? 0)}`}
142
+ aria-valuenow={`${(value ?? 0)}`}
143
+ aria-orientation="horizontal"
144
+ class="slider-handle -translate-x-1/2 absolute top-1/2 -translate-y-1/2 rounded-full bg-neutral-token-1 border-[3px] border-primary-token-5 size-4"
145
+ >
146
+
147
+ </div>
148
+
149
+ <div bind:this={sliderTooltip} data-slider-tooltip class="">
150
+ <span class="z-10 relative">
151
+ {value}
152
+ </span>
153
+ </div>
154
+
155
+ <!-- <input-->
156
+ <!-- type="range"-->
157
+ <!-- min={min}-->
158
+ <!-- max={max}-->
159
+ <!-- step={step}-->
160
+ <!-- oninput={(event) => {-->
161
+ <!-- value = event.target.value;-->
162
+ <!-- handleChange(event);-->
163
+ <!-- }}-->
164
+ <!-- class="w-full appearance-none bg-gray-300 rounded-lg h-2 focus:outline-none focus:ring-2 focus:ring-blue-500 transition"-->
165
+ <!-- />-->
166
+
167
+ <!-- {#if showTicks}-->
168
+ <!-- <div class="relative mt-2 flex justify-between text-xs text-gray-500">-->
169
+ <!-- {#each ticks as tick}-->
170
+ <!-- <div class="flex-1">-->
171
+ <!-- <div-->
172
+ <!-- class="h-2 w-0.5 bg-gray-400 mx-auto"-->
173
+ <!-- style="transform: translateX(-50%);"-->
174
+ <!-- ></div>-->
175
+ <!-- </div>-->
176
+ <!-- {/each}-->
177
+ <!-- </div>-->
178
+ <!-- {/if}-->
179
+ </div>
180
+
181
+ <style>.slider-handle {
182
+ transition: all 0.2s ease-in-out, left 0s;
183
+ }
184
+ .slider-handle:global([data-state="dragging"]), .slider-handle:hover, .slider-handle:focus, .slider-handle:active, .slider-handle:focus-visible {
185
+ --tw-scale-x: 1.25;
186
+ --tw-scale-y: 1.25;
187
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
188
+ border-color: hsl(var(--tw---token-color-primary-token-7));
189
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
190
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0.35rem + var(--tw-ring-offset-width)) var(--tw-ring-color);
191
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
192
+ --tw-ring-color: hsl(var(--tw---token-color-primary-token-2));
193
+ }
194
+
195
+ [data-slider-tooltip] {
196
+ position: absolute;
197
+ left: 50%;
198
+ z-index: 10;
199
+ width: -moz-fit-content;
200
+ width: fit-content;
201
+ border-radius: var(--border-radius-base);
202
+ background-color: hsl(var(--tw---token-color-neutral-token-12));
203
+ padding-left: 0.375rem;
204
+ padding-right: 0.375rem;
205
+ padding-top: 0.25rem;
206
+ padding-bottom: 0.25rem;
207
+ color: hsl(var(--tw---token-color-neutral-token-1));
208
+ transition: all 0.2s ease-in-out, left 0s;
209
+ opacity: 0;
210
+ transform: translateY(-3rem) translateX(-50%) scale(0.9);
211
+ }
212
+ [data-slider-tooltip]:after {
213
+ content: "";
214
+ position: absolute;
215
+ bottom: -0.15rem;
216
+ left: 50%;
217
+ width: 0.75rem;
218
+ height: 0.75rem;
219
+ --tw-translate-x: -50%;
220
+ --tw-rotate: 45deg;
221
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
222
+ border-radius: 0.125rem;
223
+ background-color: hsl(var(--tw---token-color-neutral-token-12));
224
+ }
225
+ [data-slider-tooltip]:global(.show) {
226
+ opacity: 1;
227
+ transform: translateY(-3.5rem) translateX(-50%) scale(1);
228
+ }</style>
@@ -0,0 +1,3 @@
1
+ import { type SliderProps } from "./Slider";
2
+ declare const Slider: import("svelte").Component<SliderProps, {}, "value">;
3
+ export default Slider;
@@ -0,0 +1 @@
1
+ export { default as Slider } from './Slider.svelte';
@@ -0,0 +1 @@
1
+ export { default as Slider } from './Slider.svelte';
@@ -0,0 +1,17 @@
1
+ import { type VariantProps } from "tailwind-variants";
2
+ export declare const styles: import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, {}, undefined, import("tailwind-variants").TVReturnType<{}, undefined, "", import("tailwind-variants/dist/config").TVConfig<{}, {}>, unknown, unknown, undefined>>;
3
+ type TabsVariants = VariantProps<typeof styles>;
4
+ export interface TabsProps extends TabsVariants {
5
+ children?: any;
6
+ class?: string;
7
+ value?: string;
8
+ }
9
+ export type TabsContext = {
10
+ setValue: (value: string) => void;
11
+ getValue: () => string | undefined;
12
+ currentTab?: any;
13
+ state: any;
14
+ };
15
+ export declare function getCtx(): TabsContext;
16
+ export declare function setCtx(context: TabsContext): void;
17
+ export {};
@@ -0,0 +1,15 @@
1
+ import { tv } from "tailwind-variants";
2
+ import { getContext, setContext } from "svelte";
3
+ export const styles = tv({
4
+ base: '',
5
+ variants: {},
6
+ compoundVariants: [],
7
+ defaultVariants: {},
8
+ });
9
+ const CONTEXT_NAME = 'Tabs';
10
+ export function getCtx() {
11
+ return getContext(CONTEXT_NAME);
12
+ }
13
+ export function setCtx(context) {
14
+ setContext(CONTEXT_NAME, context);
15
+ }
@@ -0,0 +1,48 @@
1
+ <script lang="ts">
2
+ import {setCtx, type TabsProps} from "../Tabs";
3
+ import {cn} from "../../../utils/utils";
4
+ import {createTabs} from "../tabs.svelte";
5
+ import {untrack} from "svelte";
6
+
7
+ let {
8
+ children,
9
+ value = $bindable(),
10
+ class: className,
11
+ ...props
12
+ }: TabsProps = $props();
13
+
14
+
15
+ function setValue(v: string) {
16
+ console.log('Change value', v)
17
+ value = v
18
+ }
19
+
20
+ function getValue() {
21
+ return value
22
+ }
23
+
24
+ let tabsState = createTabs(value)
25
+
26
+ setCtx({
27
+ setValue: setValue,
28
+ getValue: getValue,
29
+ currentTab: value,
30
+ state: tabsState
31
+ })
32
+
33
+ $effect(() => {
34
+ value = tabsState.currentTab
35
+ })
36
+
37
+ $effect(() => {
38
+ tabsState.currentTab = value
39
+ })
40
+
41
+ let tabs = $state()
42
+ </script>
43
+
44
+ <div bind:this={tabs}
45
+ data-tabs-root
46
+ class={cn("grid grid-rows-[auto_1fr] max-h-full gap-2", className)}>
47
+ {@render children?.()}
48
+ </div>
@@ -0,0 +1,3 @@
1
+ import { type TabsProps } from "../Tabs";
2
+ declare const Tabs: import("svelte").Component<TabsProps, {}, "value">;
3
+ export default Tabs;
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import {getCtx} from "../Tabs";
3
+ import {cn} from "../../../utils/utils";
4
+
5
+ let {
6
+ children,
7
+ class: className,
8
+ value,
9
+ ...props
10
+ } = $props();
11
+
12
+ let context = getCtx()
13
+
14
+ $effect(() => {
15
+ // console.log(context.state.currentTab)
16
+ })
17
+ </script>
18
+
19
+ <div
20
+ role="tabpanel"
21
+ data-value={value}
22
+ data-state={context.state.currentTab === value ? 'active' : 'inactive'}
23
+ class={cn("bg-neutral-token-1 overflow-auto", className)}>
24
+ {@render children?.()}
25
+ </div>
26
+
27
+ <style>
28
+ [data-state="active"] {
29
+ display: block
30
+ }
31
+ [data-state="inactive"] {
32
+ display: none
33
+ }
34
+
35
+ </style>
36
+
@@ -0,0 +1,6 @@
1
+ declare const TabsContent: import("svelte").Component<{
2
+ children: unknown;
3
+ class: unknown;
4
+ value: unknown;
5
+ } & Record<string, unknown>, {}, "">;
6
+ export default TabsContent;
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import {cn} from "../../../utils/utils";
3
+ import {getCtx} from "../Tabs";
4
+
5
+ let {
6
+ children,
7
+ class: className,
8
+ value,
9
+ ...props
10
+ } = $props();
11
+
12
+ let context = getCtx()
13
+
14
+ </script>
15
+
16
+ <div>
17
+ <button class={cn("tab-button font-semibold px-2.5 py-1.5 text-neutral-token-8 hover:text-primary-token-4")}
18
+ data-value={value}
19
+ data-state={value === context.state.currentTab ? 'active' : 'inactive'}
20
+ onclick={() => {
21
+ context.state.currentTab = value
22
+ }}
23
+ >
24
+ {@render children?.()}
25
+ </button>
26
+ </div>
27
+
28
+ <style>
29
+ button[data-state="active"] {
30
+ color: hsl(var(--tw---token-color-primary-token-6))
31
+ }
32
+ </style>
@@ -0,0 +1,6 @@
1
+ declare const TabsItem: import("svelte").Component<{
2
+ children: unknown;
3
+ class: unknown;
4
+ value: unknown;
5
+ } & Record<string, unknown>, {}, "">;
6
+ export default TabsItem;
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ import {cn} from "../../../utils/utils";
3
+ import {getCtx} from "../Tabs";
4
+
5
+ let {
6
+ children,
7
+ class: className,
8
+ ...props
9
+ } = $props();
10
+
11
+ let tabIndicator = $state()
12
+ let tabsList = $state()
13
+
14
+ function updateIndicator(button) {
15
+ const rect = button.getBoundingClientRect();
16
+ const containerRect = tabsList.getBoundingClientRect();
17
+
18
+ const left = rect.left - containerRect.left;
19
+ const width = rect.width;
20
+
21
+ tabIndicator.style.left = `${left}px`;
22
+ tabIndicator.style.width = `${width}px`;
23
+ }
24
+
25
+
26
+ let context = getCtx()
27
+
28
+ $effect(() => {
29
+ let tabButton = tabsList?.querySelector(`button[data-value="${context.state.currentTab}"]`)
30
+ updateIndicator(tabButton);
31
+ })
32
+ </script>
33
+
34
+ <div bind:this={tabsList}
35
+ data-tabs-list
36
+ role="tablist"
37
+ data-orientation="horizontal"
38
+ class={cn("relative flex gap-2 items-end border-b border-neutral-token-5")}>
39
+
40
+ {@render children?.()}
41
+ <div bind:this={tabIndicator} class="absolute bottom-0 h-0.5 bg-primary-token-5 transition-all duration-300"></div>
42
+ </div>
@@ -0,0 +1,5 @@
1
+ declare const TabsList: import("svelte").Component<{
2
+ children: unknown;
3
+ class: unknown;
4
+ } & Record<string, unknown>, {}, "">;
5
+ export default TabsList;
@@ -0,0 +1,4 @@
1
+ export { default as Tabs } from './components/Tabs.svelte';
2
+ export { default as TabsList } from './components/TabsList.svelte';
3
+ export { default as TabsItem } from './components/TabsItem.svelte';
4
+ export { default as TabsContent } from './components/TabsContent.svelte';
@@ -0,0 +1,4 @@
1
+ export { default as Tabs } from './components/Tabs.svelte';
2
+ export { default as TabsList } from './components/TabsList.svelte';
3
+ export { default as TabsItem } from './components/TabsItem.svelte';
4
+ export { default as TabsContent } from './components/TabsContent.svelte';
@@ -0,0 +1,3 @@
1
+ export declare function createTabs(initTab?: string): {
2
+ currentTab: string | undefined;
3
+ };
@@ -0,0 +1,11 @@
1
+ export function createTabs(initTab) {
2
+ let currentTab = $state(initTab);
3
+ return {
4
+ get currentTab() {
5
+ return currentTab;
6
+ },
7
+ set currentTab(v) {
8
+ currentTab = v;
9
+ }
10
+ };
11
+ }
@@ -0,0 +1,145 @@
1
+ import { type VariantProps } from "tailwind-variants";
2
+ export declare const styles: import("tailwind-variants").TVReturnType<{
3
+ variant: {
4
+ outlined: string;
5
+ filled: string;
6
+ borderless: string;
7
+ };
8
+ disabled: {
9
+ true: string;
10
+ false: string;
11
+ };
12
+ size: {
13
+ sm: string;
14
+ md: string;
15
+ lg: string;
16
+ };
17
+ allowClear: {
18
+ true: string;
19
+ };
20
+ }, undefined, "relative w-full inline-flex items-center justify-center rounded outline-none transition ease-in-out ring-primary-token-5/50", import("tailwind-variants/dist/config").TVConfig<{
21
+ variant: {
22
+ outlined: string;
23
+ filled: string;
24
+ borderless: string;
25
+ };
26
+ disabled: {
27
+ true: string;
28
+ false: string;
29
+ };
30
+ size: {
31
+ sm: string;
32
+ md: string;
33
+ lg: string;
34
+ };
35
+ allowClear: {
36
+ true: string;
37
+ };
38
+ }, {
39
+ variant: {
40
+ outlined: string;
41
+ filled: string;
42
+ borderless: string;
43
+ };
44
+ disabled: {
45
+ true: string;
46
+ false: string;
47
+ };
48
+ size: {
49
+ sm: string;
50
+ md: string;
51
+ lg: string;
52
+ };
53
+ allowClear: {
54
+ true: string;
55
+ };
56
+ }>, {
57
+ variant: {
58
+ outlined: string;
59
+ filled: string;
60
+ borderless: string;
61
+ };
62
+ disabled: {
63
+ true: string;
64
+ false: string;
65
+ };
66
+ size: {
67
+ sm: string;
68
+ md: string;
69
+ lg: string;
70
+ };
71
+ allowClear: {
72
+ true: string;
73
+ };
74
+ }, undefined, import("tailwind-variants").TVReturnType<{
75
+ variant: {
76
+ outlined: string;
77
+ filled: string;
78
+ borderless: string;
79
+ };
80
+ disabled: {
81
+ true: string;
82
+ false: string;
83
+ };
84
+ size: {
85
+ sm: string;
86
+ md: string;
87
+ lg: string;
88
+ };
89
+ allowClear: {
90
+ true: string;
91
+ };
92
+ }, undefined, "relative w-full inline-flex items-center justify-center rounded outline-none transition ease-in-out ring-primary-token-5/50", import("tailwind-variants/dist/config").TVConfig<{
93
+ variant: {
94
+ outlined: string;
95
+ filled: string;
96
+ borderless: string;
97
+ };
98
+ disabled: {
99
+ true: string;
100
+ false: string;
101
+ };
102
+ size: {
103
+ sm: string;
104
+ md: string;
105
+ lg: string;
106
+ };
107
+ allowClear: {
108
+ true: string;
109
+ };
110
+ }, {
111
+ variant: {
112
+ outlined: string;
113
+ filled: string;
114
+ borderless: string;
115
+ };
116
+ disabled: {
117
+ true: string;
118
+ false: string;
119
+ };
120
+ size: {
121
+ sm: string;
122
+ md: string;
123
+ lg: string;
124
+ };
125
+ allowClear: {
126
+ true: string;
127
+ };
128
+ }>, unknown, unknown, undefined>>;
129
+ type TextAreaVariants = VariantProps<typeof styles>;
130
+ export type AutoSizeConfig = boolean | {
131
+ minRows?: number;
132
+ maxRows?: number;
133
+ };
134
+ export interface TextAreaProps extends TextAreaVariants {
135
+ children?: any;
136
+ class?: string;
137
+ value?: string;
138
+ ref?: HTMLInputElement;
139
+ prefix?: any;
140
+ onchange?: (event: any) => void;
141
+ autoSize?: AutoSizeConfig;
142
+ rows?: any;
143
+ allowClear?: boolean;
144
+ }
145
+ export {};
@@ -0,0 +1,39 @@
1
+ import { tv } from "tailwind-variants";
2
+ export const styles = tv({
3
+ base: 'relative w-full inline-flex items-center justify-center rounded outline-none transition ease-in-out ring-primary-token-5/50',
4
+ variants: {
5
+ variant: {
6
+ outlined: 'border border-neutral-token-5 bg-transparent focus:border-primary-token-6 hover:border-primary-token-5 focus-visible:ring-2',
7
+ filled: 'bg-neutral-token-3 border border-neutral-token-3 focus:bg-transparent focus:border-primary-token-6 hover:bg-neutral-token-4 focus-visible:ring-2',
8
+ borderless: 'bg-transparent border-0',
9
+ },
10
+ disabled: {
11
+ true: 'cursor-not-allowed opacity-70 text-neutral-token-10',
12
+ false: 'cursor-text',
13
+ },
14
+ size: {
15
+ sm: 'px-2 pt-0.5 pb-0.5 text-sm',
16
+ md: 'px-3 pt-1 pb-0.5 text-base',
17
+ lg: 'px-3 pt-1 pb-0.5 text-lg',
18
+ },
19
+ allowClear: {
20
+ true: 'pr-5'
21
+ }
22
+ },
23
+ compoundVariants: [
24
+ {
25
+ variant: 'outlined',
26
+ disabled: true,
27
+ class: 'hover:border-neutral-token-5'
28
+ },
29
+ {
30
+ variant: 'filled',
31
+ disabled: true,
32
+ class: 'hover:bg-neutral-token-3'
33
+ }
34
+ ],
35
+ defaultVariants: {
36
+ variant: 'outlined',
37
+ size: 'md'
38
+ },
39
+ });
@@ -0,0 +1,89 @@
1
+ <script lang="ts">
2
+ import {type AutoSizeConfig, type TextAreaProps} from "./TextArea";
3
+ import {styles} from "./TextArea";
4
+ import {IconX} from "../icons";
5
+
6
+ let {
7
+ children,
8
+ class: className,
9
+ value = $bindable(),
10
+ ref = $bindable(),
11
+ size,
12
+ disabled,
13
+ variant = 'outlined',
14
+ autoSize,
15
+ onchange,
16
+ prefix,
17
+ rows,
18
+ allowClear,
19
+ ...props
20
+ }: TextAreaProps = $props();
21
+
22
+
23
+ function createAutoSizeTextarea(node: HTMLTextAreaElement, autoSize?: AutoSizeConfig) {
24
+ if (!autoSize) {
25
+ return
26
+ }
27
+ let minRows: number | null = null
28
+ let maxRows: number | null = null
29
+ if (autoSize === true) {
30
+ minRows = 1
31
+ } else {
32
+ minRows = Math.max(autoSize.minRows || 0, 1)
33
+ maxRows = autoSize.maxRows || null
34
+
35
+ }
36
+
37
+ const updateSize = () => {
38
+ node.style.height = 'auto';
39
+ const computedStyle = window.getComputedStyle(node);
40
+ const borderTopWidth = parseFloat(computedStyle.borderTopWidth);
41
+ const borderBottomWidth = parseFloat(computedStyle.borderBottomWidth);
42
+ const offset = borderTopWidth + borderBottomWidth;
43
+ const scrollHeight = node.scrollHeight + 4
44
+
45
+ const lineHeight = parseFloat(computedStyle.lineHeight);
46
+ const minHeight = minRows * lineHeight + offset;
47
+ const maxHeight = maxRows ? maxRows * lineHeight : null;
48
+
49
+ node.style.height = `${Math.max(minHeight, Math.min(scrollHeight, maxHeight ?? scrollHeight))}px`;
50
+ };
51
+
52
+ $effect(() => {
53
+ // setup goes here
54
+ value
55
+ updateSize();
56
+
57
+ return () => {
58
+ // teardown goes here
59
+ };
60
+ });
61
+ }
62
+
63
+ function clearText() {
64
+ value = ''
65
+ }
66
+
67
+ </script>
68
+
69
+ <div class="relative">
70
+ <textarea
71
+ use:createAutoSizeTextarea={autoSize}
72
+ onchange={onchange}
73
+ bind:this={ref}
74
+ style={autoSize ? "resize: none;" : ''}
75
+ class={styles({ variant, disabled , size, className, allowClear })}
76
+ {disabled}
77
+ rows={autoSize ? 1 : rows}
78
+ {...props}
79
+ bind:value
80
+ >
81
+ </textarea>
82
+
83
+ {#if allowClear && value}
84
+ <button onclick={clearText}
85
+ class="absolute top-2 right-2 bg-neutral-token-6 text-neutral-token-1 hover:bg-neutral-token-8 size-3 grid place-content-center rounded-full">
86
+ <IconX class="size-2.5"/>
87
+ </button>
88
+ {/if}
89
+ </div>
@@ -0,0 +1,3 @@
1
+ import { type TextAreaProps } from "./TextArea";
2
+ declare const TextArea: import("svelte").Component<TextAreaProps, {}, "ref" | "value">;
3
+ export default TextArea;
@@ -0,0 +1 @@
1
+ export { default as TextArea } from './TextArea.svelte';
@@ -0,0 +1 @@
1
+ export { default as TextArea } from './TextArea.svelte';
@@ -13,14 +13,14 @@
13
13
 
14
14
  let {children, user, onLogout,...props}: UserAvatarWithMenuProps = $props();
15
15
 
16
- let shortUserName = extractShortUsernameFromEmail(user.email)
16
+ let shortUserName = extractShortUsernameFromEmail(user?.email)
17
17
  let triggerRef = $state()
18
- let open = $state(true)
18
+ let open = $state(false)
19
19
  </script>
20
20
 
21
21
 
22
22
  {#if user}
23
- <button bind:this={triggerRef}>
23
+ <button class="rounded-full focus-visible:ring-0" bind:this={triggerRef}>
24
24
  <Avatar
25
25
  userUid={user.userUid}
26
26
  >
package/dist/index.d.ts CHANGED
@@ -13,5 +13,8 @@ export { LightDarkToggle } from './components/light-dark-toggle';
13
13
  export { Popover } from './components/popover';
14
14
  export { PopoverResponsive } from './components/popover-responsive';
15
15
  export { SideNavigation, SideNavigationLayout, toggleSideNavigation } from './components/side-navigation';
16
+ export { Slider } from './components/slider';
17
+ export { Tabs, TabsList, TabsItem, TabsContent } from './components/tabs';
16
18
  export { TeraUiContext } from './components/tera-ui-context';
19
+ export { TextArea } from './components/text-area';
17
20
  export { UserAvatarWithMenu } from './components/user-avatar-with-menu';
package/dist/index.js CHANGED
@@ -13,5 +13,8 @@ export { LightDarkToggle } from './components/light-dark-toggle';
13
13
  export { Popover } from './components/popover';
14
14
  export { PopoverResponsive } from './components/popover-responsive';
15
15
  export { SideNavigation, SideNavigationLayout, toggleSideNavigation } from './components/side-navigation';
16
+ export { Slider } from './components/slider';
17
+ export { Tabs, TabsList, TabsItem, TabsContent } from './components/tabs';
16
18
  export { TeraUiContext } from './components/tera-ui-context';
19
+ export { TextArea } from './components/text-area';
17
20
  export { UserAvatarWithMenu } from './components/user-avatar-with-menu';
@@ -1,10 +1,8 @@
1
- /* Default base style */
1
+ @import "scrollbar.scss"; /* Default base style */
2
2
  @tailwind base;
3
3
  @tailwind components;
4
4
  @tailwind utilities;
5
5
 
6
- @import "scrollbar.scss";
7
-
8
6
  .ripple {
9
7
  position: absolute;
10
8
  border-radius: 50%;
@@ -50,7 +48,7 @@ body {
50
48
  -ms-overflow-style: none !important; /* IE and Edge */
51
49
  scrollbar-width: none !important; /* Firefox */
52
50
  }
53
-
51
+
54
52
  .skeleton {
55
53
  @apply animate-pulse bg-neutral-token-4 rounded h-4 w-full;
56
54
  }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "tera-system-ui",
3
- "version": "0.0.22",
3
+ "version": "0.0.24",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
- "build": "vite build && npm run package",
6
+ "build": "npm run customPrepublish && npm run generate-index && vite build && npm run package && npm run postpublish",
7
7
  "preview": "vite preview",
8
8
  "package": "svelte-kit sync && svelte-package && publint",
9
9
  "customPrepublish": "node ./scripts/prepublish.js",
@@ -60,39 +60,39 @@
60
60
  "svelte": "^5.0.0"
61
61
  },
62
62
  "devDependencies": {
63
- "@chromatic-com/storybook": "^3.2.1",
64
- "@storybook/addon-essentials": "^8.3.6",
65
- "@storybook/addon-interactions": "^8.3.6",
66
- "@storybook/addon-links": "^8.3.6",
63
+ "@chromatic-com/storybook": "^3.2.2",
64
+ "@storybook/addon-essentials": "^8.4.4",
65
+ "@storybook/addon-interactions": "^8.4.4",
66
+ "@storybook/addon-links": "^8.4.4",
67
67
  "@storybook/addon-styling": "^1.3.7",
68
68
  "@storybook/addon-svelte-csf": "^5.0.0-next.8",
69
- "@storybook/addon-themes": "^8.3.6",
70
- "@storybook/addon-viewport": "^8.3.6",
71
- "@storybook/blocks": "^8.3.6",
72
- "@storybook/svelte": "^8.3.6",
73
- "@storybook/sveltekit": "^8.3.6",
74
- "@storybook/test": "^8.3.6",
69
+ "@storybook/addon-themes": "^8.4.4",
70
+ "@storybook/addon-viewport": "^8.4.4",
71
+ "@storybook/blocks": "^8.4.4",
72
+ "@storybook/svelte": "^8.4.4",
73
+ "@storybook/sveltekit": "^8.4.4",
74
+ "@storybook/test": "^8.4.4",
75
75
  "@sveltejs/adapter-auto": "^3.3.1",
76
- "@sveltejs/kit": "^2.7.3",
76
+ "@sveltejs/kit": "^2.8.1",
77
77
  "@sveltejs/package": "^2.3.7",
78
- "@sveltejs/vite-plugin-svelte": "^4.0.0",
78
+ "@sveltejs/vite-plugin-svelte": "^4.0.1",
79
79
  "npx": "^10.2.2",
80
80
  "publint": "^0.2.12",
81
- "sass-embedded": "^1.80.5",
82
- "storybook": "^8.3.6",
83
- "svelte": "^5.1.6",
84
- "svelte-check": "^4.0.5",
85
- "tailwindcss": "^3.4.14",
81
+ "sass-embedded": "^1.81.0",
82
+ "storybook": "^8.4.4",
83
+ "svelte": "^5.2.1",
84
+ "svelte-check": "^4.0.8",
85
+ "tailwindcss": "^3.4.15",
86
86
  "typescript": "^5.6.3",
87
- "vite": "^5.4.10"
87
+ "vite": "^5.4.11"
88
88
  },
89
89
  "dependencies": {
90
90
  "@floating-ui/dom": "^1.6.12",
91
91
  "@inlang/paraglide-sveltekit": "0.11.5",
92
- "@tabler/icons-svelte": "^3.21.0",
92
+ "@tabler/icons-svelte": "^3.22.0",
93
93
  "clsx": "^2.1.1",
94
94
  "autoprefixer": "^10.4.20",
95
95
  "@inlang/paraglide-js": "1.11.3",
96
- "tailwind-variants": "^0.2.1"
96
+ "tailwind-variants": "^0.3.0"
97
97
  }
98
98
  }