fluid-ui-svelte 0.3.1 → 0.3.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.
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLButtonAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import { type Snippet } from 'svelte';
5
5
 
6
6
  const {
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import type { Snippet } from 'svelte';
5
5
  import type { TransitionConfig } from 'svelte/transition';
6
6
 
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLImgAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
 
5
5
  const {
6
6
  class: className = '',
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLInputAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
4
- import { applyCharacterFilter } from '../utilities/applyCharacterFilter.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
+ import { applyCharacterFilter } from '../utilities/inputField.js';
5
5
 
6
6
  let {
7
7
  type = 'text',
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLAnchorAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import type { Snippet } from 'svelte';
5
5
 
6
6
  let {
@@ -15,9 +15,6 @@
15
15
  } & HTMLAnchorAttributes = $props();
16
16
  </script>
17
17
 
18
- <a
19
- {...rest}
20
- class={mergeClasses(className, overrideDefaultStyling ? '' : 'fluid-link')}
21
- >
18
+ <a {...rest} class={mergeClasses(className, overrideDefaultStyling ? '' : 'fluid-link')}>
22
19
  {@render children()}</a
23
- >
20
+ >
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" generics="T">
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import type { Snippet } from 'svelte';
5
5
 
6
6
  const {
@@ -36,4 +36,4 @@
36
36
  {@render itemTemplate(item)}
37
37
  </li>
38
38
  {/each}
39
- </svelte:element>
39
+ </svelte:element>
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" generics="T,U,V">
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import type { Snippet } from 'svelte';
5
5
 
6
6
  const {
@@ -39,12 +39,11 @@
39
39
  } & HTMLAttributes<HTMLTableElement> = $props();
40
40
  </script>
41
41
 
42
- <table
43
- class={mergeClasses(className, overrideDefaultStyling ? '' : 'fluid-table')}
44
- {...rest}
45
- >
42
+ <table class={mergeClasses(className, overrideDefaultStyling ? '' : 'fluid-table')} {...rest}>
46
43
  {#if caption}
47
- <caption class={mergeClasses(captionClass, overrideDefaultStyling ? '' : 'fluid-table-caption')}>
44
+ <caption
45
+ class={mergeClasses(captionClass, overrideDefaultStyling ? '' : 'fluid-table-caption')}
46
+ >
48
47
  {caption}
49
48
  </caption>
50
49
  {/if}
@@ -77,4 +76,4 @@
77
76
  {/each}
78
77
  </tr>
79
78
  </tfoot>
80
- </table>
79
+ </table>
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import type { Snippet } from 'svelte';
5
5
 
6
6
  const {
@@ -1,18 +1,18 @@
1
1
  <script lang="ts">
2
2
  import { Container, Button } from '../base/index.js';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import { slide, type TransitionConfig } from 'svelte/transition';
5
5
  import type { Snippet } from 'svelte';
6
6
 
7
7
  const {
8
- variation = '',
8
+ variant = '',
9
9
  componentId,
10
10
  header,
11
11
  body,
12
12
  transitionFunction = slide,
13
13
  transitionDuration = 250
14
14
  }: {
15
- variation?: string;
15
+ variant?: string;
16
16
  componentId?: string;
17
17
  header: Snippet<[options: { isExpanded: boolean }]>;
18
18
  body: Snippet;
@@ -22,12 +22,12 @@
22
22
  const componentState = $state({ isExpanded: false });
23
23
  </script>
24
24
 
25
- <Container id={componentId} class={mergeClasses(variation, 'fluid-accordion-wrapper')}>
25
+ <Container id={componentId} class={mergeClasses(variant, 'fluid-accordion-wrapper')}>
26
26
  <Button
27
27
  onclick={async () => {
28
28
  componentState.isExpanded = !componentState.isExpanded;
29
29
  }}
30
- class={mergeClasses(variation, 'fluid-accordion-header')}
30
+ class={mergeClasses(variant, 'fluid-accordion-header')}
31
31
  overrideDefaultStyling
32
32
  >
33
33
  {@render header(componentState)}
@@ -36,7 +36,7 @@
36
36
  <Container
37
37
  transitionFn={transitionFunction}
38
38
  transitionParams={{ duration: transitionDuration }}
39
- class={mergeClasses(variation, 'fluid-accordion-body')}
39
+ class={mergeClasses(variant, 'fluid-accordion-body')}
40
40
  >
41
41
  {@render body()}
42
42
  </Container>
@@ -1,7 +1,7 @@
1
1
  import { type TransitionConfig } from 'svelte/transition';
2
2
  import type { Snippet } from 'svelte';
3
3
  type $$ComponentProps = {
4
- variation?: string;
4
+ variant?: string;
5
5
  componentId?: string;
6
6
  header: Snippet<[options: {
7
7
  isExpanded: boolean;
@@ -5,7 +5,7 @@
5
5
  generateCalendarCellStyles,
6
6
  generateDaysOfTheMonthFromDate
7
7
  } from '../utilities/calendar.js';
8
- import { mergeClasses } from '../utilities/mergeClasses.js';
8
+ import { mergeClasses } from '../utilities/common.js';
9
9
 
10
10
  let {
11
11
  variant = '',
@@ -1,13 +1,21 @@
1
1
  <script lang="ts" generics="T">
2
2
  import { Container } from '../base/index.js';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
4
- import { scrollToIndex, getSwipeDirection } from '../utilities/carousel.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
+ import {
5
+ scrollToIndex,
6
+ handleTouchStart,
7
+ handleTouchMove,
8
+ handleTouchEnd,
9
+ type CarouselInternalState
10
+ } from '../utilities/carousel.js';
5
11
  import type { Snippet } from 'svelte';
6
12
 
7
13
  let {
8
14
  componentId = crypto.randomUUID(),
9
15
  variant = '',
10
16
  orientation = 'horizontal',
17
+ snapItems = true,
18
+ swipeable = true,
11
19
  activeIndex = $bindable(0),
12
20
  autoplay = false,
13
21
  autoplayDuration = 1000,
@@ -17,68 +25,20 @@
17
25
  componentId?: string;
18
26
  variant?: string;
19
27
  orientation?: 'horizontal' | 'vertical';
28
+ snapItems?: boolean;
29
+ swipeable?: boolean;
20
30
  activeIndex?: number;
21
31
  autoplay?: boolean;
22
32
  autoplayDuration?: number;
23
33
  items: Array<T>;
24
- itemTemplate: Snippet<[{ item: T; index: number }]>;
34
+ itemTemplate: Snippet<[{ item: T; index: number; internalState: CarouselInternalState }]>;
25
35
  } = $props();
26
36
 
27
- let touchStartX = 0;
28
- let touchStartY = 0;
29
-
30
- function handleTouchStart(e: TouchEvent) {
31
- e.stopPropagation();
32
- e.preventDefault();
33
- touchStartX = e.changedTouches[0].screenX;
34
- touchStartY = e.changedTouches[0].screenY;
35
- }
36
-
37
- function handleTouchMove(e: TouchEvent) {
38
- if (!touchStartX || !touchStartY) return;
39
-
40
- const touchCurrentX = e.changedTouches[0].screenX;
41
- const touchCurrentY = e.changedTouches[0].screenY;
42
-
43
- const diffX = Math.abs(touchCurrentX - touchStartX);
44
- const diffY = Math.abs(touchCurrentY - touchStartY);
45
-
46
- // If horizontal carousel and horizontal swipe is dominant
47
- if (orientation === 'horizontal') {
48
- if (diffX > diffY && diffX > 5) {
49
- e.preventDefault();
50
- e.stopPropagation();
51
- }
52
- } else {
53
- // Vertical carousel
54
- if (diffY > diffX && diffY > 5) {
55
- e.preventDefault();
56
- e.stopPropagation();
57
- }
58
- }
59
- }
60
-
61
- function handleTouchEnd(e: TouchEvent) {
62
- e.stopPropagation();
63
- e.preventDefault();
64
- const touchEndX = e.changedTouches[0].screenX;
65
- const touchEndY = e.changedTouches[0].screenY;
66
-
67
- const direction = getSwipeDirection(
68
- touchStartX,
69
- touchStartY,
70
- touchEndX,
71
- touchEndY,
72
- 50,
73
- orientation
74
- );
75
-
76
- if (direction === 'next') {
77
- activeIndex = Math.min(activeIndex + 1, items.length - 1);
78
- } else if (direction === 'prev') {
79
- activeIndex = Math.max(activeIndex - 1, 0);
80
- }
81
- }
37
+ const internalState = $state({
38
+ touchStart: 0,
39
+ initialScroll: 0,
40
+ movementDelta: 0
41
+ });
82
42
 
83
43
  $effect(() => {
84
44
  if (autoplay && items.length > 0) {
@@ -98,17 +58,21 @@
98
58
 
99
59
  <Container
100
60
  id={componentId}
101
- ontouchstart={handleTouchStart}
102
- ontouchmove={handleTouchMove}
103
- ontouchend={handleTouchEnd}
61
+ ontouchstart={swipeable ? (e) => handleTouchStart(e, orientation, internalState) : undefined}
62
+ ontouchmove={swipeable ? (e) => handleTouchMove(e, orientation, internalState) : undefined}
63
+ ontouchend={swipeable
64
+ ? () => {
65
+ activeIndex = handleTouchEnd(snapItems, activeIndex, items.length, internalState);
66
+ }
67
+ : undefined}
104
68
  class={mergeClasses(
105
- `fluid-carousel-container ${orientation === 'vertical' ? 'h-full snap-y flex-col overflow-y-auto' : 'flex snap-x overflow-x-auto'}`,
69
+ `fluid-carousel-container ${swipeable ? 'touch-none' : ''} ${orientation === 'vertical' ? 'h-full flex-col overflow-y-auto' : 'flex overflow-x-auto'}`,
106
70
  variant
107
71
  )}
108
72
  >
109
73
  {#each items as item, index}
110
74
  <Container class={mergeClasses('fluid-carousel-item', variant)} overrideDefaultStyling>
111
- {@render itemTemplate({ item, index })}
75
+ {@render itemTemplate({ item, index, internalState })}
112
76
  </Container>
113
77
  {/each}
114
78
  </Container>
@@ -1,9 +1,12 @@
1
+ import { type CarouselInternalState } from '../utilities/carousel.js';
1
2
  import type { Snippet } from 'svelte';
2
3
  declare function $$render<T>(): {
3
4
  props: {
4
5
  componentId?: string;
5
6
  variant?: string;
6
7
  orientation?: "horizontal" | "vertical";
8
+ snapItems?: boolean;
9
+ swipeable?: boolean;
7
10
  activeIndex?: number;
8
11
  autoplay?: boolean;
9
12
  autoplayDuration?: number;
@@ -11,6 +14,7 @@ declare function $$render<T>(): {
11
14
  itemTemplate: Snippet<[{
12
15
  item: T;
13
16
  index: number;
17
+ internalState: CarouselInternalState;
14
18
  }]>;
15
19
  };
16
20
  exports: {};
@@ -1,29 +1,32 @@
1
1
  <script lang="ts">
2
2
  import Container from '../base/Container.svelte';
3
3
  import Text from '../base/Text.svelte';
4
+ import { mergeClasses } from '../utilities/common.js';
4
5
 
5
6
  const {
6
- variation,
7
+ variant = '',
8
+ componentId,
7
9
  code = '',
8
10
  language = '',
9
11
  showLineNumbers = true
10
12
  }: {
11
- variation?: string;
13
+ variant?: string;
14
+ componentId?: string;
12
15
  code?: string;
13
16
  language?: string;
14
17
  showLineNumbers?: boolean;
15
18
  } = $props();
16
19
  </script>
17
20
 
18
- <Container class="fluid-code-block-container">
21
+ <Container id={componentId} class={mergeClasses(variant, 'fluid-code-block-container')}>
19
22
  {#each code.split('\n') as line, index}
20
- <Container class="fluid-code-block-row">
23
+ <Container class={mergeClasses(variant, 'fluid-code-block-row')}>
21
24
  {#if showLineNumbers}
22
- <Container class="fluid-code-block-index"
23
- ><Text class="select-none">{index}</Text></Container
24
- >
25
+ <Container class={mergeClasses(variant, 'fluid-code-block-index')}>
26
+ <Text class="select-none">{index}</Text>
27
+ </Container>
25
28
  {/if}
26
- <Container class="fluid-code-block-content">
29
+ <Container class={mergeClasses(variant, 'fluid-code-block-content')}>
27
30
  <Text type="pre">
28
31
  <Text type="code" class={'language-' + language}>{line}</Text>
29
32
  </Text>
@@ -1,5 +1,6 @@
1
1
  type $$ComponentProps = {
2
- variation?: string;
2
+ variant?: string;
3
+ componentId?: string;
3
4
  code?: string;
4
5
  language?: string;
5
6
  showLineNumbers?: boolean;
@@ -1,11 +1,11 @@
1
1
  <script lang="ts">
2
2
  import { Container } from '../base/index.js';
3
- import { mergeClasses } from '../utilities/mergeClasses.js';
3
+ import { mergeClasses } from '../utilities/common.js';
4
4
  import { fade, fly, type TransitionConfig } from 'svelte/transition';
5
5
  import type { Snippet } from 'svelte';
6
6
 
7
7
  let {
8
- variation = '',
8
+ variant = '',
9
9
  componentId,
10
10
  isOpen = $bindable(false),
11
11
  position = 'left',
@@ -25,7 +25,7 @@
25
25
  position?: 'left' | 'right' | 'top' | 'bottom';
26
26
  closeOnBackdropClick?: boolean;
27
27
  scrollLock?: boolean;
28
- variation?: string;
28
+ variant?: string;
29
29
  componentId?: string;
30
30
  transitionFn?: (node: Element, params?: any) => TransitionConfig;
31
31
  transitionParams?: TransitionConfig & { x?: number; y?: number };
@@ -65,7 +65,7 @@
65
65
  {#if isOpen}
66
66
  <Container
67
67
  id={componentId}
68
- class={mergeClasses(variation, 'fluid-drawer-container')}
68
+ class={mergeClasses(variant, 'fluid-drawer-container')}
69
69
  transitionFn={backdropTransitionFn}
70
70
  transitionParams={backdropTransitionParams}
71
71
  onclick={async () => {
@@ -77,7 +77,7 @@
77
77
  role="dialog"
78
78
  aria-modal="true"
79
79
  onclick={(event) => event.stopPropagation()}
80
- class={mergeClasses(variation, `fluid-drawer-panel ${positionClasses[position]}`)}
80
+ class={mergeClasses(variant, `fluid-drawer-panel ${positionClasses[position]}`)}
81
81
  {transitionFn}
82
82
  {transitionParams}
83
83
  overrideDefaultStyling
@@ -5,7 +5,7 @@ type $$ComponentProps = {
5
5
  position?: 'left' | 'right' | 'top' | 'bottom';
6
6
  closeOnBackdropClick?: boolean;
7
7
  scrollLock?: boolean;
8
- variation?: string;
8
+ variant?: string;
9
9
  componentId?: string;
10
10
  transitionFn?: (node: Element, params?: any) => TransitionConfig;
11
11
  transitionParams?: TransitionConfig & {
@@ -21,6 +21,6 @@
21
21
  <meta name="description" content={description} />
22
22
  </svelte:head>
23
23
 
24
- <Container class="fluid-page" type="section">
24
+ <Container class="fluid-page" type="main" {...rest}>
25
25
  {@render children?.()}
26
26
  </Container>
@@ -1,2 +1,9 @@
1
+ export type CarouselInternalState = {
2
+ touchStart: number;
3
+ initialScroll: number;
4
+ movementDelta: number;
5
+ };
1
6
  export declare function scrollToIndex(componentId: string, activeIndex: number, totalItems: number, orientation?: 'horizontal' | 'vertical'): void;
2
- export declare function getSwipeDirection(touchStartX: number, touchStartY: number, touchEndX: number, touchEndY: number, threshold?: number, orientation?: 'horizontal' | 'vertical'): 'next' | 'prev' | null;
7
+ export declare function handleTouchStart(e: TouchEvent, orientation: 'horizontal' | 'vertical', internalState: CarouselInternalState): void;
8
+ export declare function handleTouchMove(e: TouchEvent, orientation: 'horizontal' | 'vertical', internalState: CarouselInternalState): void;
9
+ export declare function handleTouchEnd(snapItems: boolean, activeIndex: number, totalItems: number, internalState: CarouselInternalState): number;
@@ -10,18 +10,35 @@ export function scrollToIndex(componentId, activeIndex, totalItems, orientation
10
10
  top: orientation === 'vertical' ? targetPosition : 0
11
11
  });
12
12
  }
13
- export function getSwipeDirection(touchStartX, touchStartY, touchEndX, touchEndY, threshold = 50, orientation = 'horizontal') {
14
- const diffX = touchStartX - touchEndX;
15
- const diffY = touchStartY - touchEndY;
16
- if (orientation === 'horizontal') {
17
- if (Math.abs(diffX) > threshold) {
18
- return diffX > 0 ? 'next' : 'prev';
19
- }
13
+ export function handleTouchStart(e, orientation, internalState) {
14
+ e.stopPropagation();
15
+ const element = e.currentTarget;
16
+ internalState.touchStart =
17
+ orientation === 'vertical' ? e.touches[0].clientY : e.touches[0].clientX;
18
+ internalState.initialScroll = orientation === 'vertical' ? element.scrollTop : element.scrollLeft;
19
+ internalState.movementDelta = 0;
20
+ }
21
+ export function handleTouchMove(e, orientation, internalState) {
22
+ const element = e.currentTarget;
23
+ const currentTouch = orientation === 'vertical' ? e.touches[0].clientY : e.touches[0].clientX;
24
+ internalState.movementDelta = internalState.touchStart - currentTouch;
25
+ element.scrollTo({
26
+ left: orientation === 'vertical' ? 0 : internalState.initialScroll + internalState.movementDelta,
27
+ top: orientation === 'vertical' ? internalState.initialScroll + internalState.movementDelta : 0,
28
+ behavior: 'instant'
29
+ });
30
+ }
31
+ export function handleTouchEnd(snapItems, activeIndex, totalItems, internalState) {
32
+ if (!snapItems)
33
+ return activeIndex;
34
+ const threshold = 50;
35
+ let newIndex = activeIndex;
36
+ if (internalState.movementDelta > threshold && activeIndex < totalItems - 1) {
37
+ newIndex = activeIndex + 1;
20
38
  }
21
- else {
22
- if (Math.abs(diffY) > threshold) {
23
- return diffY > 0 ? 'next' : 'prev';
24
- }
39
+ else if (internalState.movementDelta < -threshold && activeIndex > 0) {
40
+ newIndex = activeIndex - 1;
25
41
  }
26
- return null;
42
+ internalState.movementDelta = 0;
43
+ return newIndex;
27
44
  }
@@ -10,6 +10,6 @@ export declare const codeBlockContents: {
10
10
  calendarSixMonth: string;
11
11
  calendarRange: string;
12
12
  calendarMulti: string;
13
- carouselSlide: string;
14
- carouselFade: string;
13
+ carouselInteractive: string;
14
+ carouselUsage: string;
15
15
  };
@@ -246,38 +246,30 @@ const calendarMulti = `<script>
246
246
  />
247
247
  </Container>
248
248
  </Container>`;
249
- const carouselSlide = `<script>
249
+ const carouselInteractive = `<script>
250
250
  import { Carousel } from 'fluid-ui-svelte/components';
251
- import { Image } from 'fluid-ui-svelte/base';
252
-
253
- const items = [
254
- { src: 'https://via.placeholder.com/800x400?text=Slide+1', alt: 'Slide 1' },
255
- { src: 'https://via.placeholder.com/800x400?text=Slide+2', alt: 'Slide 2' },
256
- { src: 'https://via.placeholder.com/800x400?text=Slide+3', alt: 'Slide 3' }
257
- ];
251
+ const items = [...];
258
252
  </script>
259
253
 
260
- <Carousel {items} type="slide" loop>
261
- {#snippet children(item)}
262
- <Image src={item.src} alt={item.alt} class="w-full h-64 object-cover" />
254
+ <Carousel {items} componentId="demo-id">
255
+ {#snippet itemTemplate({ item })}
256
+ <div class="h-64 flex items-center justify-center">
257
+ {item.text}
258
+ </div>
263
259
  {/snippet}
264
260
  </Carousel>`;
265
- const carouselFade = `<script>
261
+ const carouselUsage = `<script>
266
262
  import { Carousel } from 'fluid-ui-svelte/components';
267
- import { Text } from 'fluid-ui-svelte/base';
268
-
269
- const quotes = [
270
- { text: "Innovation is key.", author: "Tech CEO" },
271
- { text: "Design is intelligence made visible.", author: "Designer" },
272
- { text: "Simplicity is the ultimate sophistication.", author: "Da Vinci" }
273
- ];
263
+ const items = [...];
264
+ let activeIndex = $state(0);
274
265
  </script>
275
266
 
276
- <Carousel {items: quotes} type="fade" autoplay autoplayInterval={4000}>
277
- {#snippet children(quote)}
278
- <div class="h-64 flex flex-col items-center justify-center bg-neutral-100 dark:bg-neutral-800 p-8 text-center">
279
- <Text type="h3" class="text-2xl font-bold mb-4">"{quote.text}"</Text>
280
- <Text class="text-neutral-500">- {quote.author}</Text>
267
+ <Carousel {items} bind:activeIndex>
268
+ {#snippet itemTemplate({ item, index, internalState })}
269
+ <div class="h-64">
270
+ {item.name}
271
+ <!-- Delta available for custom animations -->
272
+ <span>Delta: {internalState.movementDelta}</span>
281
273
  </div>
282
274
  {/snippet}
283
275
  </Carousel>`;
@@ -293,6 +285,6 @@ export const codeBlockContents = {
293
285
  calendarSixMonth,
294
286
  calendarRange,
295
287
  calendarMulti,
296
- carouselSlide,
297
- carouselFade
288
+ carouselInteractive,
289
+ carouselUsage
298
290
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluid-ui-svelte",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "author": {
5
5
  "name": "Emre Ayaz",
6
6
  "email": "ayazthemre@gmail.com"
package/dist/app.css DELETED
@@ -1,284 +0,0 @@
1
- @import 'tailwindcss';
2
-
3
- @custom-variant dark (&:where(.dark, .dark *));
4
-
5
- @theme {
6
- --font-family-sans: 'Inter', sans-serif;
7
- --color-*: initial;
8
- --color-white: #fff;
9
- --color-black: #000;
10
-
11
- --color-neutral-50: #fafafa;
12
- --color-neutral-100: #f4f4f5;
13
- --color-neutral-200: #e4e4e7;
14
- --color-neutral-300: #dedee1;
15
- --color-neutral-400: #a1a1aa;
16
- --color-neutral-500: #71717a;
17
- --color-neutral-600: #52525b;
18
- --color-neutral-700: #3f3f46;
19
- --color-neutral-800: #27272a;
20
- --color-neutral-900: #18181b;
21
- --color-neutral-950: #09090b;
22
-
23
- --color-primary-50: #eff4ff;
24
- --color-primary-100: #dce6fd;
25
- --color-primary-200: #c0d4fd;
26
- --color-primary-300: #95bafb;
27
- --color-primary-400: #6295f8;
28
- --color-primary-500: #3e6ff3;
29
- --color-primary-600: #284fe8;
30
- --color-primary-700: #203bd5;
31
- --color-primary-800: #2032ad;
32
- --color-primary-900: #203088;
33
- --color-primary-950: #182053;
34
-
35
- --color-secondary-50: #f5f3ff;
36
- --color-secondary-100: #ede9fe;
37
- --color-secondary-200: #ddd6fe;
38
- --color-secondary-300: #c4b5fd;
39
- --color-secondary-400: #a78bfa;
40
- --color-secondary-500: #8b5cf6;
41
- --color-secondary-600: #7c3aed;
42
- --color-secondary-700: #6d28d9;
43
- --color-secondary-800: #5b21b6;
44
- --color-secondary-900: #4c1d95;
45
- --color-secondary-950: #2a1065;
46
-
47
- --color-tetriary-50: #f5f3ff;
48
- --color-tetriary-100: #ede9fe;
49
- --color-tetriary-200: #ddd6fe;
50
- --color-tetriary-300: #c4b5fd;
51
- --color-tetriary-400: #a78bfa;
52
- --color-tetriary-500: #8b5cf6;
53
- --color-tetriary-600: #7c3aed;
54
- --color-tetriary-700: #6d28d9;
55
- --color-tetriary-800: #5b21b6;
56
- --color-tetriary-900: #4c1d95;
57
- --color-tetriary-950: #2a1065;
58
-
59
- --color-success-50: #ecfdf5;
60
- --color-success-100: #d1fae5;
61
- --color-success-200: #a7f3d0;
62
- --color-success-300: #6ee7b7;
63
- --color-success-400: #34d399;
64
- --color-success-500: #10b981;
65
- --color-success-600: #059669;
66
- --color-success-700: #0f766e;
67
- --color-success-800: #065f46;
68
- --color-success-900: #064e3b;
69
- --color-success-950: #022c22;
70
-
71
- --color-warning-50: #fffbeb;
72
- --color-warning-100: #fef3c7;
73
- --color-warning-200: #fde68a;
74
- --color-warning-300: #fcd34d;
75
- --color-warning-400: #fbbf24;
76
- --color-warning-500: #f59e0b;
77
- --color-warning-600: #d97706;
78
- --color-warning-700: #b45309;
79
- --color-warning-800: #92400e;
80
- --color-warning-900: #78350f;
81
- --color-warning-950: #451a03;
82
-
83
- --color-info-50: #f0f9ff;
84
- --color-info-100: #e0f2fe;
85
- --color-info-200: #bae6fd;
86
- --color-info-300: #7dd3fc;
87
- --color-info-400: #38bdf8;
88
- --color-info-500: #0ea5e9;
89
- --color-info-600: #0284c7;
90
- --color-info-700: #0369a1;
91
- --color-info-800: #075985;
92
- --color-info-900: #0c4a6e;
93
- --color-info-950: #082f49;
94
-
95
- --color-error-50: #fef2f2;
96
- --color-error-100: #fee2e2;
97
- --color-error-200: #fecaca;
98
- --color-error-300: #fca5a5;
99
- --color-error-400: #f87171;
100
- --color-error-500: #ef4444;
101
- --color-error-600: #dc2626;
102
- --color-error-700: #b91c1c;
103
- --color-error-800: #991b1b;
104
- --color-error-900: #7f1d1d;
105
- --color-error-950: #450a0a;
106
- }
107
-
108
- /* ==========================================================================
109
- BASE LAYER STYLES
110
- Fundamental building blocks and semantic wrappers.
111
- ========================================================================== */
112
-
113
- /* Button -------------------------- */
114
- .fluid-button {
115
- @apply flex cursor-pointer items-center gap-1 rounded-md p-2 transition-all duration-500;
116
- }
117
- .fluid-button-primary {
118
- @apply bg-primary-500 text-neutral-50 hover:bg-primary-400;
119
- }
120
- .fluid-button-secondary {
121
- @apply bg-secondary-500 text-neutral-50 hover:bg-secondary-400;
122
- }
123
- .fluid-button-outline {
124
- @apply text-primary-500 outline-2 outline-primary-500 hover:bg-primary-500 hover:text-neutral-50;
125
- }
126
- .fluid-button-transparent {
127
- @apply text-primary-500 hover:text-primary-700 dark:hover:text-neutral-50;
128
- }
129
-
130
- /* Container ----------------------- */
131
- .fluid-container {
132
- @apply transition-all duration-500;
133
- }
134
-
135
- section,
136
- main.fluid-container {
137
- @apply min-w-0 bg-neutral-50 transition-all duration-500 dark:bg-neutral-900;
138
- }
139
-
140
- /* Image --------------------------- */
141
- .fluid-image {
142
- @apply object-contain;
143
- }
144
- .fluid-image-loading {
145
- @apply animate-pulse bg-primary-500;
146
- }
147
-
148
- /* Input Field --------------------- */
149
- .fluid-input-field {
150
- @apply rounded-md bg-neutral-50 p-1 outline-1 outline-primary-500 transition-all focus:outline-2 focus:outline-primary-500 dark:bg-neutral-800 dark:text-neutral-50;
151
- }
152
- .fluid-input-field-error {
153
- @apply outline-2 outline-error-500;
154
- }
155
-
156
- /* Link ---------------------------- */
157
- .fluid-link {
158
- @apply text-neutral-950 transition-all visited:text-primary-300 hover:text-neutral-500 dark:text-neutral-50 dark:hover:text-neutral-300;
159
- }
160
-
161
- /* List ---------------------------- */
162
- .fluid-unordered-list {
163
- @apply list-disc text-neutral-950 dark:text-neutral-50;
164
- }
165
- .fluid-ordered-list {
166
- @apply list-decimal text-neutral-950 dark:text-neutral-50;
167
- }
168
-
169
- /* Table --------------------------- */
170
- .fluid-table {
171
- @apply w-full border-separate border-spacing-0 overflow-hidden rounded-md border dark:border-neutral-300;
172
- }
173
- .fluid-table-head {
174
- @apply bg-neutral-200 dark:bg-neutral-800;
175
- }
176
- .fluid-table-row {
177
- @apply even:bg-neutral-200 dark:even:bg-neutral-800;
178
- }
179
- .fluid-table-cell {
180
- @apply border-collapse bg-clip-padding text-center;
181
- }
182
- .fluid-table-body {
183
- }
184
- .fluid-table-footer {
185
- @apply bg-clip-padding p-2 odd:bg-neutral-100 dark:odd:bg-neutral-800;
186
- }
187
-
188
- /* Text ---------------------------- */
189
- .fluid-text {
190
- @apply text-neutral-950 transition-all duration-500 dark:text-neutral-50;
191
- }
192
-
193
- /* ==========================================================================
194
- COMPONENT LAYER STYLES
195
- Complex UI elements composed from the Base Layer.
196
- ========================================================================== */
197
-
198
- /* Accordion ----------------------- */
199
- .fluid-accordion-wrapper {
200
- @apply flex-col;
201
- }
202
- .fluid-accordion-header {
203
- @apply flex w-full cursor-pointer flex-nowrap items-center justify-between rounded-md p-2 transition-all hover:bg-neutral-200 dark:text-neutral-50 dark:hover:bg-neutral-800;
204
- }
205
- .fluid-accordion-body {
206
- @apply flex w-full flex-col gap-1 p-2;
207
- }
208
-
209
- /* Calendar ------------------------ */
210
- .fluid-calendar {
211
- }
212
- .fluid-calendar-container {
213
- @apply flex flex-wrap;
214
- }
215
- .fluid-calendar-wrapper {
216
- @apply flex flex-col items-center gap-1 p-2;
217
- }
218
- .fluid-calendar-header {
219
- @apply flex w-full justify-center;
220
- }
221
- .fluid-calendar-body {
222
- @apply grid grid-cols-7 justify-items-center gap-4;
223
- }
224
- .fluid-calendar-cell {
225
- @apply dark:text-neutral-50;
226
- }
227
- .fluid-calendar-cell-selected {
228
- @apply bg-primary-600 text-neutral-50;
229
- }
230
- .fluid-calendar-cell-in-range {
231
- @apply bg-primary-400 text-neutral-50;
232
- }
233
- .fluid-calendar-cell-rolling-day {
234
- @apply opacity-25;
235
- }
236
-
237
- /* Carousel ------------------------ */
238
- .fluid-carousel-container {
239
- @apply flex snap-mandatory overflow-hidden scroll-smooth [scrollbar-width:none] [&::-webkit-scrollbar]:hidden;
240
- }
241
- .fluid-carousel-item {
242
- @apply size-full shrink-0 snap-center;
243
- }
244
-
245
- /* Code Block ---------------------- */
246
- .fluid-code-block-container {
247
- @apply flex flex-col overflow-scroll rounded-md bg-neutral-200 p-4 font-mono dark:bg-neutral-800;
248
- }
249
- .fluid-code-block-row {
250
- @apply flex items-center gap-1;
251
- }
252
- .fluid-code-block-index {
253
- @apply min-w-8 gap-1 border-r dark:border-neutral-50;
254
- }
255
- .fluid-code-block-content {
256
- @apply flex flex-col gap-1 px-2;
257
- }
258
-
259
- /* Drawer -------------------------- */
260
- .fluid-drawer-container {
261
- @apply fixed inset-0 z-10 bg-black/30 backdrop-blur-sm;
262
- }
263
- .fluid-drawer-panel {
264
- @apply fixed z-20 bg-white p-6 shadow-xl transition-all dark:bg-neutral-900;
265
- }
266
-
267
- /* Page ---------------------------- */
268
- .fluid-page {
269
- @apply flex w-full flex-1 flex-col p-8 md:p-16;
270
- }
271
-
272
- /* Switch -------------------------- */
273
- .fluid-switch-button {
274
- @apply relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent bg-neutral-200 transition-colors duration-200 ease-in-out focus:outline-none disabled:cursor-not-allowed disabled:opacity-50;
275
- }
276
- .fluid-switch-circle {
277
- @apply pointer-events-none inline-block h-4 w-4 translate-x-0 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out checked:translate-x-4;
278
- }
279
- .fluid-switch-button.checked {
280
- @apply bg-primary-600;
281
- }
282
- .fluid-switch-button.checked .fluid-switch-circle {
283
- @apply translate-x-4;
284
- }
File without changes