@makolabs/ripple 3.2.0 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,10 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../../helper/cls.js';
3
3
  import { buildTestId } from '../../helper/testid.js';
4
- import { Color } from '../../variants.js';
4
+ import { Color, Size } from '../../variants.js';
5
5
  import { fade } from 'svelte/transition';
6
6
  import { quintOut } from 'svelte/easing';
7
+ import Button from '../../button/Button.svelte';
7
8
  import type { AlertProps, VariantColors } from '../../index.js';
8
9
 
9
10
  let {
@@ -11,7 +12,7 @@
11
12
  message,
12
13
  color = Color.DEFAULT,
13
14
  onclose,
14
- footer,
15
+ actions,
15
16
  icon: Icon,
16
17
  class: className = '',
17
18
  testId
@@ -21,6 +22,9 @@
21
22
  onclose?.();
22
23
  }
23
24
 
25
+ // Container chrome: bg-{c}-50 + border-{c}-200 + body text-{c}-800.
26
+ // Title and icon get their own steps for stronger hierarchy:
27
+ // title → text-{c}-900 (darker than body), icon circle → bg-{c}-100 / text-{c}-700.
24
28
  const colorClasses: Record<VariantColors, string> = {
25
29
  [Color.DEFAULT]: 'bg-default-50 border-default-200 text-default-800',
26
30
  [Color.PRIMARY]: 'bg-primary-50 border-primary-200 text-primary-800',
@@ -30,28 +34,79 @@
30
34
  [Color.WARNING]: 'bg-warning-50 border-warning-200 text-warning-800',
31
35
  [Color.DANGER]: 'bg-danger-50 border-danger-200 text-danger-800'
32
36
  };
37
+
38
+ const titleColorClasses: Record<VariantColors, string> = {
39
+ [Color.DEFAULT]: 'text-default-900',
40
+ [Color.PRIMARY]: 'text-primary-900',
41
+ [Color.SECONDARY]: 'text-secondary-900',
42
+ [Color.INFO]: 'text-info-900',
43
+ [Color.SUCCESS]: 'text-success-900',
44
+ [Color.WARNING]: 'text-warning-900',
45
+ [Color.DANGER]: 'text-danger-900'
46
+ };
47
+
48
+ const iconCircleClasses: Record<VariantColors, string> = {
49
+ [Color.DEFAULT]: 'bg-default-100 text-default-700',
50
+ [Color.PRIMARY]: 'bg-primary-100 text-primary-700',
51
+ [Color.SECONDARY]: 'bg-secondary-100 text-secondary-700',
52
+ [Color.INFO]: 'bg-info-100 text-info-700',
53
+ [Color.SUCCESS]: 'bg-success-100 text-success-700',
54
+ [Color.WARNING]: 'bg-warning-100 text-warning-700',
55
+ [Color.DANGER]: 'bg-danger-100 text-danger-700'
56
+ };
33
57
  </script>
34
58
 
35
59
  <div
36
60
  role="alert"
37
- class={cn('relative rounded-lg border p-4', colorClasses[color], className)}
61
+ class={cn('relative rounded-lg border p-4 shadow-sm', colorClasses[color], className)}
38
62
  data-testid={buildTestId('alert', undefined, testId)}
39
63
  transition:fade={{ duration: 1000, easing: quintOut }}
40
64
  >
