negodesign 0.0.69 → 0.0.70

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.
@@ -0,0 +1,109 @@
1
+ <script lang="ts">
2
+ import type { CtaCardImageBannerProps } from "./types";
3
+
4
+ let {
5
+ title,
6
+ description,
7
+ primaryText,
8
+ secondaryText,
9
+ primaryHref,
10
+ secondaryHref,
11
+ onClickPrimary,
12
+ onClickSecondary,
13
+ imageSrc = "https://tailwindcss.com/plus-assets/img/component-images/dark-project-app-screenshot.png",
14
+ imageAlt = "Imagem de destaque",
15
+ imageWidth = 1824,
16
+ imageHeight = 1080,
17
+ class: className = "",
18
+ imageContainerClass = "",
19
+ }: CtaCardImageBannerProps = $props();
20
+ </script>
21
+
22
+ <div class="bg-white">
23
+ <div class="mx-auto max-w-7xl py-24 sm:px-6 sm:py-32 lg:px-8">
24
+ <div
25
+ class="relative isolate overflow-hidden bg-gradient px-6 pt-16 shadow-2xl sm:rounded-3xl sm:px-16 md:pt-24 lg:flex lg:gap-x-20 lg:px-24 lg:pt-0 {className}"
26
+ >
27
+ <svg
28
+ viewBox="0 0 1024 1024"
29
+ aria-hidden="true"
30
+ class="absolute top-1/2 left-1/2 -z-10 size-256 -translate-y-1/2 mask-[radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0"
31
+ >
32
+ <circle
33
+ r="512"
34
+ cx="512"
35
+ cy="512"
36
+ fill="url(#759c1415-0410-454c-8f7c-9a820de03641)"
37
+ fill-opacity="0.7"
38
+ />
39
+ <defs>
40
+ <radialGradient id="759c1415-0410-454c-8f7c-9a820de03641">
41
+ <stop stop-color="#7775D6" />
42
+ <stop offset="1" stop-color="#E935C1" />
43
+ </radialGradient>
44
+ </defs>
45
+ </svg>
46
+
47
+ {#snippet pill(
48
+ label: string,
49
+ href: string | undefined,
50
+ onClick: (() => void) | undefined,
51
+ style: "primary" | "secondary",
52
+ )}
53
+ {#if href}
54
+ <a
55
+ {href}
56
+ class={style === "primary"
57
+ ? "rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-xs hover:bg-gray-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
58
+ : "text-sm/6 font-semibold text-white hover:text-gray-100"}
59
+ >
60
+ {label}
61
+ {#if style === "secondary"}<span aria-hidden="true">→</span>{/if}
62
+ </a>
63
+ {:else}
64
+ <button
65
+ type="button"
66
+ onclick={() => onClick?.()}
67
+ class={style === "primary"
68
+ ? "rounded-md bg-white px-3.5 py-2.5 text-sm font-semibold text-gray-900 shadow-xs hover:bg-gray-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white"
69
+ : "text-sm/6 font-semibold text-white hover:text-gray-100"}
70
+ >
71
+ {label}
72
+ {#if style === "secondary"}<span aria-hidden="true">→</span>{/if}
73
+ </button>
74
+ {/if}
75
+ {/snippet}
76
+
77
+ <div
78
+ class="mx-auto max-w-md text-center lg:mx-0 lg:flex-auto lg:py-32 lg:text-left"
79
+ >
80
+ <h2
81
+ class="text-3xl font-semibold tracking-tight text-balance text-white sm:text-4xl"
82
+ >
83
+ {title}
84
+ </h2>
85
+ {#if description}
86
+ <p class="mt-6 text-lg/8 text-pretty text-gray-300">{description}</p>
87
+ {/if}
88
+ <div
89
+ class="mt-10 flex items-center justify-center gap-x-6 lg:justify-start"
90
+ >
91
+ {@render pill(primaryText, primaryHref, onClickPrimary, "primary")}
92
+ {#if secondaryText}
93
+ {@render pill(secondaryText, secondaryHref, onClickSecondary, "secondary")}
94
+ {/if}
95
+ </div>
96
+ </div>
97
+ <div class="relative mt-16 h-80 lg:mt-8 {imageContainerClass}">
98
+ <img
99
+ src={imageSrc}
100
+ alt={imageAlt}
101
+ width={imageWidth}
102
+ height={imageHeight}
103
+ loading="lazy"
104
+ class="absolute top-0 left-0 w-228 max-w-none rounded-md bg-white/5 ring-1 ring-white/10"
105
+ />
106
+ </div>
107
+ </div>
108
+ </div>
109
+ </div>
@@ -0,0 +1,4 @@
1
+ import type { CtaCardImageBannerProps } from "./types";
2
+ declare const CtaCardImageBanner: import("svelte").Component<CtaCardImageBannerProps, {}, "">;
3
+ type CtaCardImageBanner = ReturnType<typeof CtaCardImageBanner>;
4
+ export default CtaCardImageBanner;
@@ -71,3 +71,40 @@ export type CtaCardBannerProps = {
71
71
  color: string;
72
72
  }>;
73
73
  };
74
+ /**
75
+ * CTA banner com imagem de destaque em fundo gradiente.
76
+ * Título, descrição e até dois CTAs (primário e secundário), cada um com
77
+ * texto, href e/ou callback de clique, além da imagem e seus atributos.
78
+ * Usa `bg-gradient` como fundo padrão (customizável via `containerClass`).
79
+ * @component
80
+ */
81
+ export type CtaCardImageBannerProps = {
82
+ /** Título principal do banner. */
83
+ title: string;
84
+ /** Texto de apoio / descrição. */
85
+ description?: string;
86
+ /** Texto do CTA primário. */
87
+ primaryText: string;
88
+ /** href do CTA primário (link). */
89
+ primaryHref?: string;
90
+ /** Chamado ao clicar no CTA primário. */
91
+ onClickPrimary?: () => void;
92
+ /** Texto do CTA secundário. */
93
+ secondaryText?: string;
94
+ /** href do CTA secundário (link). */
95
+ secondaryHref?: string;
96
+ /** Chamado ao clicar no CTA secundário. */
97
+ onClickSecondary?: () => void;
98
+ /** URL da imagem de destaque. */
99
+ imageSrc?: string;
100
+ /** Texto alternativo da imagem. */
101
+ imageAlt?: string;
102
+ /** Largura da imagem (atributo width). */
103
+ imageWidth?: number;
104
+ /** Altura da imagem (atributo height). */
105
+ imageHeight?: number;
106
+ /** Classe CSS adicional para o artigo (fundo). */
107
+ class?: string;
108
+ /** Classe CSS do container da imagem. */
109
+ imageContainerClass?: string;
110
+ };
@@ -10,11 +10,13 @@ export type NavigationMenuItemProps = {
10
10
  label: string;
11
11
  href?: string;
12
12
  textClass?: string;
13
+ hoverClass?: string;
13
14
  };
14
15
  export type NavigationMenuItemCardProps = {
15
16
  label?: string;
16
17
  textClass?: string;
17
18
  subTextClass?: string;
19
+ hoverClass?: string;
18
20
  header?: {
19
21
  label: string;
20
22
  description: string;
@@ -28,18 +30,21 @@ export type NavigationMenuItemCardProps = {
28
30
  export type NavigationMenuItemGridProps = {
29
31
  label: string;
30
32
  textClass?: string;
33
+ hoverClass?: string;
31
34
  subTextClass?: string;
32
35
  grids?: ListItemProps[];
33
36
  };
34
37
  export type NavigationMenuItemListProps = {
35
38
  label: string;
36
39
  textClass?: string;
40
+ hoverClass?: string;
37
41
  subTextClass?: string;
38
42
  list?: ListItemProps[];
39
43
  };
40
44
  export type NavigationMenuItemsProps = {
41
45
  label: string;
42
46
  textClass?: string;
47
+ hoverClass?: string;
43
48
  items?: {
44
49
  title: string;
45
50
  href: string;
@@ -49,6 +54,7 @@ export type ComplexMenuProps = IMenuProps & {
49
54
  menus: (NavigationMenuItemProps | NavigationMenuItemListProps | NavigationMenuItemCardProps | NavigationMenuItemGridProps | NavigationMenuItemsProps)[];
50
55
  textClass?: string;
51
56
  subTextClass?: string;
57
+ hoverClass?: string;
52
58
  };
53
59
  export type MenuVarientProps = ComplexMenuProps | SimpleMenuProps;
54
60
  export type MenuProps = IMenuProps & {
@@ -13,23 +13,39 @@
13
13
  import NavigationMenuItemList from "./shared/navigation/NavigationMenuItemList.svelte";
14
14
  import NavigationMenuItems from "./shared/navigation/NavigationMenuItems.svelte";
15
15
 
16
- let { menus: links, textClass, subTextClass }: ComplexMenuProps = $props();
16
+ let { menus, textClass, subTextClass, hoverClass }: ComplexMenuProps =
17
+ $props();
17
18
  </script>
18
19
 
19
20
  <ul
20
21
  class="flex list-none flex-1 flex-wrap items-center justify-center {textClass}"
21
22
  >
22
- {#each links as link, i (i)}
23
+ {#each menus as link, i (i)}
23
24
  {#if isCard(link)}
24
- <NavigationMenuItemCard {...link} {textClass} {subTextClass} />
25
+ <NavigationMenuItemCard
26
+ {...link}
27
+ {textClass}
28
+ {subTextClass}
29
+ {hoverClass}
30
+ />
25
31
  {:else if isGrid(link)}
26
- <NavigationMenuItemGrid {...link} {textClass} {subTextClass} />
32
+ <NavigationMenuItemGrid
33
+ {...link}
34
+ {textClass}
35
+ {subTextClass}
36
+ {hoverClass}
37
+ />
27
38
  {:else if isList(link)}
28
- <NavigationMenuItemList {...link} {textClass} {subTextClass} />
39
+ <NavigationMenuItemList
40
+ {...link}
41
+ {textClass}
42
+ {subTextClass}
43
+ {hoverClass}
44
+ />
29
45
  {:else if isItems(link)}
30
- <NavigationMenuItems {...link} {textClass} />
46
+ <NavigationMenuItems {...link} {textClass} {hoverClass} />
31
47
  {:else if isItem(link)}
32
- <NavigationMenuItem {...link} {textClass} />
48
+ <NavigationMenuItem {...link} {textClass} {hoverClass} />
33
49
  {/if}
34
50
  {/each}
35
51
  </ul>
@@ -6,11 +6,15 @@
6
6
  let {
7
7
  label,
8
8
  className = "",
9
+ hoverClass = "",
10
+ onClick,
9
11
  children,
10
12
  }: {
11
13
  label: string;
12
14
  className?: string;
13
- children: Snippet;
15
+ hoverClass?: string;
16
+ children?: Snippet;
17
+ onClick?: () => void;
14
18
  } = $props();
15
19
 
16
20
  let open = $state(false);
@@ -50,25 +54,30 @@
50
54
  type="button"
51
55
  aria-expanded={open}
52
56
  onclick={() => {
53
- clearTimeout(closeTimer);
54
- open = !open;
57
+ if (children) {
58
+ clearTimeout(closeTimer);
59
+ open = !open;
60
+ }
61
+ if (onClick) onClick();
55
62
  }}
56
- class="inline-flex h-9 w-max items-center justify-center rounded-2xl px-4.5 py-2.5 text-sm font-medium transition-all outline-none select-none hover:bg-muted focus:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 {open
57
- ? 'bg-muted'
63
+ class="inline-flex h-9 w-max items-center justify-center rounded-2xl px-4.5 py-2.5 text-sm font-medium transition-all outline-none select-none hover:{hoverClass} focus:{hoverClass} focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 {open
64
+ ? hoverClass
58
65
  : ''}"
59
66
  >
60
67
  {label}
61
- <HugeiconsIcon
62
- icon={ArrowDown01Icon}
63
- strokeWidth={2}
64
- class={`relative top-px ml-1 size-3 transition-transform duration-300 ${
65
- open ? "rotate-180" : ""
66
- }`}
67
- aria-hidden="true"
68
- />
68
+ {#if children}
69
+ <HugeiconsIcon
70
+ icon={ArrowDown01Icon}
71
+ strokeWidth={2}
72
+ class={`relative top-px ml-1 size-3 transition-transform duration-300 ${
73
+ open ? "rotate-180" : ""
74
+ }`}
75
+ aria-hidden="true"
76
+ />
77
+ {/if}
69
78
  </button>
70
79
 
71
- {#if open}
80
+ {#if open && children}
72
81
  <div
73
82
  class="absolute left-0 top-full z-50 md:z-100 mt-1.5 w-max rounded-2xl bg-popover p-2.5 pr-3 overflow-hidden text-popover-foreground shadow-2xl ring-1 ring-foreground/5"
74
83
  >
@@ -2,7 +2,9 @@ import type { Snippet } from "svelte";
2
2
  type $$ComponentProps = {
3
3
  label: string;
4
4
  className?: string;
5
- children: Snippet;
5
+ hoverClass?: string;
6
+ children?: Snippet;
7
+ onClick?: () => void;
6
8
  };
7
9
  declare const NavDropdown: import("svelte").Component<$$ComponentProps, {}, "">;
8
10
  type NavDropdown = ReturnType<typeof NavDropdown>;
@@ -1,14 +1,17 @@
1
1
  <script lang="ts">
2
+ import { goto } from "$app/navigation";
2
3
  import type { NavigationMenuItemProps } from "../../../data/types";
4
+ import NavDropdown from "./NavDropdown.svelte";
3
5
 
4
- let { label, href, textClass }: NavigationMenuItemProps = $props();
6
+ let { label, href, textClass, hoverClass }: NavigationMenuItemProps =
7
+ $props();
5
8
  </script>
6
9
 
7
- <li>
8
- <a
9
- {href}
10
- class="inline-flex h-9 w-max items-center justify-center rounded-2xl px-4.5 py-2.5 text-sm font-medium transition-all outline-none select-none hover:bg-muted focus:bg-muted focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 {textClass}"
11
- >
12
- {label}
13
- </a>
14
- </li>
10
+ <NavDropdown
11
+ {label}
12
+ className="hidden md:block"
13
+ {hoverClass}
14
+ onClick={() => {
15
+ if (href) goto(href);
16
+ }}
17
+ />
@@ -7,8 +7,7 @@
7
7
  label,
8
8
  header,
9
9
  cards: items,
10
- textClass,
11
- subTextClass,
10
+ hoverClass,
12
11
  }: NavigationMenuItemCardProps = $props();
13
12
  </script>
14
13
 
@@ -24,7 +23,7 @@
24
23
  </p>
25
24
  {/snippet}
26
25
 
27
- <NavDropdown label={label ?? header?.label ?? ""}>
26
+ <NavDropdown label={label ?? header?.label ?? ""} {hoverClass}>
28
27
  <ul class="grid gap-2 p-2 w-100 lg:w-125 lg:grid-cols-[.75fr_1fr]">
29
28
  {#if header}
30
29
  <li
@@ -8,6 +8,7 @@
8
8
  grids: items,
9
9
  textClass,
10
10
  subTextClass,
11
+ hoverClass,
11
12
  }: NavigationMenuItemGridProps = $props();
12
13
 
13
14
  const cols = (): string => {
@@ -22,7 +23,7 @@
22
23
  const gridCols = $derived(cols());
23
24
  </script>
24
25
 
25
- <NavDropdown {label}>
26
+ <NavDropdown {label} {hoverClass}>
26
27
  {#if items}
27
28
  <ul
28
29
  class={`grid w-75 gap-2 p-2 sm:w-100 md:w-125 lg:min-w-150 max-h-75 overflow-y-auto ${gridCols}`}
@@ -2,10 +2,10 @@
2
2
  import type { NavigationMenuItemListProps } from "../../../data/types";
3
3
  import NavDropdown from "./NavDropdown.svelte";
4
4
 
5
- let { label, list }: NavigationMenuItemListProps = $props();
5
+ let { label, list, hoverClass }: NavigationMenuItemListProps = $props();
6
6
  </script>
7
7
 
8
- <NavDropdown {label} className="hidden md:block">
8
+ <NavDropdown {label} className="hidden md:block" {hoverClass}>
9
9
  <ul class="grid w-75 gap-4 p-2">
10
10
  {#each list as item, i (i)}
11
11
  <li>
@@ -2,10 +2,10 @@
2
2
  import type { NavigationMenuItemsProps } from "../../../data/types";
3
3
  import NavDropdown from "./NavDropdown.svelte";
4
4
 
5
- let { label, items, textClass }: NavigationMenuItemsProps = $props();
5
+ let { label, items, hoverClass }: NavigationMenuItemsProps = $props();
6
6
  </script>
7
7
 
8
- <NavDropdown {label} className="hidden md:block">
8
+ <NavDropdown {label} className="hidden md:block" {hoverClass}>
9
9
  <ul class="grid min-w-50 gap-4 p-1 md:p-2">
10
10
  {#each items as item, i (i)}
11
11
  <li>
@@ -3,20 +3,7 @@
3
3
  import { t } from "../../../i18n";
4
4
  import { HugeiconsIcon } from "@hugeicons/svelte";
5
5
  import { Search01Icon } from "@hugeicons/core-free-icons";
6
- import type { Snippet } from "svelte";
7
- import type { IconSvgElement } from "@hugeicons/svelte";
8
-
9
- type Props = {
10
- title?: string;
11
- description?: string;
12
- icon?: IconSvgElement;
13
- className?: string;
14
- actionHref?: string;
15
- actionLabel?: string;
16
- onAction?: () => void;
17
- showAction?: boolean;
18
- children?: Snippet;
19
- };
6
+ import type { NotFoundEmptyProps } from "./type";
20
7
 
21
8
  let {
22
9
  title,
@@ -28,7 +15,7 @@
28
15
  onAction,
29
16
  showAction = false,
30
17
  children,
31
- }: Props = $props();
18
+ }: NotFoundEmptyProps = $props();
32
19
 
33
20
  const resolvedTitle = $derived(title ?? $t("empty.title"));
34
21
  const resolvedDescription = $derived(description ?? $t("empty.description"));
@@ -1,16 +1,4 @@
1
- import type { Snippet } from "svelte";
2
- import type { IconSvgElement } from "@hugeicons/svelte";
3
- type Props = {
4
- title?: string;
5
- description?: string;
6
- icon?: IconSvgElement;
7
- className?: string;
8
- actionHref?: string;
9
- actionLabel?: string;
10
- onAction?: () => void;
11
- showAction?: boolean;
12
- children?: Snippet;
13
- };
14
- declare const NotFoundEmpty: import("svelte").Component<Props, {}, "">;
1
+ import type { NotFoundEmptyProps } from "./type";
2
+ declare const NotFoundEmpty: import("svelte").Component<NotFoundEmptyProps, {}, "">;
15
3
  type NotFoundEmpty = ReturnType<typeof NotFoundEmpty>;
16
4
  export default NotFoundEmpty;
@@ -1,5 +1,30 @@
1
1
  import type { CarouselPlugins } from "../../ui/carousel/context";
2
2
  import type { Snippet } from "svelte";
3
+ import type { IconSvgElement } from "@hugeicons/svelte";
4
+ /**
5
+ * Props do NotFoundEmpty — estado vazio com ícone, título, descrição
6
+ * e ação (link ou botão) quando não há conteúdo a exibir.
7
+ */
8
+ export type NotFoundEmptyProps = {
9
+ /** Título do estado vazio. Padrão: tradução de "empty.title" */
10
+ title?: string;
11
+ /** Descrição/apoio do estado vazio. Padrão: tradução de "empty.description" */
12
+ description?: string;
13
+ /** Ícone exibido na área de media. Padrão: ícone de busca */
14
+ icon?: IconSvgElement;
15
+ /** Classe CSS adicional para o container */
16
+ className?: string;
17
+ /** URL de destino da ação (link) quando não há onAction */
18
+ actionHref?: string;
19
+ /** Texto da ação (link ou botão) */
20
+ actionLabel?: string;
21
+ /** Callback ao clicar na ação (renderiza um botão) */
22
+ onAction?: () => void;
23
+ /** Exibe a ação de suporte mesmo sem onAction */
24
+ showAction?: boolean;
25
+ /** Snippet de conteúdo customizado no lugar da ação padrão */
26
+ children?: Snippet;
27
+ };
3
28
  /**
4
29
  * Props do slot/container de carousel (CarouselSlot).
5
30
  * Controla botões de navegação, bordas, plugins e conteúdo customizado.