ui-svelte 0.2.2 → 0.2.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,31 +1,43 @@
1
1
  <script lang="ts">
2
2
  import { codeToHtml } from 'shiki';
3
3
  import { useClipboard } from '../hooks/use-clipboard.svelte.js';
4
- import { Button, IconButton } from '../index.js';
4
+ import { IconButton } from '../index.js';
5
5
  import { Checkmark24RegularIcon, Copy24RegularIcon } from '../icons/index.js';
6
+ import { theme } from '../stores/theme.svelte.js';
6
7
 
7
8
  type Props = {
8
9
  code: string;
9
- lang?: string;
10
- theme?: string;
11
- showCopy?: boolean;
10
+ lang: string;
11
+ lightTheme?: string;
12
+ darkTheme?: string;
13
+ disableCopy?: boolean;
14
+ hideLang?: boolean;
12
15
  };
13
16
 
14
- let { code, lang = 'html', theme = 'catppuccin-frappe', showCopy }: Props = $props();
17
+ let {
18
+ code,
19
+ lang,
20
+ lightTheme = 'catppuccin-latte',
21
+ darkTheme = 'catppuccin-frappe',
22
+ disableCopy,
23
+ hideLang
24
+ }: Props = $props();
15
25
 
16
26
  let html: string = $state('');
17
27
  let open = $state(false);
28
+ let hover = $state(false);
18
29
 