41
- <div class="flex items-start justify-between gap-4">
65
+ <div class="flex items-center justify-between gap-4">
42
66
  {#if Icon}
43
- <Icon class="mt-0.5 h-5 w-5 shrink-0" />
67
+ <div
68
+ class={cn(
69
+ 'flex h-10 w-10 shrink-0 items-center justify-center rounded-full',
70
+ iconCircleClasses[color]
71
+ )}
72
+ aria-hidden="true"
73
+ data-testid={buildTestId('alert', 'icon', testId)}
74
+ >
75
+ <Icon class="h-5 w-5" />
76
+ </div>
44
77
  {/if}
45
- <div class="flex-1">
78
+ <div class="min-w-0 flex-1">
46
79
  {#if title}
47
- <h4 class="font-semibold" data-testid={buildTestId('alert', 'title', testId)}>{title}</h4>
80
+ <h4
81
+ class={cn('font-semibold', titleColorClasses[color])}
82
+ data-testid={buildTestId('alert', 'title', testId)}
83
+ >
84
+ {title}
85
+ </h4>
48
86
  {/if}
49
87
  <p class="text-sm" data-testid={buildTestId('alert', 'message', testId)}>{message}</p>
50
88
  </div>
89
+ {#if actions && actions.length > 0}
90
+ <div
91
+ class="flex shrink-0 items-center gap-2"
92
+ data-testid={buildTestId('alert', 'actions', testId)}
93
+ >
94
+ {#each actions as action, i (action.label + i)}
95
+ <Button
96
+ size={Size.SM}
97
+ variant={action.variant ?? 'solid'}
98
+ color={action.color ?? color}
99
+ onclick={() => action.onclick?.()}
100
+ >
101
+ {action.label}
102
+ </Button>
103
+ {/each}
104
+ </div>
105
+ {/if}
51
106
  {#if onclose}
52
107
  <button
53
108
  type="button"
54
- class="hover:bg-default-200/20 flex-shrink-0 cursor-pointer rounded-md p-1"
109
+ class="hover:bg-default-200/20 shrink-0 cursor-pointer rounded-md p-1"
55
110
  onclick={handleClose}
56
111
  aria-label="Close alert"
57
112
  data-testid={buildTestId('alert', 'close', testId)}
@@ -66,7 +121,4 @@
66
121
  </button>
67
122
  {/if}
68
123
  </div>
69
- {#if footer}
70
- {@render footer()}
71
- {/if}
72
124
  </div>
package/dist/index.d.ts CHANGED
@@ -28,7 +28,7 @@ export type { ModalProps } from './modal/modal-types.js';
28
28
  export type { ConfirmDialogProps } from './modal/confirm-dialog-types.js';
29
29
  export type { DrawerProps } from './drawer/drawer-types.js';
30
30
  export type { DropdownItem, DropSection, DropHeaderConfig, DropdownMenuProps, SelectItem, SelectProps } from './elements/dropdown/dropdown-types.js';
31
- export type { CardProps, AlertProps, MetricDetail, MetricCardProps } from './layout/card/card-types.js';
31
+ export type { CardProps, AlertProps, AlertAction, MetricDetail, MetricCardProps } from './layout/card/card-types.js';
32
32
  export type { DataRow, KeyType, StatusType, TableColumn, SortDirection, SortState, TableProps } from './layout/table/table-types.js';
33
33
  export type { BreadcrumbItem, BreadcrumbsProps, PageHeaderProps } from './header/header-types.js';
34
34
  export type { TabItem, TabProps, TabsGroupProps, TabContentProps } from './layout/tabs/tabs-types.js';
@@ -73,6 +73,26 @@ export type CardProps = {
73
73
  loading?: boolean;
74
74
  testId?: string;
75
75
  };
76
+ /**
77
+ * Button-style action attached to an `<Alert>` (e.g. "Mark as Shipped",
78
+ * "Upgrade now"). Rendered inline on the right side of the alert,
79
+ * between the message and the optional close button.
80
+ *
81
+ * The same shape as `ActivityItemAction` — consumers building both
82
+ * activity feeds and alerts only need to learn one action contract.
83
+ */
84
+ export type AlertAction = {
85
+ label: string;
86
+ onclick?: () => void;
87
+ /**
88
+ * Override the action button's color. Defaults to the parent
89
+ * `<Alert>`'s `color` so the CTA visually anchors to the banner
90
+ * (e.g. a warning alert gets warning-colored buttons).
91
+ */
92
+ color?: VariantColors;
93
+ /** Optional ripple button variant. @default 'solid' */
94
+ variant?: 'solid' | 'outline' | 'ghost' | 'link';
95
+ };
76
96
  /**
77
97
  * Props for `<Alert>` — a prominent inline banner for success / warning /
78
98
  * error / info messages. Use at the top of a page or above a form. For
@@ -86,12 +106,14 @@ export type CardProps = {
86
106
  *
87
107
  * @example
88
108
  * ```svelte
89
- * <!-- Dismissable with a custom footer action -->
90
- * <Alert color="warning" message="Your trial ends in 3 days." onclose={() => {}}>
91
- * {#snippet footer()}
92
- * <Button size="sm">Upgrade now</Button>
93
- * {/snippet}
94
- * </Alert>
109
+ * <!-- Dismissable with an inline action -->
110
+ * <Alert
111
+ * color="warning"
112
+ * title="Ready for Shipment"
113
+ * message="Payment complete. Notify supplier when dispatched."
114
+ * actions={[{ label: 'Mark as Shipped', onclick: openShipModal }]}
115
+ * onclose={() => {}}
116
+ * />
95
117
  * ```
96
118
  */
97
119
  export type AlertProps = {
@@ -104,8 +126,12 @@ export type AlertProps = {
104
126
  class?: ClassValue;
105
127
  /** When provided, renders a × dismiss button. */
106
128
  onclose?: () => void;
107
- /** Additional content below the message (e.g. action buttons). */
108
- footer?: Snippet;
129
+ /**
130
+ * Inline action buttons rendered on the right side of the alert,
131
+ * between the message and the close button. Each action defaults
132
+ * to the alert's `color` and `variant: 'solid'`.
133
+ */
134
+ actions?: AlertAction[];
109
135
  /** Override the default color-appropriate icon. */
110
136
  icon?: Component;
111
137
  testId?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makolabs/ripple",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Simple Svelte 5 powered component library ✨",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {