@aspect-ops/exon-ui 0.2.2 → 0.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.
Files changed (35) hide show
  1. package/dist/components/CTASection/CTASection.svelte +298 -0
  2. package/dist/components/CTASection/CTASection.svelte.d.ts +15 -0
  3. package/dist/components/CTASection/index.d.ts +2 -0
  4. package/dist/components/CTASection/index.js +1 -0
  5. package/dist/components/GlobalHeader/GlobalHeader.svelte +692 -0
  6. package/dist/components/GlobalHeader/GlobalHeader.svelte.d.ts +3 -0
  7. package/dist/components/GlobalHeader/index.d.ts +2 -0
  8. package/dist/components/GlobalHeader/index.js +1 -0
  9. package/dist/components/Hero/Hero.svelte +306 -0
  10. package/dist/components/Hero/Hero.svelte.d.ts +18 -0
  11. package/dist/components/Hero/index.d.ts +2 -0
  12. package/dist/components/Hero/index.js +1 -0
  13. package/dist/components/LogoCloud/LogoCloud.svelte +333 -0
  14. package/dist/components/LogoCloud/LogoCloud.svelte.d.ts +20 -0
  15. package/dist/components/LogoCloud/index.d.ts +2 -0
  16. package/dist/components/LogoCloud/index.js +1 -0
  17. package/dist/components/ServiceCard/ServiceCard.svelte +359 -0
  18. package/dist/components/ServiceCard/ServiceCard.svelte.d.ts +16 -0
  19. package/dist/components/ServiceCard/index.d.ts +1 -0
  20. package/dist/components/ServiceCard/index.js +1 -0
  21. package/dist/components/SplitSection/SplitSection.svelte +194 -0
  22. package/dist/components/SplitSection/SplitSection.svelte.d.ts +15 -0
  23. package/dist/components/SplitSection/index.d.ts +1 -0
  24. package/dist/components/SplitSection/index.js +1 -0
  25. package/dist/components/TestimonialCard/TestimonialCard.svelte +290 -0
  26. package/dist/components/TestimonialCard/TestimonialCard.svelte.d.ts +14 -0
  27. package/dist/components/TestimonialCard/index.d.ts +1 -0
  28. package/dist/components/TestimonialCard/index.js +1 -0
  29. package/dist/components/Timeline/Timeline.svelte +444 -0
  30. package/dist/components/Timeline/Timeline.svelte.d.ts +19 -0
  31. package/dist/components/Timeline/index.d.ts +2 -0
  32. package/dist/components/Timeline/index.js +1 -0
  33. package/dist/index.d.ts +16 -0
  34. package/dist/index.js +9 -0
  35. package/package.json +1 -1
