@windstream/react-shared-components 0.1.60 → 0.1.63

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.
package/dist/index.d.ts CHANGED
@@ -346,7 +346,7 @@ type ButtonAsAnchor = ButtonCustomProps & Omit<AnchorHTMLAttributes<HTMLAnchorEl
346
346
  };
347
347
  type ButtonProps = ButtonAsButton | ButtonAsAnchor;
348
348
 
349
- declare const BrandButton: React__default.ForwardRefExoticComponent<ButtonProps$2 & React__default.RefAttributes<HTMLButtonElement | HTMLAnchorElement>>;
349
+ declare const BrandButton: React__default.ForwardRefExoticComponent<ButtonProps$2 & React__default.RefAttributes<HTMLAnchorElement | HTMLButtonElement>>;
350
350
 
351
351
  declare const Checklist: React__default.FC<ChecklistProps>;
352
352
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windstream/react-shared-components",
3
- "version": "0.1.60",
3
+ "version": "0.1.63",
4
4
  "type": "module",
5
5
  "description": "Shared React components for Kinetic applications",
6
6
  "main": "dist/index.js",
@@ -78,23 +78,14 @@ function buildPageItems(current: number, total: number): (number | "...")[] {
78
78
  if (total <= 7) {
79
79
  return Array.from({ length: total }, (_, i) => i + 1);
80
80
  }
81
- const items: (number | "...")[] = [];
82
- items.push(1);
83
81
 
84
- if (current > 3) {
85
- items.push("...");
82
+ if (current <= 4) {
83
+ return [1, 2, 3, 4, 5, "...", total];
86
84
  }
87
- const rangeStart = Math.max(2, current - 1);
88
- const rangeEnd = Math.min(total - 1, current + 1);
89
85
 
90
- for (let i = rangeStart; i <= rangeEnd; i++) {
91
- items.push(i);
86
+ if (current >= total - 3) {
87
+ return [1, "...", total - 4, total - 3, total - 2, total - 1, total];
92
88
  }
93
89
 
94
- if (current < total - 2) {
95
- items.push("...");
96
- }
97
-
98
- items.push(total);
99
- return items;
90
+ return [1, "...", current - 1, current, current + 1, "...", total];
100
91
  }
@@ -6,6 +6,7 @@ import { Text } from "@shared/components/text";
6
6
  import { BlogCard } from "@shared/contentful/blocks/cards/blog-card";
7
7
 
8
8
  export function BlogGridBase({
9
+ title = "recent articles",
9
10
  paginatedArticles,
10
11
  totalArticles,
11
12
  currentPage,
@@ -14,6 +15,7 @@ export function BlogGridBase({
14
15
  categoryOptions,
15
16
  onCategoryChange,
16
17
  onPageChange,
18
+ imageComponent,
17
19
  }: BlogGridBaseProps) {
18
20
  function handleCategoryChange(value: unknown) {
19
21
  if (!value || Array.isArray(value)) return;
@@ -34,31 +36,33 @@ export function BlogGridBase({
34
36
  {/* Controls bar */}
35
37
  <div className="mx-auto flex max-w-[1200px] flex-wrap items-center justify-between gap-3 px-6 pb-6">
36
38
  <Text className="w-full text-center text-heading5 font-black lowercase text-text-secondary md:w-auto md:text-left">
37
- recent articles
39
+ {title}
38
40
  </Text>
39
41
 
40
- <div className="flex w-full flex-col-reverse gap-3 md:w-auto md:flex-row md:items-center md:gap-6">
41
- {/* Showing count */}
42
- <Text className="whitespace-nowrap text-center text-label3 font-bold text-text-info md:text-right md:text-label2">
43
- <Text as="span" className="hidden md:block">
44
- showing
45
- </Text>
46
- <strong className="block text-nowrap font-bold text-text-info">
47
- <Text as="span" className="md:hidden">
48
- showing{" "}
42
+ {categoryOptions.length > 0 && (
43
+ <div className="flex w-full flex-col-reverse gap-3 md:w-auto md:flex-row md:items-center md:gap-6">
44
+ {/* Showing count */}
45
+ <Text className="whitespace-nowrap text-center text-label3 font-bold text-text-info md:text-right md:text-label2">
46
+ <Text as="span" className="hidden md:block">
47
+ showing
49
48
  </Text>
50
- {paginatedArticles.length} of {totalArticles} articles
51
- </strong>
52
- </Text>
49
+ <strong className="block text-nowrap font-bold text-text-info">
50
+ <Text as="span" className="md:hidden">
51
+ showing{" "}
52
+ </Text>
53
+ {paginatedArticles.length} of {totalArticles} articles
54
+ </strong>
55
+ </Text>
53
56
 
54
- {/* Filter dropdown */}
55
- <Select
56
- options={categoryOptions}
57
- value={selectedCategory}
58
- onChange={handleCategoryChange}
59
- className="w-full md:w-[280px]"
60
- />
61
- </div>
57
+ {/* Filter dropdown */}
58
+ <Select
59
+ options={categoryOptions}
60
+ value={selectedCategory}
61
+ onChange={handleCategoryChange}
62
+ className="w-full md:w-[280px]"
63
+ />
64
+ </div>
65
+ )}
62
66
  </div>
63
67
 
64
68
  {/* Articles grid */}
@@ -89,6 +93,7 @@ export function BlogGridBase({
89
93
  date={article.blogCreationDate}
90
94
  category={article.category}
91
95
  image={coverImage}
96
+ imageComponent={imageComponent}
92
97
  index={index}
93
98
  />
94
99
  );
@@ -1,3 +1,6 @@
1
+ import React from "react";
2
+ import { BlogCardImageProps } from "@shared/contentful/blocks/cards/blog-card/types";
3
+
1
4
  export interface BlogCardProps {
2
5
  slug: string;
3
6
  title?: string;
@@ -13,6 +16,7 @@ export interface BlogCardProps {
13
16
  }
14
17
 
15
18
  export interface BlogGridBaseProps {
19
+ title?: string;
16
20
  paginatedArticles: BlogCardProps[];
17
21
  totalArticles: number;
18
22
  currentPage: number;
@@ -21,6 +25,8 @@ export interface BlogGridBaseProps {
21
25
  categoryOptions: BlogCategoryOption[];
22
26
  onCategoryChange?: (category: BlogCategoryOption) => void;
23
27
  onPageChange?: (page: number) => void;
28
+ /** Pass next/image's Image component here to enable image optimization */
29
+ imageComponent?: React.ComponentType<BlogCardImageProps>;
24
30
  }
25
31
 
26
32
  export interface BlogCategoryOption {
@@ -20,6 +20,7 @@ export const BlogCard: React.FC<BlogCardProps> = ({
20
20
  date,
21
21
  category,
22
22
  image,
23
+ imageComponent: ImageComponent,
23
24
  readMoreText = "Read more",
24
25
  asGrid = true,
25
26
  lgWidth,
@@ -41,15 +42,26 @@ export const BlogCard: React.FC<BlogCardProps> = ({
41
42
  <Link href={href} tabIndex={-1} aria-hidden="true" className="block">
42
43
  <div className="h-[232px] w-full flex-shrink-0 overflow-hidden bg-gray-100">
43
44
  {image ? (
44
- <img
45
- src={image.src}
46
- alt={image.alt}
47
- width={image.width}
48
- height={image.height}
49
- loading="lazy"
50
- decoding="async"
51
- className="h-full w-full object-cover transition-transform duration-300 hover:scale-[1.03]"
52
- />
45
+ ImageComponent ? (
46
+ <ImageComponent
47
+ src={image.src}
48
+ alt={image.alt}
49
+ width={image.width}
50
+ height={image.height}
51
+ className="h-full w-full object-cover transition-transform duration-300 hover:scale-[1.03]"
52
+ sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
53
+ />
54
+ ) : (
55
+ <img
56
+ src={image.src}
57
+ alt={image.alt}
58
+ width={image.width}
59
+ height={image.height}
60
+ loading="lazy"
61
+ decoding="async"
62
+ className="h-full w-full object-cover transition-transform duration-300 hover:scale-[1.03]"
63
+ />
64
+ )
53
65
  ) : (
54
66
  <div
55
67
  className="h-full w-full bg-gradient-to-br from-gray-200 to-gray-100"
@@ -1,3 +1,17 @@
1
+ import React from "react";
2
+
3
+ export interface BlogCardImageProps {
4
+ src: string;
5
+ alt: string;
6
+ width: number;
7
+ height: number;
8
+ className?: string;
9
+ sizes?: string;
10
+ loading?: "lazy" | "eager";
11
+ decoding?: "async" | "auto" | "sync";
12
+ [key: string]: unknown;
13
+ }
14
+
1
15
  export interface BlogCardProps {
2
16
  href: string;
3
17
  title?: string;
@@ -10,6 +24,8 @@ export interface BlogCardProps {
10
24
  width: number;
11
25
  height: number;
12
26
  };
27
+ /** Pass next/image's Image component here to enable image optimization */
28
+ imageComponent?: React.ComponentType<BlogCardImageProps>;
13
29
  readMoreText?: string;
14
30
  asGrid?: boolean;
15
31
  lgWidth?: string;