@yatoday/astro-ui 0.6.0 → 0.6.10

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.
@@ -8,7 +8,7 @@ const {
8
8
  title = await Astro.slots.render('title'),
9
9
  subtitle = await Astro.slots.render('subtitle'),
10
10
  tagline = await Astro.slots.render('tagline'),
11
- actions = await Astro.slots.render('actions'),
11
+ callToAction = await Astro.slots.render('actions'),
12
12
 
13
13
  id,
14
14
  isDark = false,
@@ -29,17 +29,32 @@ const {
29
29
  subtitle: 'text-xl',
30
30
  }}
31
31
  />
32
+
32
33
  {
33
- actions && (
34
+ callToAction && (
34
35
  <div class="m-auto flex flex-nowrap flex-col md:flex-row md:justify-start gap-4 mt-6">
35
- {Array.isArray(actions) ? (
36
- actions.map((action) => (
37
- <div class="flex w-auto">
38
- <Button {...(action || {})} class="w-full sm:mb-0" />
39
- </div>
36
+ {Array.isArray(callToAction) ? (
37
+ callToAction.map((action) => (
38
+ <Fragment>
39
+ {typeof action === 'string' ? (
40
+ <Fragment set:html={action} />
41
+ ) : (
42
+ <div class="flex w-auto">
43
+ <Button {...(action || {})} class="w-full sm:mb-0" />
44
+ </div>
45
+ )}
46
+ </Fragment>
40
47
  ))
41
48
  ) : (
42
- <Fragment set:html={actions} />
49
+ <Fragment>
50
+ {typeof callToAction === 'string' ? (
51
+ <Fragment set:html={callToAction} />
52
+ ) : (
53
+ <div class="flex w-auto">
54
+ <Button {...(callToAction as Object)} class="w-full sm:mb-0" />
55
+ </div>
56
+ )}
57
+ </Fragment>
43
58
  )}
44
59
  </div>
45
60
  )
@@ -5,6 +5,5 @@ export type CallToActionProps = {
5
5
  title?: string;
6
6
  subtitle?: string;
7
7
  tagline?: string;
8
- callToAction?: ToAction;
9
- actions?: string | ToAction[];
8
+ callToAction?: string | ToAction | Array<string | ToAction>;
10
9
  } & WidgetWrapperProps;
@@ -5,15 +5,16 @@ import Image from '../Image/Image.astro';
5
5
  import Button from '../Button/Button.astro';
6
6
  import { Icon } from 'astro-icon/components';
7
7
  import { twMerge } from 'tailwind-merge';
8
+ import { cn } from '../../utils';
8
9
 
9
10
  const {
10
11
  title = await Astro.slots.render('title'),
11
12
  description,
12
13
  icon,
13
- image,
14
+ image = await Astro.slots.render('image'),
14
15
  data = [],
15
16
  links = [],
16
- callToAction,
17
+ callToAction = await Astro.slots.render('actions'),
17
18
  classes = {},
18
19
  as = 'article',
19
20
  asHeader = 'h3',
@@ -49,37 +50,19 @@ const img = {
49
50
  {
50
51
  image && (
51
52
  <div class={twMerge('w-full overflow-hidden -mt-6 h-60 bg-gray-400 dark:bg-zinc-700', imageClass)}>
52
- {callToAction && callToAction.href ? (
53
- <a href={callToAction.href} class="group">
54
- <Image
55
- src={img.src}
56
- class={twMerge('w-full h-full hover:scale-105 transition duration-300')}
57
- widths={[400, 900]}
58
- width={400}
59
- height={400}
60
- sizes="(max-width: 900px) 400px, 900px"
61
- alt={img.alt}
62
- aspectRatio={img.aspectRatio}
63
- layout="cover"
64
- loading="lazy"
65
- decoding="async"
66
- />
67
- </a>
68
- ) : (
69
- <Image
70
- src={img.src || String(image)}
71
- class={twMerge('w-full h-full')}
72
- widths={[400, 900]}
73
- width={400}
74
- height={400}
75
- sizes="(max-width: 900px) 400px, 900px"
76
- alt={img.alt || title}
77
- aspectRatio={img.aspectRatio}
78
- layout="cover"
79
- loading="lazy"
80
- decoding="async"
81
- />
82
- )}
53
+ <Image
54
+ src={img.src || String(image)}
55
+ class={twMerge('w-full h-full')}
56
+ widths={[400, 900]}
57
+ width={400}
58
+ height={400}
59
+ sizes="(max-width: 900px) 400px, 900px"
60
+ alt={img.alt || title}
61
+ aspectRatio={img.aspectRatio}
62
+ layout="cover"
63
+ loading="lazy"
64
+ decoding="async"
65
+ />
83
66
  </div>
84
67
  )
85
68
  }
@@ -137,10 +120,24 @@ const img = {
137
120
  <div class={twMerge('w-full px-6')}>
138
121
  <slot name="footer" />
139
122
 
140
- {callToAction && (
141
- <div class={twMerge('', actionClass)}>
142
- <Button {...callToAction} />
123
+ {Array.isArray(callToAction) ? (
124
+ <div class={cn('flex gap-2', actionClass)}>
125
+ {callToAction.map((action) => (
126
+ <Fragment>
127
+ {typeof action === 'string' ? <Fragment set:html={action} /> : <Button {...(action || {})} />}
128
+ </Fragment>
129
+ ))}
143
130
  </div>
131
+ ) : (
132
+ <Fragment>
133
+ {typeof callToAction === 'string' ? (
134
+ <Fragment set:html={callToAction} />
135
+ ) : (
136
+ <div class={cn('', actionClass)}>
137
+ <Button {...(callToAction as Object)} />
138
+ </div>
139
+ )}
140
+ </Fragment>
144
141
  )}
145
142
  </div>
146
143
  )
@@ -7,7 +7,7 @@ export type Card1Props = {
7
7
  title?: string;
8
8
  description?: string;
9
9
  icon?: string;
10
- callToAction?: ToAction;
10
+ callToAction?: string | ToAction | Array<string | ToAction>;
11
11
  data?: NameValue[];
12
12
  links?: Link[];
13
13
  badge?: string;
@@ -4,13 +4,15 @@ import Card0 from '../Card0/Card0.astro';
4
4
  import Image from '../Image/Image.astro';
5
5
  import { Icon } from 'astro-icon/components';
6
6
  import { twMerge } from 'tailwind-merge';
7
+ import { cn } from '../../utils';
7
8
 
8
9
  const {
9
10
  title = await Astro.slots.render('title'),
10
11
  description,
11
12
  icon,
12
- image,
13
- url = '/',
13
+ image = await Astro.slots.render('image'),
14
+ url = '',
15
+ callToAction,
14
16
  classes = {},
15
17
  as = 'article',
16
18
  asHeader = 'h3',
@@ -39,7 +41,7 @@ const img = {
39
41
  as={as}
40
42
  badge={badge}
41
43
  classes={{
42
- container: containerClass,
44
+ container: cn('group', containerClass),
43
45
  badge: badgeClass,
44
46
  }}
45
47
  >
@@ -50,7 +52,7 @@ const img = {
50
52
  <div class={twMerge('w-full overflow-hidden -mt-6 h-40 bg-gray-400 dark:bg-zinc-700', imageClass)}>
51
53
  <Image
52
54
  src={img.src || String(image)}
53
- class={twMerge('w-full md:h-full group-hover:scale-105 transition duration-300', imageClass)}
55
+ class={cn('w-full md:h-full', imageClass, (url || callToAction?.href) && 'group-hover:scale-105 transition duration-300')}
54
56
  widths={[400, 900]}
55
57
  width={400}
56
58
  height={400}
@@ -65,16 +67,16 @@ const img = {
65
67
  )
66
68
  }
67
69
 
68
- <!-- Icon -->
69
70
  {
70
71
  icon && (
71
72
  <div class="h-12 px-6">
72
73
  <Icon
73
74
  name={icon}
74
- class={twMerge(
75
+ class={cn(
75
76
  'w-12 h-12 text-primary group-hover:scale-105 transition duration-300',
76
77
  image ? 'mt-6' : '',
77
- iconClass
78
+ iconClass,
79
+ url || (callToAction?.href && 'group-hover:scale-105 transition duration-300')
78
80
  )}
79
81
  />
80
82
  </div>
@@ -87,8 +89,8 @@ const img = {
87
89
  <div>
88
90
  <WrapperHeaderTag class={twMerge('text-xl font-bold', titleClass)}>
89
91
  {
90
- url ? (
91
- <a href={url} class="after:content-[''] after:inset-0 after:absolute">
92
+ url || callToAction?.href ? (
93
+ <a href={url || callToAction?.href || '/'} class="after:content-[''] after:inset-0 after:absolute">
92
94
  {title}
93
95
  </a>
94
96
  ) : (
@@ -1,5 +1,6 @@
1
1
  import type { HTMLTag } from 'astro/types';
2
2
  import type { Card0Props } from '../Card0/types';
3
+ import type { ToAction } from '~/types';
3
4
 
4
5
  export type Card2Props = {
5
6
  title?: string;
@@ -8,4 +9,5 @@ export type Card2Props = {
8
9
  asHeader?: HTMLTag;
9
10
  badge?: string;
10
11
  url?: string;
12
+ callToAction?: ToAction;
11
13
  } & Card0Props;
@@ -4,12 +4,13 @@ import Card0 from '../Card0/Card0.astro';
4
4
  import Image from '../Image/Image.astro';
5
5
  import Button from '../Button/Button.astro';
6
6
  import { twMerge } from 'tailwind-merge';
7
+ import { cn } from '../../utils';
7
8
 
8
9
  const {
9
10
  title = await Astro.slots.render('title'),
10
11
  description,
11
- callToAction,
12
- image,
12
+ callToAction = await Astro.slots.render('actions'),
13
+ image = await Astro.slots.render('image'),
13
14
  classes = {},
14
15
  as = 'article',
15
16
  asHeader = 'h3',
@@ -23,14 +24,17 @@ const {
23
24
  title: titleClass = '',
24
25
  description: descriptionClass = 'text-muted-foreground',
25
26
  image: imageClass = '',
27
+ action: actionClass = '',
26
28
  badge: badgeClass = 'top-2 left-2',
27
29
  } = classes;
28
30
 
29
- const img = {
30
- src: typeof image === 'string' ? image : image?.src,
31
- alt: typeof image === 'string' ? title : image?.alt,
32
- aspectRatio: typeof image === 'string' ? '4:3' : image?.aspectRatio || '4:3',
33
- };
31
+ const urlForImage = Array.isArray(callToAction)
32
+ ? typeof callToAction[0] === 'string'
33
+ ? callToAction[0]
34
+ : (callToAction[0] as { href?: string })?.href
35
+ : typeof callToAction === 'string'
36
+ ? callToAction
37
+ : (callToAction as { href?: string })?.href;
34
38
  ---
35
39
 
36
40
  <Card0
@@ -47,36 +51,42 @@ const img = {
47
51
  <div
48
52
  class={twMerge('w-full aspect-square overflow-hidden rounded-lg bg-gray-400 dark:bg-zinc-700', imageClass)}
49
53
  >
50
- {callToAction && callToAction.href ? (
51
- <a href={callToAction.href} class="group">
52
- <Image
53
- src={img.src}
54
- class={twMerge('w-full h-full hover:scale-105 transition duration-300')}
55
- widths={[400, 900]}
56
- width={400}
57
- height={400}
58
- sizes="(max-width: 900px) 400px, 900px"
59
- alt={img.alt}
60
- aspectRatio={img.aspectRatio}
61
- layout="cover"
62
- loading="lazy"
63
- decoding="async"
64
- />
54
+ {urlForImage ? (
55
+ <a href={urlForImage} class="group">
56
+ {typeof image === 'string' ? (
57
+ <Fragment set:html={image} />
58
+ ) : (
59
+ <Image
60
+ class={twMerge('w-full h-full hover:scale-105 transition duration-300')}
61
+ widths={[400, 900]}
62
+ width={400}
63
+ height={400}
64
+ sizes="(max-width: 900px) 400px, 900px"
65
+ layout="cover"
66
+ loading="lazy"
67
+ decoding="async"
68
+ {...image}
69
+ />
70
+ )}
65
71
  </a>
66
72
  ) : (
67
- <Image
68
- src={img.src || String(image)}
69
- class={twMerge('w-full h-full')}
70
- widths={[400, 900]}
71
- width={400}
72
- height={400}
73
- sizes="(max-width: 900px) 400px, 900px"
74
- alt={img.alt || title}
75
- aspectRatio={img.aspectRatio}
76
- layout="cover"
77
- loading="lazy"
78
- decoding="async"
79
- />
73
+ <Fragment>
74
+ {typeof image === 'string' ? (
75
+ <Fragment set:html={image} />
76
+ ) : (
77
+ <Image
78
+ class={twMerge('w-full h-full')}
79
+ widths={[400, 900]}
80
+ width={400}
81
+ height={400}
82
+ sizes="(max-width: 900px) 400px, 900px"
83
+ layout="cover"
84
+ loading="lazy"
85
+ decoding="async"
86
+ {...image}
87
+ />
88
+ )}
89
+ </Fragment>
80
90
  )}
81
91
  </div>
82
92
  )
@@ -85,16 +95,42 @@ const img = {
85
95
 
86
96
  <div class="flex items-start gap-2">
87
97
  <div>
88
- <WrapperHeaderTag class={twMerge('text-lg md:text-xl font-bold', titleClass)}>
98
+ <WrapperHeaderTag class={cn('text-lg md:text-xl font-bold', titleClass)}>
89
99
  {title}
90
100
  </WrapperHeaderTag>
91
101
 
92
- <div class={twMerge('mt-2 text-sm md:text-base leading-5 md:leading-6', descriptionClass)}>
102
+ <div class={cn('mt-2 text-sm md:text-base leading-5 md:leading-6', descriptionClass)}>
93
103
  <slot />
94
104
  {description}
95
105
  </div>
96
106
  </div>
97
107
 
98
- {callToAction && <Button {...callToAction} />}
108
+ {
109
+ callToAction && (
110
+ <div>
111
+ <slot name="footer" />
112
+
113
+ {Array.isArray(callToAction) ? (
114
+ <div class={cn('flex gap-2', actionClass)}>
115
+ {callToAction.map((action) => (
116
+ <Fragment>
117
+ {typeof action === 'string' ? <Fragment set:html={action} /> : <Button {...(action || {})} />}
118
+ </Fragment>
119
+ ))}
120
+ </div>
121
+ ) : (
122
+ <Fragment>
123
+ {typeof callToAction === 'string' ? (
124
+ <Fragment set:html={callToAction} />
125
+ ) : (
126
+ <div class={cn('', actionClass)}>
127
+ <Button {...(callToAction as Object)} />
128
+ </div>
129
+ )}
130
+ </Fragment>
131
+ )}
132
+ </div>
133
+ )
134
+ }
99
135
  </div>
100
136
  </Card0>
@@ -7,5 +7,5 @@ export type Card3Props = {
7
7
  description?: string;
8
8
  asHeader?: HTMLTag;
9
9
  badge?: string;
10
- callToAction?: ToAction;
10
+ callToAction?: string | ToAction | Array<string | ToAction>;
11
11
  } & Card0Props;
@@ -9,7 +9,7 @@ import { cn } from '../../utils';
9
9
  const {
10
10
  title = await Astro.slots.render('title'),
11
11
  description = await Astro.slots.render('description'),
12
- callToAction,
12
+ callToAction = await Astro.slots.render('actions'),
13
13
  as = 'article',
14
14
  asHeader = 'h3',
15
15
  icon,
@@ -23,6 +23,7 @@ const {
23
23
  title: titleClass = '',
24
24
  description: descriptionClass = '',
25
25
  icon: iconClass = '',
26
+ action: actionClass = '',
26
27
  } = classes;
27
28
  ---
28
29
 
@@ -48,10 +49,31 @@ const {
48
49
  )
49
50
  }
50
51
  </div>
52
+
51
53
  {
52
54
  callToAction && (
53
- <div class={cn('w-full', classes?.action)}>
54
- <Button {...callToAction} />
55
+ <div>
56
+ <slot name="footer" />
57
+
58
+ {Array.isArray(callToAction) ? (
59
+ <div class={cn('flex gap-2', actionClass)}>
60
+ {callToAction.map((action) => (
61
+ <Fragment>
62
+ {typeof action === 'string' ? <Fragment set:html={action} /> : <Button {...(action || {})} />}
63
+ </Fragment>
64
+ ))}
65
+ </div>
66
+ ) : (
67
+ <Fragment>
68
+ {typeof callToAction === 'string' ? (
69
+ <Fragment set:html={callToAction} />
70
+ ) : (
71
+ <div class={cn('', actionClass)}>
72
+ <Button {...(callToAction as Object)} />
73
+ </div>
74
+ )}
75
+ </Fragment>
76
+ )}
55
77
  </div>
56
78
  )
57
79
  }
@@ -7,5 +7,5 @@ export type Card4Props = {
7
7
  title?: string;
8
8
  description?: string;
9
9
  icon?: string;
10
- callToAction?: ToAction;
10
+ callToAction?: string | ToAction | Array<string | ToAction>;
11
11
  } & Card0Props;
@@ -10,11 +10,11 @@ import { cn } from '../../utils';
10
10
  const {
11
11
  title = await Astro.slots.render('title'),
12
12
  description = await Astro.slots.render('description'),
13
- callToAction,
13
+ callToAction = await Astro.slots.render('actions'),
14
14
  as = 'article',
15
15
  asHeader = 'h3',
16
16
  icon,
17
- image,
17
+ image = await Astro.slots.render('image'),
18
18
  author,
19
19
  authorDescription,
20
20
 
@@ -21,10 +21,12 @@ const img = {
21
21
  };
22
22
 
23
23
  const {
24
- container: containerClass = 'h-96',
24
+ container: containerClass = 'bg-zinc-700 text-zinc-200 h-96',
25
25
  image: imageClass = '',
26
+ content: contentClass = '',
26
27
  title: titleClass = '',
27
28
  description: descriptionClass = '',
29
+ action: actionClass = 'w-full',
28
30
  } = classes;
29
31
 
30
32
  const WrapperHeaderTag = asHeader;
@@ -32,13 +34,13 @@ const WrapperHeaderTag = asHeader;
32
34
 
33
35
  <div
34
36
  class={twMerge(
35
- 'swiper-slide overflow-hidden bg-zinc-700 text-zinc-200 dark:bg-card dark:text-card-foreground',
37
+ 'swiper-slide overflow-hidden dark:bg-card dark:text-card-foreground',
36
38
  containerClass
37
39
  )}
38
40
  >
39
41
  <div class="slide flex flex-col-reverse justify-between md:flex-row h-full">
40
42
  <div class="w-full flex items-center justify-center">
41
- <div class="p-6 md:px-12 lg:px-20 xl:px-24 w-full h-full md:h-auto">
43
+ <div class={twMerge("p-6 md:px-12 lg:px-20 xl:px-24 w-full h-full md:h-auto", contentClass)}>
42
44
  <slot />
43
45
  {
44
46
  title && description && (
@@ -46,7 +48,7 @@ const WrapperHeaderTag = asHeader;
46
48
  <div class="mb-6">
47
49
  <WrapperHeaderTag
48
50
  class={twMerge(
49
- 'text-white text-base md:text-lg xl:text-2xl font-medium md:font-semibold mb-2',
51
+ 'text-base md:text-lg xl:text-2xl font-medium md:font-semibold mb-2',
50
52
  titleClass
51
53
  )}
52
54
  >
@@ -56,7 +58,7 @@ const WrapperHeaderTag = asHeader;
56
58
  </div>
57
59
  {callToAction && (
58
60
  <Button
59
- class={twMerge('transition hover:translate-y-0.5 w-full', callToAction?.class)}
61
+ class={twMerge('transition hover:translate-y-0.5 w-full', actionClass)}
60
62
  {...callToAction}
61
63
  />
62
64
  )}
@@ -33,7 +33,7 @@ const Component = via;
33
33
  id={id}
34
34
  isDark={isDark}
35
35
  bg={bg}
36
- containerClass={`${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : 'px-0 md:px-6 py-6 md:py-8 lg:py-8'} ${classes?.container}`}
36
+ containerClass={`${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : ''} ${classes?.container}`}
37
37
  >
38
38
  <Headline title={title} subtitle={subtitle} tagline={tagline} classes={classes?.headline as Record<string, string>} />
39
39
 
@@ -2,12 +2,15 @@
2
2
  import type { WidgetFeatures0Props as Props } from './types';
3
3
  import WidgetWrapper from '../WidgetWrapper/WidgetWrapper.astro';
4
4
  import Headline from '../Headline/Headline.astro';
5
+ import Button from '../Button/Button.astro';
6
+ import Image from '../Image/Image.astro';
5
7
 
6
8
  const {
7
9
  title = await Astro.slots.render('title'),
8
10
  subtitle = await Astro.slots.render('subtitle'),
9
11
  tagline = await Astro.slots.render('tagline'),
10
12
  isAfterContent = false,
13
+ callToAction = await Astro.slots.render('actions'),
11
14
 
12
15
  id,
13
16
  isDark = false,
@@ -24,4 +27,34 @@ const {
24
27
  >
25
28
  <Headline title={title} subtitle={subtitle} tagline={tagline} classes={classes?.headline as Record<string, string>} />
26
29
  <slot />
30
+
31
+ {
32
+ callToAction && (
33
+ <div class="max-w-xs sm:max-w-md m-auto flex flex-nowrap flex-col sm:flex-row sm:justify-center gap-4 mt-6">
34
+ {Array.isArray(callToAction) ? (
35
+ callToAction.map((action) => (
36
+ <Fragment>
37
+ {typeof action === 'string' ? (
38
+ <Fragment set:html={action} />
39
+ ) : (
40
+ <div class="flex w-full sm:w-auto">
41
+ <Button {...(action || {})} class="w-full sm:mb-0" />
42
+ </div>
43
+ )}
44
+ </Fragment>
45
+ ))
46
+ ) : (
47
+ <Fragment>
48
+ {typeof callToAction === 'string' ? (
49
+ <Fragment set:html={callToAction} />
50
+ ) : (
51
+ <div class="flex w-full sm:w-auto">
52
+ <Button {...(callToAction || {})} class="w-full sm:mb-0" />
53
+ </div>
54
+ )}
55
+ </Fragment>
56
+ )}
57
+ </div>
58
+ )
59
+ }
27
60
  </WidgetWrapper>
@@ -1,8 +1,10 @@
1
1
  import type { HeadlineProps } from '../Headline/types';
2
2
  import type { WidgetWrapperProps } from '../WidgetWrapper/types.ts';
3
+ import type { ToAction } from '~/types';
3
4
 
4
5
  export type WidgetFeatures0Props = {
5
6
  isBeforeContent?: boolean;
6
7
  isAfterContent?: boolean;
8
+ callToAction?: string | ToAction | Array<string | ToAction>;
7
9
  } & WidgetWrapperProps &
8
10
  Omit<HeadlineProps, 'classes'>;
@@ -5,7 +5,6 @@ import WidgetWrapper from '../WidgetWrapper/WidgetWrapper.astro';
5
5
  import Headline from '../Headline/Headline.astro';
6
6
  import ItemGrid0 from '../ItemGrid0/ItemGrid0.astro';
7
7
  import Image from '../Image/Image.astro';
8
- import { twMerge } from 'tailwind-merge';
9
8
  import { cn } from '../../utils';
10
9
 
11
10
  const {
@@ -6,5 +6,4 @@ export type WidgetFeaturesCardProps = {
6
6
  items?: any[];
7
7
  columns?: number;
8
8
  image?: Image | string;
9
- isAfterContent?: boolean;
10
9
  } & WidgetFeatures0Props;
@@ -114,7 +114,7 @@ const {
114
114
  id={id}
115
115
  isDark={isDark}
116
116
  bg={bg}
117
- containerClass={`${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : 'px-0 md:px-6 py-6 md:py-8 lg:py-8'} ${classes?.container}`}
117
+ containerClass={`${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : ''} ${classes?.container}`}
118
118
  >
119
119
  <div class="relative md:rounded-xl overflow-hidden group">
120
120
  <swiper-container
@@ -3,6 +3,7 @@ import type { WidgetStepsTimelineProps as Props } from './types';
3
3
  import WidgetWrapper from '../WidgetWrapper/WidgetWrapper.astro';
4
4
  import Headline from '../Headline/Headline.astro';
5
5
  import Timeline from '../Timeline/Timeline.astro';
6
+ import Image from '../Image/Image.astro';
6
7
 
7
8
  const {
8
9
  title = await Astro.slots.render('title'),
@@ -4,8 +4,8 @@ import Headline from '../Headline/Headline.astro';
4
4
  import WidgetWrapper from '../WidgetWrapper/WidgetWrapper.astro';
5
5
  import SwiperSlider from '../SwiperSlider/SwiperSlider.astro';
6
6
  import { Image as AstroImage, getImage } from 'astro:assets';
7
- import {fetchLocalImages} from "../../utils/images";
8
- import Image from "../Image/Image.astro";
7
+ import { fetchLocalImages } from '../../utils/images';
8
+ import Image from '../Image/Image.astro';
9
9
 
10
10
  const {
11
11
  title = await Astro.slots.render('title'),
@@ -26,15 +26,13 @@ const images = await fetchLocalImages();
26
26
  const imagePaths = Object.keys(images).filter((imagePath) => {
27
27
  return imagePath.startsWith(`/src/assets/images/${imagesFolder}/`);
28
28
  });
29
-
30
-
31
29
  ---
32
30
 
33
31
  <WidgetWrapper
34
32
  id={id}
35
33
  isDark={isDark}
36
34
  bg={bg}
37
- containerClass={`gallery ${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : 'px-0 md:px-6 py-6 md:py-8 lg:py-8'} ${classes?.container}`}
35
+ containerClass={`gallery ${isAfterContent ? 'pt-0 md:pt-0 lg:pt-0' : ''} ${classes?.container}`}
38
36
  >
39
37
  <Headline title={title} subtitle={subtitle} tagline={tagline} classes={classes?.headline as Record<string, string>} />
40
38
 
@@ -64,7 +62,7 @@ const imagePaths = Object.keys(images).filter((imagePath) => {
64
62
  width={400}
65
63
  height={400}
66
64
  sizes="(max-width: 900px) 400px, 900px"
67
- class="w-full md:h-full group-hover:scale-105 transition duration-300"
65
+ class="aspect-square w-full md:h-full group-hover:scale-105 transition duration-300"
68
66
  />
69
67
  </a>
70
68
  </swiper-slide>
@@ -76,13 +74,13 @@ const imagePaths = Object.keys(images).filter((imagePath) => {
76
74
  </WidgetWrapper>
77
75
 
78
76
  <script>
79
- import PhotoSwipeLightbox from "photoswipe/lightbox";
80
- import "photoswipe/style.css";
77
+ import PhotoSwipeLightbox from 'photoswipe/lightbox';
78
+ import 'photoswipe/style.css';
81
79
 
82
80
  const lightbox = new PhotoSwipeLightbox({
83
- gallery: ".gallery",
84
- children: "a",
85
- pswpModule: () => import("photoswipe"),
81
+ gallery: '.gallery',
82
+ children: 'a',
83
+ pswpModule: () => import('photoswipe'),
86
84
  });
87
85
 
88
86
  lightbox.init();
package/index.js CHANGED
@@ -4,4 +4,5 @@ export * from './utils/id.ts'
4
4
  export * from './utils/images-optimization.ts'
5
5
  export * from './utils/images.ts'
6
6
  export * from './utils/index.ts'
7
+ export * from './utils/slugify.ts'
7
8
  export * from './utils/utils.ts'
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yatoday/astro-ui",
3
3
  "type": "module",
4
- "version": "0.6.0",
4
+ "version": "0.6.10",
5
5
  "scripts": {
6
6
  "prepare": "husky",
7
7
  "pre-commit": "lint-staged",
@@ -23,7 +23,6 @@
23
23
  "create-component": "node scripts/createComponent.js"
24
24
  },
25
25
  "dependencies": {
26
- "limax": "4.1.0",
27
26
  "lodash.merge": "^4.6.2",
28
27
  "photoswipe": "^5.4.4",
29
28
  "swiper": "^11.2.5",
package/styles/styles.css CHANGED
@@ -2264,11 +2264,6 @@
2264
2264
  padding-block: calc(var(--spacing) * 6);
2265
2265
  }
2266
2266
  }
2267
- .lg\:py-8 {
2268
- @media (width >= 64rem) {
2269
- padding-block: calc(var(--spacing) * 8);
2270
- }
2271
- }
2272
2267
  .lg\:py-20 {
2273
2268
  @media (width >= 64rem) {
2274
2269
  padding-block: calc(var(--spacing) * 20);
package/utils/URLUtils.ts CHANGED
@@ -1,4 +1,4 @@
1
- import slug from 'limax';
1
+ import slugify from '../utils/slugify';
2
2
  import { trim } from './utils';
3
3
 
4
4
  /**
@@ -39,7 +39,7 @@ export const createPath = (...params: string[]): string => {
39
39
  export const cleanSlug = (text: string = ''): string =>
40
40
  trimSlash(text)
41
41
  .split('/')
42
- .map((a: string) => slug(a))
42
+ .map((a: string) => slugify(a))
43
43
  .join('/');
44
44
 
45
45
  /**
@@ -0,0 +1,82 @@
1
+ interface Options {
2
+ replacement?: string;
3
+ remove?: RegExp;
4
+ lower?: boolean;
5
+ strict?: boolean;
6
+ trim?: boolean;
7
+ locale?: string;
8
+ }
9
+
10
+ interface LocaleMap {
11
+ [key: string]: string;
12
+ }
13
+
14
+ interface CharMap {
15
+ [key: string]: string;
16
+ }
17
+
18
+ const charMap: CharMap = JSON.parse(
19
+ '{"$":"dollar","%":"percent","&":"and","<":"less",">":"greater","|":"or","¢":"cent","£":"pound","¤":"currency","¥":"yen","©":"(c)","ª":"a","®":"(r)","º":"o","À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Æ":"AE","Ç":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","Þ":"TH","ß":"ss","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","æ":"ae","ç":"c","è":"e","é":"e","ê":"e","ë":"e","ì":"i","í":"i","î":"i","ï":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","þ":"th","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Č":"C","č":"c","Ď":"D","ď":"d","Đ":"DJ","đ":"dj","Ē":"E","ē":"e","Ė":"E","ė":"e","Ę":"e","ę":"e","Ě":"E","ě":"e","Ğ":"G","ğ":"g","Ģ":"G","ģ":"g","Ĩ":"I","ĩ":"i","Ī":"i","ī":"i","Į":"I","į":"i","İ":"I","ı":"i","Ķ":"k","ķ":"k","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ł":"L","ł":"l","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","Ō":"O","ō":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","Ŕ":"R","ŕ":"r","Ř":"R","ř":"r","Ś":"S","ś":"s","Ş":"S","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","Ť":"T","ť":"t","Ũ":"U","ũ":"u","Ū":"u","ū":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","Ə":"E","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Lj":"LJ","lj":"lj","Nj":"NJ","nj":"nj","Ș":"S","ș":"s","Ț":"T","ț":"t","ə":"e","˚":"o","Ά":"A","Έ":"E","Ή":"H","Ί":"I","Ό":"O","Ύ":"Y","Ώ":"W","ΐ":"i","Α":"A","Β":"B","Γ":"G","Δ":"D","Ε":"E","Ζ":"Z","Η":"H","Θ":"8","Ι":"I","Κ":"K","Λ":"L","Μ":"M","Ν":"N","Ξ":"3","Ο":"O","Π":"P","Ρ":"R","Σ":"S","Τ":"T","Υ":"Y","Φ":"F","Χ":"X","Ψ":"PS","Ω":"W","Ϊ":"I","Ϋ":"Y","ά":"a","έ":"e","ή":"h","ί":"i","ΰ":"y","α":"a","β":"b","γ":"g","δ":"d","ε":"e","ζ":"z","η":"h","θ":"8","ι":"i","κ":"k","λ":"l","μ":"m","ν":"n","ξ":"3","ο":"o","π":"p","ρ":"r","ς":"s","σ":"s","τ":"t","υ":"y","φ":"f","χ":"x","ψ":"ps","ω":"w","ϊ":"i","ϋ":"y","ό":"o","ύ":"y","ώ":"w","Ё":"Yo","Ђ":"DJ","Є":"Ye","І":"I","Ї":"Yi","Ј":"J","Љ":"LJ","Њ":"NJ","Ћ":"C","Џ":"DZ","А":"A","Б":"B","В":"V","Г":"G","Д":"D","Е":"E","Ж":"Zh","З":"Z","И":"I","Й":"J","К":"K","Л":"L","М":"M","Н":"N","О":"O","П":"P","Р":"R","С":"S","Т":"T","У":"U","Ф":"F","Х":"H","Ц":"C","Ч":"Ch","Ш":"Sh","Щ":"Sh","Ъ":"U","Ы":"Y","Ь":"","Э":"E","Ю":"Yu","Я":"Ya","а":"a","б":"b","в":"v","г":"g","д":"d","е":"e","ж":"zh","з":"z","и":"i","й":"j","к":"k","л":"l","м":"m","н":"n","о":"o","п":"p","р":"r","с":"s","т":"t","у":"u","ф":"f","х":"h","ц":"c","ч":"ch","ш":"sh","щ":"sh","ъ":"u","ы":"y","ь":"","э":"e","ю":"yu","я":"ya","ё":"yo","ђ":"dj","є":"ye","і":"i","ї":"yi","ј":"j","љ":"lj","њ":"nj","ћ":"c","ѝ":"u","џ":"dz","Ґ":"G","ґ":"g","Ғ":"GH","ғ":"gh","Қ":"KH","қ":"kh","Ң":"NG","ң":"ng","Ү":"UE","ү":"ue","Ұ":"U","ұ":"u","Һ":"H","һ":"h","Ә":"AE","ә":"ae","Ө":"OE","ө":"oe","Ա":"A","Բ":"B","Գ":"G","Դ":"D","Ե":"E","Զ":"Z","Է":"E\'","Ը":"Y\'","Թ":"T\'","Ժ":"JH","Ի":"I","Լ":"L","Խ":"X","Ծ":"C\'","Կ":"K","Հ":"H","Ձ":"D\'","Ղ":"GH","Ճ":"TW","Մ":"M","Յ":"Y","Ն":"N","Շ":"SH","Չ":"CH","Պ":"P","Ջ":"J","Ռ":"R\'","Ս":"S","Վ":"V","Տ":"T","Ր":"R","Ց":"C","Փ":"P\'","Ք":"Q\'","Օ":"O\'\'","Ֆ":"F","և":"EV","ء":"a","آ":"aa","أ":"a","ؤ":"u","إ":"i","ئ":"e","ا":"a","ب":"b","ة":"h","ت":"t","ث":"th","ج":"j","ح":"h","خ":"kh","د":"d","ذ":"th","ر":"r","ز":"z","س":"s","ش":"sh","ص":"s","ض":"dh","ط":"t","ظ":"z","ع":"a","غ":"gh","ف":"f","ق":"q","ك":"k","ل":"l","م":"m","ن":"n","ه":"h","و":"w","ى":"a","ي":"y","ً":"an","ٌ":"on","ٍ":"en","َ":"a","ُ":"u","ِ":"e","ْ":"","٠":"0","١":"1","٢":"2","٣":"3","٤":"4","٥":"5","٦":"6","٧":"7","٨":"8","٩":"9","پ":"p","چ":"ch","ژ":"zh","ک":"k","گ":"g","ی":"y","۰":"0","۱":"1","۲":"2","۳":"3","۴":"4","۵":"5","۶":"6","۷":"7","۸":"8","۹":"9","฿":"baht","ა":"a","ბ":"b","გ":"g","დ":"d","ე":"e","ვ":"v","ზ":"z","თ":"t","ი":"i","კ":"k","ლ":"l","მ":"m","ნ":"n","ო":"o","პ":"p","ჟ":"zh","რ":"r","ს":"s","ტ":"t","უ":"u","ფ":"f","ქ":"k","ღ":"gh","ყ":"q","შ":"sh","ჩ":"ch","ც":"ts","ძ":"dz","წ":"ts","ჭ":"ch","ხ":"kh","ჯ":"j","ჰ":"h","Ṣ":"S","ṣ":"s","Ẁ":"W","ẁ":"w","Ẃ":"W","ẃ":"w","Ẅ":"W","ẅ":"w","ẞ":"SS","Ạ":"A","ạ":"a","Ả":"A","ả":"a","Ấ":"A","ấ":"a","Ầ":"A","ầ":"a","Ẩ":"A","ẩ":"a","Ẫ":"A","ẫ":"a","Ậ":"A","ậ":"a","Ắ":"A","ắ":"a","Ằ":"A","ằ":"a","Ẳ":"A","ẳ":"a","Ẵ":"A","ẵ":"a","Ặ":"A","ặ":"a","Ẹ":"E","ẹ":"e","Ẻ":"E","ẻ":"e","Ẽ":"E","ẽ":"e","Ế":"E","ế":"e","Ề":"E","ề":"e","Ể":"E","ể":"e","Ễ":"E","ễ":"e","Ệ":"E","ệ":"e","Ỉ":"I","ỉ":"i","Ị":"I","ị":"i","Ọ":"O","ọ":"o","Ỏ":"O","ỏ":"o","Ố":"O","ố":"o","Ồ":"O","ồ":"o","Ổ":"O","ổ":"o","Ỗ":"O","ỗ":"o","Ộ":"O","ộ":"o","Ớ":"O","ớ":"o","Ờ":"O","ờ":"o","Ở":"O","ở":"o","Ỡ":"O","ỡ":"o","Ợ":"O","ợ":"o","Ụ":"U","ụ":"u","Ủ":"U","ủ":"u","Ứ":"U","ứ":"u","Ừ":"U","ừ":"u","Ử":"U","ử":"u","Ữ":"U","ữ":"u","Ự":"U","ự":"u","Ỳ":"Y","ỳ":"y","Ỵ":"Y","ỵ":"y","Ỷ":"Y","ỷ":"y","Ỹ":"Y","ỹ":"y","–":"-","‘":"\'","’":"\'","“":"\\\"","”":"\\\"","„":"\\\"","†":"+","•":"*","…":"...","₠":"ecu","₢":"cruzeiro","₣":"french franc","₤":"lira","₥":"mill","₦":"naira","₧":"peseta","₨":"rupee","₩":"won","₪":"new shequel","₫":"dong","€":"euro","₭":"kip","₮":"tugrik","₯":"drachma","₰":"penny","₱":"peso","₲":"guarani","₳":"austral","₴":"hryvnia","₵":"cedi","₸":"kazakhstani tenge","₹":"indian rupee","₺":"turkish lira","₽":"russian ruble","₿":"bitcoin","℠":"sm","™":"tm","∂":"d","∆":"delta","∑":"sum","∞":"infinity","♥":"love","元":"yuan","円":"yen","﷼":"rial","ﻵ":"laa","ﻷ":"laa","ﻹ":"lai","ﻻ":"la"}'
20
+ );
21
+
22
+ const locales: Record<string, LocaleMap> = JSON.parse(
23
+ '{"bg":{"Й":"Y","Ц":"Ts","Щ":"Sht","Ъ":"A","Ь":"Y","й":"y","ц":"ts","щ":"sht","ъ":"a","ь":"y"},"de":{"Ä":"AE","ä":"ae","Ö":"OE","ö":"oe","Ü":"UE","ü":"ue","ß":"ss","%":"prozent","&":"und","|":"oder","∑":"summe","∞":"unendlich","♥":"liebe"},"es":{"%":"por ciento","&":"y","<":"menor que",">":"mayor que","|":"o","¢":"centavos","£":"libras","¤":"moneda","₣":"francos","∑":"suma","∞":"infinito","♥":"amor"},"fr":{"%":"pourcent","&":"et","<":"plus petit",">":"plus grand","|":"ou","¢":"centime","£":"livre","¤":"devise","₣":"franc","∑":"somme","∞":"infini","♥":"amour"},"pt":{"%":"porcento","&":"e","<":"menor",">":"maior","|":"ou","¢":"centavo","∑":"soma","£":"libra","∞":"infinito","♥":"amor"},"uk":{"И":"Y","и":"y","Й":"Y","й":"y","Ц":"Ts","ц":"ts","Х":"Kh","х":"kh","Щ":"Shch","щ":"shch","Г":"H","г":"h"},"vi":{"Đ":"D","đ":"d"},"da":{"Ø":"OE","ø":"oe","Å":"AA","å":"aa","%":"procent","&":"og","|":"eller","$":"dollar","<":"mindre end",">":"større end"},"nb":{"&":"og","Å":"AA","Æ":"AE","Ø":"OE","å":"aa","æ":"ae","ø":"oe"},"it":{"&":"e"},"nl":{"&":"en"},"sv":{"&":"och","Å":"AA","Ä":"AE","Ö":"OE","å":"aa","ä":"ae","ö":"oe"}}'
24
+ );
25
+
26
+ function replace(string: string, options?: string | Options): string {
27
+ if (typeof string !== 'string') {
28
+ throw new Error('slugify: string argument expected');
29
+ }
30
+
31
+ const resolvedOptions: Options =
32
+ typeof options === 'string' ? { replacement: options } : options || {};
33
+
34
+ const locale: LocaleMap = locales[resolvedOptions.locale || ''] || {};
35
+ const replacement: string = resolvedOptions.replacement === undefined ? '-' : resolvedOptions.replacement;
36
+ const trim: boolean = resolvedOptions.trim === undefined ? true : resolvedOptions.trim;
37
+
38
+ // Define a regular expression to remove single and double quotes
39
+ const quotesAndSpecialCharsToRemove = /['"]+/g;
40
+
41
+ let slug = string
42
+ .normalize()
43
+ .replace(quotesAndSpecialCharsToRemove, '') // Remove quotes
44
+ .split('')
45
+ .reduce((result, ch) => {
46
+ let appendChar: string | undefined = locale[ch];
47
+ if (appendChar === undefined) appendChar = charMap[ch];
48
+ if (appendChar === undefined) appendChar = ch;
49
+ if (appendChar === replacement) appendChar = ' ';
50
+ return result + appendChar;
51
+ }, '')
52
+ .replace(resolvedOptions.remove || /[^\w\s$*_+~.()'"!\-:@]+/g, '');
53
+
54
+ if (resolvedOptions.strict) {
55
+ slug = slug.replace(/[^A-Za-z0-9\s]/g, '');
56
+ }
57
+
58
+ if (trim) {
59
+ slug = slug.trim();
60
+ }
61
+
62
+ slug = slug.replace(/\s+/g, replacement);
63
+
64
+ if (resolvedOptions.lower) {
65
+ slug = slug.toLowerCase();
66
+ }
67
+
68
+ return slug;
69
+ }
70
+
71
+ replace.extend = (customMap: CharMap): void => {
72
+ Object.assign(charMap, customMap);
73
+ };
74
+
75
+ // Export as a module
76
+ export default replace;
77
+
78
+ // For CommonJS compatibility (as in the original code)
79
+ if (typeof exports === 'object') {
80
+ module.exports = replace;
81
+ module.exports.default = replace;
82
+ }