@@ -0,0 +1,444 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+
4
+ export interface TimelineItem {
5
+ title: string;
6
+ description?: string;
7
+ date?: string;
8
+ icon?: string | Snippet;
9
+ status?: 'completed' | 'current' | 'upcoming';
10
+ }
11
+
12
+ export interface TimelineProps {
13
+ items: TimelineItem[];
14
+ variant?: 'vertical' | 'horizontal';
15
+ alternating?: boolean;
16
+ size?: 'sm' | 'md' | 'lg';
17
+ connectorStyle?: 'solid' | 'dashed' | 'dotted';
18
+ class?: string;
19
+ }
20
+
21
+ let {
22
+ items,
23
+ variant = 'vertical',
24
+ alternating = false,
25
+ size = 'md',
26
+ connectorStyle = 'solid',
27
+ class: className = ''
28
+ }: TimelineProps = $props();
29
+
30
+ const getStatusLabel = (status?: string): string => {
31
+ switch (status) {
32
+ case 'completed':
33
+ return 'Completed';
34
+ case 'current':
35
+ return 'Current step';
36
+ case 'upcoming':
37
+ return 'Upcoming';
38
+ default:
39
+ return '';
40
+ }
41
+ };
42
+
43
+ const isSnippet = (icon: any): icon is Snippet => {
44
+ return typeof icon === 'function';
45
+ };
46
+ </script>
47
+
48
+ <ol
49
+ class="timeline {variant} {size} connector-{connectorStyle} {className}"
50
+ class:alternating={alternating && variant === 'vertical'}
51
+ role="list"
52
+ >
53
+ {#each items as item, index}
54
+ {@const isAlternate = alternating && variant === 'vertical' && index % 2 === 1}
55
+ {@const statusLabel = getStatusLabel(item.status)}
56
+
57
+ <li
58
+ class="timeline-item"
59
+ class:alternate={isAlternate}
60
+ class:status-completed={item.status === 'completed'}
61
+ class:status-current={item.status === 'current'}
62
+ class:status-upcoming={item.status === 'upcoming'}
63
+ aria-current={item.status === 'current' ? 'step' : undefined}
64
+ aria-label={statusLabel ? `${item.title} - ${statusLabel}` : item.title}
65
+ >
66
+ <div class="timeline-marker">
67
+ <div class="timeline-dot">
68
+ {#if item.icon}
69
+ <div class="timeline-icon">
70
+ {#if typeof item.icon === 'string'}
71
+ <span class="icon-text">{item.icon}</span>
72
+ {:else if isSnippet(item.icon)}
73
+ {@render item.icon()}
74
+ {/if}
75
+ </div>
76
+ {/if}
77
+ </div>
78
+ {#if index < items.length - 1}
79
+ <div class="timeline-connector" aria-hidden="true"></div>
80
+ {/if}
81
+ </div>
82
+
83
+ <div class="timeline-content">
84
+ {#if item.date}
85
+ <time class="timeline-date" datetime={item.date}>{item.date}</time>
86
+ {/if}
87
+ <h3 class="timeline-title">{item.title}</h3>
88
+ {#if item.description}
89
+ <p class="timeline-description">{item.description}</p>
90
+ {/if}
91
+ </div>
92
+ </li>
93
+ {/each}
94
+ </ol>
95
+
96
+ <style>
97
+ .timeline {
98
+ --timeline-line-color: var(--color-border, #e5e7eb);
99
+ --timeline-dot-size: 1rem;
100
+ --timeline-completed-color: var(--color-success, #10b981);
101
+ --timeline-current-color: var(--color-primary, #3b82f6);
102
+ --timeline-upcoming-color: var(--color-text-muted, #9ca3af);
103
+ --timeline-gap: 1.5rem;
104
+
105
+ list-style: none;
106
+ padding: 0;
107
+ margin: 0;
108
+ position: relative;
109
+ }
110
+
111
+ /* Size variants */
112
+ .timeline.sm {
113
+ --timeline-dot-size: 0.75rem;
114
+ --timeline-gap: 1rem;
115
+ }
116
+
117
+ .timeline.sm .timeline-title {
118
+ font-size: 0.875rem;
119
+ }
120
+
121
+ .timeline.sm .timeline-description,
122
+ .timeline.sm .timeline-date {
123
+ font-size: 0.75rem;
124
+ }
125
+
126
+ .timeline.lg {
127
+ --timeline-dot-size: 1.25rem;
128
+ --timeline-gap: 2rem;
129
+ }
130
+
131
+ .timeline.lg .timeline-title {
132
+ font-size: 1.125rem;
133
+ }
134
+
135
+ /* Vertical layout (default) */
136
+ .timeline.vertical {
137
+ display: flex;
138
+ flex-direction: column;
139
+ gap: var(--timeline-gap);
140
+ }
141
+
142
+ .timeline.vertical .timeline-item {
143
+ display: grid;
144
+ grid-template-columns: auto 1fr;
145
+ gap: 1rem;
146
+ position: relative;
147
+ }
148
+
149
+ .timeline.vertical .timeline-marker {
150
+ display: flex;
151
+ flex-direction: column;
152
+ align-items: center;
153
+ position: relative;
154
+ }
155
+
156
+ .timeline.vertical .timeline-connector {
157
+ width: 2px;
158
+ flex: 1;
159
+ margin-top: 0.5rem;
160
+ background-color: var(--timeline-line-color);
161
+ }
162
+
163
+ .timeline.vertical.connector-dashed .timeline-connector {
164
+ background: repeating-linear-gradient(
165
+ to bottom,
166
+ var(--timeline-line-color) 0,
167
+ var(--timeline-line-color) 4px,
168
+ transparent 4px,
169
+ transparent 8px
170
+ );
171
+ }
172
+
173
+ .timeline.vertical.connector-dotted .timeline-connector {
174
+ background: repeating-linear-gradient(
175
+ to bottom,
176
+ var(--timeline-line-color) 0,
177
+ var(--timeline-line-color) 2px,
178
+ transparent 2px,
179
+ transparent 6px
180
+ );
181
+ }
182
+
183
+ /* Alternating layout */
184
+ .timeline.alternating .timeline-item.alternate {
185
+ grid-template-columns: 1fr auto;
186
+ direction: rtl;
187
+ }
188
+
189
+ .timeline.alternating .timeline-item.alternate .timeline-content {
190
+ direction: ltr;
191
+ text-align: right;
192
+ }
193
+
194
+ .timeline.alternating .timeline-item.alternate .timeline-date {
195
+ text-align: right;
196
+ }
197
+
198
+ /* Horizontal layout */
199
+ .timeline.horizontal {
200
+ display: flex;
201
+ flex-direction: row;
202
+ gap: var(--timeline-gap);
203
+ overflow-x: auto;
204
+ padding-bottom: 1rem;
205
+ }
206
+
207
+ .timeline.horizontal .timeline-item {
208
+ display: flex;
209
+ flex-direction: column;
210
+ align-items: center;
211
+ min-width: 8rem;
212
+ flex-shrink: 0;
213
+ }
214
+
215
+ .timeline.horizontal .timeline-marker {
216
+ display: flex;
217
+ flex-direction: row;
218
+ align-items: center;
219
+ width: 100%;
220
+ }
221
+
222
+ .timeline.horizontal .timeline-connector {
223
+ height: 2px;
224
+ flex: 1;
225
+ margin-left: 0.5rem;
226
+ background-color: var(--timeline-line-color);
227
+ }
228
+
229
+ .timeline.horizontal.connector-dashed .timeline-connector {
230
+ background: repeating-linear-gradient(
231
+ to right,
232
+ var(--timeline-line-color) 0,
233
+ var(--timeline-line-color) 4px,
234
+ transparent 4px,
235
+ transparent 8px
236
+ );
237
+ }
238
+
239
+ .timeline.horizontal.connector-dotted .timeline-connector {
240
+ background: repeating-linear-gradient(
241
+ to right,
242
+ var(--timeline-line-color) 0,
243
+ var(--timeline-line-color) 2px,
244
+ transparent 2px,
245
+ transparent 6px
246
+ );
247
+ }
248
+
249
+ .timeline.horizontal .timeline-content {
250
+ margin-top: 0.75rem;
251
+ text-align: center;
252
+ }
253
+
254
+ /* Timeline dot */
255
+ .timeline-dot {
256
+ width: var(--timeline-dot-size);
257
+ height: var(--timeline-dot-size);
258
+ border-radius: 50%;
259
+ background-color: var(--timeline-upcoming-color);
260
+ border: 2px solid currentColor;
261
+ display: flex;
262
+ align-items: center;
263
+ justify-content: center;
264
+ flex-shrink: 0;
265
+ position: relative;
266
+ z-index: 1;
267
+ }
268
+
269
+ .timeline-item.status-completed .timeline-dot {
270
+ background-color: var(--timeline-completed-color);
271
+ color: var(--timeline-completed-color);
272
+ }
273
+
274
+ .timeline-item.status-current .timeline-dot {
275
+ background-color: var(--timeline-current-color);
276
+ color: var(--timeline-current-color);
277
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
278
+ animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
279
+ }
280
+
281
+ .timeline-item.status-upcoming .timeline-dot {
282
+ background-color: var(--color-background, #ffffff);
283
+ color: var(--timeline-upcoming-color);
284
+ }
285
+
286
+ @keyframes pulse {
287
+ 0%,
288
+ 100% {
289
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
290
+ }
291
+ 50% {
292
+ box-shadow: 0 0 0 6px rgba(59, 130, 246, 0.1);
293
+ }
294
+ }
295
+
296
+ /* Timeline icon */
297
+ .timeline-icon {
298
+ display: flex;
299
+ align-items: center;
300
+ justify-content: center;
301
+ width: 100%;
302
+ height: 100%;
303
+ font-size: 0.625rem;
304
+ }
305
+
306
+ .icon-text {
307
+ line-height: 1;
308
+ }
309
+
310
+ /* Timeline content */
311
+ .timeline-content {
312
+ min-width: 0;
313
+ padding-top: 0.125rem;
314
+ }
315
+
316
+ .timeline-date {
317
+ display: block;
318
+ font-size: 0.875rem;
319
+ color: var(--timeline-upcoming-color);
320
+ margin-bottom: 0.25rem;
321
+ }
322
+
323
+ .timeline-title {
324
+ font-size: 1rem;
325
+ font-weight: 600;
326
+ color: var(--color-text, #1f2937);
327
+ margin: 0 0 0.25rem 0;
328
+ line-height: 1.5;
329
+ }
330
+
331
+ .timeline-item.status-current .timeline-title {
332
+ font-weight: 700;
333
+ color: var(--timeline-current-color);
334
+ }
335
+
336
+ .timeline-description {
337
+ font-size: 0.875rem;
338
+ color: var(--color-text-secondary, #6b7280);
339
+ margin: 0;
340
+ line-height: 1.5;
341
+ }
342
+
343
+ /* Responsive: horizontal becomes vertical on mobile */
344
+ @media (max-width: 640px) {
345
+ .timeline.horizontal {
346
+ flex-direction: column;
347
+ gap: var(--timeline-gap);
348
+ }
349
+
350
+ .timeline.horizontal .timeline-item {
351
+ display: grid;
352
+ grid-template-columns: auto 1fr;
353
+ gap: 1rem;
354
+ min-width: auto;
355
+ align-items: start;
356
+ }
357
+
358
+ .timeline.horizontal .timeline-marker {
359
+ flex-direction: column;
360
+ width: auto;
361
+ }
362
+
363
+ .timeline.horizontal .timeline-connector {
364
+ width: 2px;
365
+ height: auto;
366
+ flex: 1;
367
+ margin-left: 0;
368
+ margin-top: 0.5rem;
369
+ }
370
+
371
+ .timeline.horizontal.connector-dashed .timeline-connector {
372
+ background: repeating-linear-gradient(
373
+ to bottom,
374
+ var(--timeline-line-color) 0,
375
+ var(--timeline-line-color) 4px,
376
+ transparent 4px,
377
+ transparent 8px
378
+ );
379
+ }
380
+
381
+ .timeline.horizontal.connector-dotted .timeline-connector {
382
+ background: repeating-linear-gradient(
383
+ to bottom,
384
+ var(--timeline-line-color) 0,
385
+ var(--timeline-line-color) 2px,
386
+ transparent 2px,
387
+ transparent 6px
388
+ );
389
+ }
390
+
391
+ .timeline.horizontal .timeline-content {
392
+ margin-top: 0;
393
+ text-align: left;
394
+ }
395
+
396
+ /* Alternating becomes single-side on mobile */
397
+ .timeline.alternating .timeline-item.alternate {
398
+ grid-template-columns: auto 1fr;
399
+ direction: ltr;
400
+ }
401
+
402
+ .timeline.alternating .timeline-item.alternate .timeline-content {
403
+ text-align: left;
404
+ }
405
+
406
+ .timeline.alternating .timeline-item.alternate .timeline-date {
407
+ text-align: left;
408
+ }
409
+ }
410
+
411
+ /* Accessibility: Focus styles */
412
+ .timeline-item:focus-visible {
413
+ outline: 2px solid var(--timeline-current-color);
414
+ outline-offset: 2px;
415
+ border-radius: 0.25rem;
416
+ }
417
+
418
+ /* Touch targets */
419
+ @media (hover: none) {
420
+ .timeline-item {
421
+ min-height: 44px;
422
+ }
423
+ }
424
+
425
+ /* Dark mode support */
426
+ @media (prefers-color-scheme: dark) {
427
+ .timeline {
428
+ --timeline-line-color: var(--color-border-dark, #374151);
429
+ --timeline-upcoming-color: var(--color-text-muted-dark, #6b7280);
430
+ }
431
+
432
+ .timeline-title {
433
+ color: var(--color-text-dark, #f9fafb);
434
+ }
435
+
436
+ .timeline-description {
437
+ color: var(--color-text-secondary-dark, #9ca3af);
438
+ }
439
+
440
+ .timeline-item.status-upcoming .timeline-dot {
441
+ background-color: var(--color-background-dark, #1f2937);
442
+ }
443
+ }
444
+ </style>
@@ -0,0 +1,19 @@
1
+ import type { Snippet } from 'svelte';
2
+ export interface TimelineItem {
3
+ title: string;
4
+ description?: string;
5
+ date?: string;
6
+ icon?: string | Snippet;
7
+ status?: 'completed' | 'current' | 'upcoming';
8
+ }
9
+ export interface TimelineProps {
10
+ items: TimelineItem[];
11
+ variant?: 'vertical' | 'horizontal';
12
+ alternating?: boolean;
13
+ size?: 'sm' | 'md' | 'lg';
14
+ connectorStyle?: 'solid' | 'dashed' | 'dotted';
15
+ class?: string;
16
+ }
17
+ declare const Timeline: import("svelte").Component<TimelineProps, {}, "">;
18
+ type Timeline = ReturnType<typeof Timeline>;
19
+ export default Timeline;
@@ -0,0 +1,2 @@
1
+ export { default as Timeline } from './Timeline.svelte';
2
+ export type { TimelineProps, TimelineItem } from './Timeline.svelte';
@@ -0,0 +1 @@
1
+ export { default as Timeline } from './Timeline.svelte';
package/dist/index.d.ts CHANGED
@@ -89,4 +89,20 @@ export { ContactForm } from './components/ContactForm/index.js';
89
89
  export { ViewCounter } from './components/ViewCounter/index.js';
90
90
  export { Mermaid } from './components/Mermaid/index.js';
91
91
  export { DoughnutChart } from './components/DoughnutChart/index.js';
92
+ export { TestimonialCard } from './components/TestimonialCard/index.js';
93
+ export type { TestimonialCardProps } from './components/TestimonialCard/index.js';
94
+ export { Hero } from './components/Hero/index.js';
95
+ export type { HeroProps } from './components/Hero/index.js';
96
+ export { GlobalHeader } from './components/GlobalHeader/index.js';
97
+ export type { GlobalHeaderProps, NavItem as GlobalHeaderNavItem } from './components/GlobalHeader/index.js';
98
+ export { CTASection } from './components/CTASection/index.js';
99
+ export type { CTASectionProps } from './components/CTASection/index.js';
100
+ export { LogoCloud } from './components/LogoCloud/index.js';
101
+ export type { LogoCloudProps, LogoItem } from './components/LogoCloud/index.js';
102
+ export { ServiceCard } from './components/ServiceCard/index.js';
103
+ export type { ServiceCardProps } from './components/ServiceCard/index.js';
104
+ export { SplitSection } from './components/SplitSection/index.js';
105
+ export type { SplitSectionProps } from './components/SplitSection/index.js';
106
+ export { Timeline } from './components/Timeline/index.js';
107
+ export type { TimelineProps, TimelineItem } from './components/Timeline/index.js';
92
108
  export type { ButtonProps, ButtonVariant, ButtonSize, TypographyProps, TypographyVariant, IconProps, IconSize, BadgeProps, BadgeVariant, LinkProps, InputSize, TextInputType, FormFieldProps, TextInputProps, TextareaProps, SelectOption, SelectProps, CheckboxProps, RadioProps, RadioGroupProps, SwitchProps, SearchInputProps, DatePickerProps, FileUploadProps, OTPInputProps, TimeFormat, TimePickerProps, RatingProps, ToggleGroupType, ToggleGroupOrientation, ToggleGroupProps, ToggleGroupItemProps, NumberInputProps, PaginationProps, TabsOrientation, TabsProps, TabListProps, TabTriggerProps, TabContentProps, MenuProps, MenuTriggerProps, MenuContentProps, MenuItemProps, MenuSeparatorProps, MenuSubProps, MenuSubTriggerProps, MenuSubContentProps, BreadcrumbItemData, BreadcrumbsProps, BreadcrumbItemProps, BottomNavItemData, BottomNavProps, BottomNavItemProps, NavItemProps, NavbarProps, SidebarItemData, SidebarProps, SidebarItemProps, SidebarGroupProps, StepperOrientation, StepperProps, StepperStepProps, AlertVariant, AlertProps, ToastVariant, ToastPosition, ToastData, ToastProps, ToastContainerProps, ModalSize, ModalProps, ModalHeaderProps, ModalBodyProps, ModalFooterProps, ProgressSize, ProgressBarProps, ProgressCircleProps, SpinnerProps, TooltipSide, TooltipProps, PopoverSide, PopoverProps, PopoverTriggerProps, PopoverContentProps, SkeletonVariant, SkeletonProps, StatusBannerStatus, StatusBannerPosition, StatusBannerProps, CardVariant, CardProps, CardHeaderProps, CardBodyProps, CardFooterProps, FlipDirection, FlipTrigger, FlipCardProps, AvatarSize, AvatarShape, AvatarProps, AvatarGroupProps, TagVariant, TagSize, TagProps, ChipVariant, ChipColor, ChipSize, ChipProps, ChipGroupProps, EmptyStateSize, EmptyStateProps, PageHeaderProps, StatCircleColor, StatCircleSize, StatCircleProps, ListProps, ListItemProps, TableProps, TableHeadProps, TableHeaderAlign, TableHeaderSortDirection, TableHeaderProps, TableBodyProps, TableRowProps, TableCellAlign, TableCellProps, AccordionProps, AccordionItemProps, SliderProps, CarouselProps, CarouselSlideProps, ImageObjectFit, ImageRounded, ImageProps, StatusBadgeColor, StatusBadgeSize, StatusBadgeProps, StatsCardColor, StatsCardTrend, StatsCardProps, DataTableSortOrder, DataTableColumnAlign, DataTableColumn, DataTableProps, ContainerSize, ContainerProps, GridAlign, GridJustify, SpacingToken, GridProps, GridItemProps, StackDirection, StackProps, DividerOrientation, DividerProps, SpacerSize, SpacerProps, AspectRatioPreset, AspectRatioProps, CenterProps, BoxProps, SafeAreaEdge, SafeAreaProps, BottomSheetSnapPoint, BottomSheetProps, BottomSheetHeaderProps, BottomSheetBodyProps, ActionSheetAction, ActionSheetProps, ActionSheetItemProps, PullToRefreshProps, SwipeActionSide, SwipeActionData, SwipeActionsProps, SwipeActionProps, FABSize, FABPosition, FABProps, FABAction, FABGroupProps } from './types/index.js';
package/dist/index.js CHANGED
@@ -98,3 +98,12 @@ export { ContactForm } from './components/ContactForm/index.js';
98
98
  export { ViewCounter } from './components/ViewCounter/index.js';
99
99
  export { Mermaid } from './components/Mermaid/index.js';
100
100
  export { DoughnutChart } from './components/DoughnutChart/index.js';
101
+ // Section Components (Website Sections)
102
+ export { TestimonialCard } from './components/TestimonialCard/index.js';
103
+ export { Hero } from './components/Hero/index.js';
104
+ export { GlobalHeader } from './components/GlobalHeader/index.js';
105
+ export { CTASection } from './components/CTASection/index.js';
106
+ export { LogoCloud } from './components/LogoCloud/index.js';
107
+ export { ServiceCard } from './components/ServiceCard/index.js';
108
+ export { SplitSection } from './components/SplitSection/index.js';
109
+ export { Timeline } from './components/Timeline/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aspect-ops/exon-ui",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Reusable Svelte UI components for web and Capacitor mobile apps",
5
5
  "author": "Exon Team",
6
6
  "license": "MIT",