19
- const generateCode = async (value: string) => {
30
+ const generateCode = async (value: string, currentTheme: string) => {
20
31
  html = await codeToHtml(value, {
21
32
  lang,
22
- theme
33
+ theme: currentTheme
23
34
  });
24
35
  open = true;
25
36
  };
26
37
 
27
38
  $effect(() => {
28
- generateCode(code);
39
+ const currentTheme = theme.isDark ? darkTheme : lightTheme;
40
+ generateCode(code, currentTheme);
29
41
  });
30
42
 
31
43
  const clipboard = useClipboard();
@@ -36,13 +48,18 @@
36
48
  </script>
37
49
 
38
50
  <!-- svelte-ignore a11y_no_static_element_interactions -->
39
- <div class="code">
51
+ <div class="code" onmouseenter={() => (hover = true)} onmouseleave={() => (hover = false)}>
40
52
  {#if open}
41
- {#if showCopy}
53
+ {#if !hover && !hideLang}
54
+ <div class="code-info">
55
+ <div class="code-lang">{lang}</div>
56
+ </div>
57
+ {/if}
58
+ {#if hover && !disableCopy}
42
59
  <div class="code-info">
43
60
  <IconButton
44
61
  onclick={handleCopy}
45
- variant="primary"
62
+ variant="ghost"
46
63
  size="sm"
47
64
  icon={clipboard.copied ? Checkmark24RegularIcon : Copy24RegularIcon}
48
65
  />
@@ -1,8 +1,10 @@
1
1
  type Props = {
2
2
  code: string;
3
- lang?: string;
4
- theme?: string;
5
- showCopy?: boolean;
3
+ lang: string;
4
+ lightTheme?: string;
5
+ darkTheme?: string;
6
+ disableCopy?: boolean;
7
+ hideLang?: boolean;
6
8
  };
7
9
  declare const Code: import("svelte").Component<Props, {}, "">;
8
10
  type Code = ReturnType<typeof Code>;
@@ -4,14 +4,20 @@
4
4
  tab-size: 4;
5
5
  -moz-tab-size: 4;
6
6
  }
7
+
7
8
  .code-content {
8
9
  @apply size-full overflow-auto rounded-md;
9
10
  background-color: inherit;
10
11
  }
11
12
 
12
13
  .code-info {
13
- @apply absolute top-2 right-2 flex justify-end items-center gap-2;
14
+ @apply absolute top-2 right-2 flex justify-end items-center gap-2 z-10;
15
+ }
16
+
17
+ .code-lang {
18
+ @apply text-sm font-medium text-on-muted;
14
19
  }
20
+
15
21
  .shiki {
16
22
  @apply p-3 rounded-ui;
17
23
  min-width: fit-content;
@@ -1,7 +1,12 @@
1
1
  <script lang="ts">
2
2
  import type { SearchState, SearchOption } from '../hooks/use-search.svelte.js';
3
- import { Avatar, Icon, Item } from '../index.js';
4
- import type { IconName } from '../types.js';
3
+ import {
4
+ ArrowDown24RegularIcon,
5
+ Dismiss24RegularIcon,
6
+ DotsMoveIcon,
7
+ Search24RegularIcon
8
+ } from '../icons/index.js';
9
+ import { Avatar, Icon, Item, type IconData } from '../index.js';
5
10
  import { cn } from '../utils/class-names.js';
6
11
  import { onMount, tick } from 'svelte';
7
12
 
@@ -27,7 +32,7 @@
27
32
  isSolid?: boolean;
28
33
  isClearable?: boolean;
29
34
  isDisabled?: boolean;
30
- arrowIcon?: IconName;
35
+ arrowIcon?: IconData;
31
36
  };
32
37
 
33
38
  let {
@@ -52,7 +57,7 @@
52
57
  isSolid,
53
58
  isClearable = false,
54
59
  isDisabled = false,
55
- arrowIcon = 'fluent:arrow-sort-down-24-regular'
60
+ arrowIcon = ArrowDown24RegularIcon
56
61
  }: Props = $props();
57
62
 
58
63
  const variantClasses = {
@@ -356,13 +361,8 @@
356
361
  </span>
357
362
  {/if}
358
363
 
359
- {#if selected?.src || selected?.icon}
360
- <Avatar
361
- src={selected.src}
362
- name={selected.label}
363
- icon={selected.icon as IconName}
364
- size={avatarSizes[size]}
365
- />
364
+ {#if selected?.src}
365
+ <Avatar src={selected.src} name={selected.label} size={avatarSizes[size]} />
366
366
  {/if}
367
367
 
368
368
  <div class="control-selected">
@@ -386,10 +386,10 @@
386
386
  onclick={handleClear}
387
387
  aria-label="Clear selection"
388
388
  >
389
- <Icon name="fluent:dismiss-16-regular" />
389
+ <Icon icon={Dismiss24RegularIcon} />
390
390
  </button>
391
391
  {/if}
392
- <Icon name={arrowIcon} class={cn('control-arrow', isOpen && 'is-active')} />
392
+ <Icon icon={arrowIcon} class={cn('control-arrow', isOpen && 'is-active')} />
393
393
  </div>
394
394
  </button>
395
395
 
@@ -399,7 +399,7 @@
399
399
 
400
400
  <div class:is-active={isOpen} class="combo-box-popover" bind:this={contentEl} {style}>
401
401
  <div class={cn('combo-box-search', variantClasses[variant])}>
402
- <Icon name="fluent:search-24-regular" class="combo-box-search-icon" />
402
+ <Icon icon={Search24RegularIcon} class="combo-box-search-icon" />
403
403
  <input
404
404
  type="text"
405
405
  class="combo-box-search-input"
@@ -410,7 +410,7 @@
410
410
 
411
411
  {#if search.isLoading}
412
412
  <div class="combo-box-loading">
413
- <Icon name="fluent:spinner-ios-20-regular" class="combo-box-loading-spinner" />
413
+ <Icon icon={DotsMoveIcon} class="combo-box-loading-spinner" />
414
414
  <span>{loadingText}</span>
415
415
  </div>
416
416
  {:else if search.options.length === 0 && hasSearched}
@@ -421,7 +421,7 @@
421
421
  <li>
422
422
  <Item
423
423
  label={item.label}
424
- icon={item.icon as IconName}
424
+ icon={item.icon as IconData}
425
425
  src={item.src}
426
426
  description={item.description}
427
427
  id={item.id}
@@ -438,7 +438,7 @@
438
438
 
439
439
  {#if search.isLoadingMore}
440
440
  <li class="combo-box-loading-more">
441
- <Icon name="fluent:spinner-ios-20-regular" class="combo-box-loading-spinner" />
441
+ <Icon icon={DotsMoveIcon} class="combo-box-loading-spinner" />
442
442
  <span>{loadingMoreText}</span>
443
443
  </li>
444
444
  {/if}
@@ -1,5 +1,5 @@
1
1
  import type { SearchState, SearchOption } from '../hooks/use-search.svelte.js';
2
- import type { IconName } from '../types.js';
2
+ import { type IconData } from '../index.js';
3
3
  type Props = {
4
4
  search: SearchState;
5
5
  value?: string | number | null;
@@ -22,7 +22,7 @@ type Props = {
22
22
  isSolid?: boolean;
23
23
  isClearable?: boolean;
24
24
  isDisabled?: boolean;
25
- arrowIcon?: IconName;
25
+ arrowIcon?: IconData;
26
26
  };
27
27
  declare const ComboBox: import("svelte").Component<Props, {}, "value" | "selected">;
28
28
  type ComboBox = ReturnType<typeof ComboBox>;
@@ -1,8 +1,9 @@
1
+ import type { IconData } from '../types.svelte.js';
1
2
  export interface SearchOption {
2
3
  id: string | number;
3
4
  label: string;
4
5
  description?: string;
5
- icon?: string;
6
+ icon?: IconData;
6
7
  src?: string;
7
8
  disabled?: boolean;
8
9
  [key: string]: unknown;
package/dist/index.css CHANGED
@@ -51,12 +51,13 @@
51
51
  @import './layout/css/app-bar.css';
52
52
  @import './layout/css/bottom-bar.css';
53
53
  @import './layout/css/footer.css';
54
- @import './layout/css/footer-links.css';
55
54
  @import './layout/css/scaffold.css';
56
55
  @import './layout/css/sidebar.css';
57
56
 
58
57
  @import './navigation/css/bottom-nav.css';
59
58
  @import './navigation/css/nav-menu.css';
59
+ @import './navigation/css/footer-nav.css';
60
+ @import './navigation/css/footer-group.css';
60
61
  @import './navigation/css/side-nav.css';
61
62
  @import './navigation/css/tabs.css';
62
63
 
package/dist/index.d.ts CHANGED
@@ -45,11 +45,12 @@ import Toggle from './form/Toggle.svelte';
45
45
  import AppBar from './layout/AppBar.svelte';
46
46
  import Provider from './layout/Provider.svelte';
47
47
  import Footer from './layout/Footer.svelte';
48
- import FooterLinks from './layout/FooterLinks.svelte';
49
48
  import Scaffold from './layout/Scaffold.svelte';
50
49
  import Sidebar from './layout/Sidebar.svelte';
51
50
  import NavMenu from './navigation/NavMenu.svelte';
52
51
  import BottomNav from './navigation/BottomNav.svelte';
52
+ import FooterNav from './navigation/FooterNav.svelte';
53
+ import FooterGroup from './navigation/FooterGroup.svelte';
53
54
  import SideNav, { type SideNavItem, type SideNavSubItem } from './navigation/SideNav.svelte';
54
55
  import Tabs from './navigation/Tabs.svelte';
55
56
  import AlertDialog from './overlay/AlertDialog.svelte';
@@ -73,5 +74,5 @@ import { useAuth } from './hooks/use-auth.svelte.js';
73
74
  import { theme } from './stores/theme.svelte.js';
74
75
  import { useSearch } from './hooks/use-search.svelte.js';
75
76
  import { useChat } from './hooks/use-chat.svelte.js';
76
- export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterLinks, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
77
+ export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterNav, FooterGroup, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
77
78
  export type { IconData, SideNavItem, SideNavSubItem };
package/dist/index.js CHANGED
@@ -45,11 +45,12 @@ import Toggle from './form/Toggle.svelte';
45
45
  import AppBar from './layout/AppBar.svelte';
46
46
  import Provider from './layout/Provider.svelte';
47
47
  import Footer from './layout/Footer.svelte';
48
- import FooterLinks from './layout/FooterLinks.svelte';
49
48
  import Scaffold from './layout/Scaffold.svelte';
50
49
  import Sidebar from './layout/Sidebar.svelte';
51
50
  import NavMenu from './navigation/NavMenu.svelte';
52
51
  import BottomNav from './navigation/BottomNav.svelte';
52
+ import FooterNav from './navigation/FooterNav.svelte';
53
+ import FooterGroup from './navigation/FooterGroup.svelte';
53
54
  import SideNav, {} from './navigation/SideNav.svelte';
54
55
  import Tabs from './navigation/Tabs.svelte';
55
56
  import AlertDialog from './overlay/AlertDialog.svelte';
@@ -73,4 +74,4 @@ import { useAuth } from './hooks/use-auth.svelte.js';
73
74
  import { theme } from './stores/theme.svelte.js';
74
75
  import { useSearch } from './hooks/use-search.svelte.js';
75
76
  import { useChat } from './hooks/use-chat.svelte.js';
76
- export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterLinks, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
77
+ export { AreaChart, ArcChart, BarChart, Candlestick, LineChart, PieChart, Alert, AlertDialog, AppBar, Accordion, Avatar, Audio, Badge, Button, BottomNav, Carousel, Card, ChatBox, Checkbox, Chip, Code, Collapsible, Command, ComboBox, CsvField, DateField, Drawer, Dropzone, Divider, Dropdown, Empty, Footer, FooterNav, FooterGroup, formatCurrency, formatDate, formatNumber, getWeekdays, i18n, Icon, IconButton, ImageCropper, Item, initLanguage, Modal, Marquee, NavMenu, PasswordField, PhoneField, PinField, plural, PopoverStack, Provider, RadioGroup, Record, Scaffold, Section, Select, setLanguage, Sidebar, SideNav, Slider, t, Table, Tabs, TextField, Textarea, theme, Toast, toast, Toggle, ToggleTheme, Tooltip, useAuth, useChat, useClipboard, useFetch, useForm, useLocalStorage, useScroll, useSearch, useTable, useWebSocket, Video };
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import { cn } from '../utils/class-names.js';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ type FooterLink = {
6
+ label: string;
7
+ href: string;
8
+ external?: boolean;
9
+ };
10
+
11
+ type Props = {
12
+ title?: string;
13
+ links?: FooterLink[];
14
+ children?: Snippet;
15
+ class?: string;
16
+ };
17
+
18
+ const { title, links = [], children, class: className }: Props = $props();
19
+ </script>
20
+
21
+ <div class={cn('footer-group', className)}>
22
+ {#if title}
23
+ <h3 class="footer-group-title">{title}</h3>
24
+ {/if}
25
+
26
+ {#if links.length > 0}
27
+ <ul class="footer-group-links">
28
+ {#each links as link}
29
+ <li>
30
+ <a
31
+ href={link.href}
32
+ class="footer-group-link"
33
+ target={link.external ? '_blank' : undefined}
34
+ rel={link.external ? 'noopener noreferrer' : undefined}
35
+ >
36
+ {link.label}
37
+ {#if link.external}
38
+ <span class="sr-only">(abre en nueva ventana)</span>
39
+ {/if}
40
+ </a>
41
+ </li>
42
+ {/each}
43
+ </ul>
44
+ {/if}
45
+
46
+ {#if children}
47
+ <div class="footer-group-content">
48
+ {@render children()}
49
+ </div>
50
+ {/if}
51
+ </div>
@@ -0,0 +1,15 @@
1
+ import type { Snippet } from 'svelte';
2
+ type FooterLink = {
3
+ label: string;
4
+ href: string;
5
+ external?: boolean;
6
+ };
7
+ type Props = {
8
+ title?: string;
9
+ links?: FooterLink[];
10
+ children?: Snippet;
11
+ class?: string;
12
+ };
13
+ declare const FooterGroup: import("svelte").Component<Props, {}, "">;
14
+ type FooterGroup = ReturnType<typeof FooterGroup>;
15
+ export default FooterGroup;
@@ -19,9 +19,9 @@
19
19
  }
20
20
  </script>
21
21
 
22
- <div class={cn('footer-links', className)}>
22
+ <div class={cn('footer-nav', className)}>
23
23
  {#each links as link}
24
- <a href={link.href} class={cn('footer-link', isLinkActive(link.href) && 'is-active')}>
24
+ <a href={link.href} class={cn('footer-nav-link', isLinkActive(link.href) && 'is-active')}>
25
25
  {link.label}
26
26
  </a>
27
27
  {/each}
@@ -0,0 +1,11 @@
1
+ type FooterLink = {
2
+ label: string;
3
+ href: string;
4
+ };
5
+ type Props = {
6
+ links: FooterLink[];
7
+ class?: string;
8
+ };
9
+ declare const FooterNav: import("svelte").Component<Props, {}, "">;
10
+ type FooterNav = ReturnType<typeof FooterNav>;
11
+ export default FooterNav;
@@ -0,0 +1,27 @@
1
+ @layer components {
2
+ .footer-group {
3
+ @apply flex flex-col gap-4;
4
+
5
+ .footer-group-title {
6
+ @apply text-base font-semibold;
7
+ @apply mb-2;
8
+ }
9
+
10
+ .footer-group-links {
11
+ @apply flex flex-col gap-2;
12
+ @apply list-none p-0 m-0;
13
+
14
+ .footer-group-link {
15
+ @apply text-sm text-on-muted;
16
+ @apply transition-colors duration-200;
17
+ @apply hover:underline;
18
+ @apply focus:outline-none;
19
+ @apply inline-flex items-center gap-1;
20
+ }
21
+ }
22
+
23
+ .footer-group-content {
24
+ @apply flex flex-col gap-3;
25
+ }
26
+ }
27
+ }
@@ -1,11 +1,11 @@
1
1
  @layer components {
2
- .footer-links {
2
+ .footer-nav {
3
3
  @apply column md:row items-start md:items-center gap-3 md:gap-6;
4
4
 
5
- .footer-link {
5
+ .footer-nav-link {
6
6
  @apply text-sm opacity-70;
7
7
  @apply transition-all duration-200;
8
- @apply hover:opacity-100;
8
+ @apply hover:underline;
9
9
  @apply focus:outline-none;
10
10
  @apply cursor-pointer select-none;
11
11
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ui-svelte",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "author": {
5
5
  "name": "SappsDev",
6
6
  "email": "info@sappsdev.com"
@@ -1,11 +0,0 @@
1
- type FooterLink = {
2
- label: string;
3
- href: string;
4
- };
5
- type Props = {
6
- links: FooterLink[];
7
- class?: string;
8
- };
9
- declare const FooterLinks: import("svelte").Component<Props, {}, "">;
10
- type FooterLinks = ReturnType<typeof FooterLinks>;
11
- export default FooterLinks;