@digital-b2c/coreui-kit 0.9.0 → 0.10.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.
- package/LICENSE.txt +21 -21
- package/README.md +52 -52
- package/dist/index.cjs +245 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +49 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.mjs +245 -52
- package/dist/index.mjs.map +1 -1
- package/dist/types/global.d.ts +25 -25
- package/package.json +100 -99
package/LICENSE.txt
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Luxottica
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Luxottica
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
# CoreUI Kit
|
|
2
|
-
|
|
3
|
-
A React‑based design system and component library.
|
|
4
|
-
|
|
5
|
-
## 🚀 Getting Started
|
|
6
|
-
|
|
7
|
-
Install
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
Development
|
|
14
|
-
|
|
15
|
-
- Run the build in watch mode
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
npm run dev
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Start Storybook
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
npm run storybook
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Run tests
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm test
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
Lint/format
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
npm run lint
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
## 🛠️ Usage
|
|
40
|
-
|
|
41
|
-
Import components in other projects:
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
import '@digital-b2c/coreui-kit/styles.css'
|
|
45
|
-
|
|
46
|
-
import { MiniSectionCta } from '@digital-b2c/coreui-kit'
|
|
47
|
-
|
|
48
|
-
<MiniSectionCta>
|
|
49
|
-
<MiniSectionCta.Title>Header</MiniSectionCta.Title>
|
|
50
|
-
<MiniSectionCta.Subtitle>Description</MiniSectionCta.Subtitle>
|
|
51
|
-
</MiniSectionCta>
|
|
52
|
-
```
|
|
1
|
+
# CoreUI Kit
|
|
2
|
+
|
|
3
|
+
A React‑based design system and component library.
|
|
4
|
+
|
|
5
|
+
## 🚀 Getting Started
|
|
6
|
+
|
|
7
|
+
Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Development
|
|
14
|
+
|
|
15
|
+
- Run the build in watch mode
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm run dev
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Start Storybook
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm run storybook
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Run tests
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm test
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Lint/format
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm run lint
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 🛠️ Usage
|
|
40
|
+
|
|
41
|
+
Import components in other projects:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import '@digital-b2c/coreui-kit/styles.css'
|
|
45
|
+
|
|
46
|
+
import { MiniSectionCta } from '@digital-b2c/coreui-kit'
|
|
47
|
+
|
|
48
|
+
<MiniSectionCta>
|
|
49
|
+
<MiniSectionCta.Title>Header</MiniSectionCta.Title>
|
|
50
|
+
<MiniSectionCta.Subtitle>Description</MiniSectionCta.Subtitle>
|
|
51
|
+
</MiniSectionCta>
|
|
52
|
+
```
|
package/dist/index.cjs
CHANGED
|
@@ -2572,7 +2572,9 @@ var ResourcesGridList_module_default = {
|
|
|
2572
2572
|
searchCollapse: "ResourcesGridList_module_searchCollapse",
|
|
2573
2573
|
searchIconInner: "ResourcesGridList_module_searchIconInner",
|
|
2574
2574
|
searchInput: "ResourcesGridList_module_searchInput",
|
|
2575
|
+
searchClear: "ResourcesGridList_module_searchClear",
|
|
2575
2576
|
dropdownPanel: "ResourcesGridList_module_dropdownPanel",
|
|
2577
|
+
searchPanel: "ResourcesGridList_module_searchPanel",
|
|
2576
2578
|
dropdownOption: "ResourcesGridList_module_dropdownOption",
|
|
2577
2579
|
selected: "ResourcesGridList_module_selected",
|
|
2578
2580
|
content: "ResourcesGridList_module_content",
|
|
@@ -2589,6 +2591,7 @@ var ResourcesGridList_module_default = {
|
|
|
2589
2591
|
cardsArea: "ResourcesGridList_module_cardsArea",
|
|
2590
2592
|
grid: "ResourcesGridList_module_grid",
|
|
2591
2593
|
list: "ResourcesGridList_module_list",
|
|
2594
|
+
cardLink: "ResourcesGridList_module_cardLink",
|
|
2592
2595
|
cardGrid: "ResourcesGridList_module_cardGrid",
|
|
2593
2596
|
cardBody: "ResourcesGridList_module_cardBody",
|
|
2594
2597
|
cardIconTitle: "ResourcesGridList_module_cardIconTitle",
|
|
@@ -2622,23 +2625,31 @@ function FilterBar({
|
|
|
2622
2625
|
filterValue,
|
|
2623
2626
|
onFilterChange,
|
|
2624
2627
|
sortValue,
|
|
2625
|
-
onSortChange
|
|
2628
|
+
onSortChange,
|
|
2629
|
+
searchValue,
|
|
2630
|
+
onSearchChange
|
|
2626
2631
|
}) {
|
|
2627
2632
|
const [openDropdown, setOpenDropdown] = React62.useState(null);
|
|
2628
2633
|
const [searchState, setSearchState] = React62.useState("closed");
|
|
2629
|
-
const [searchQuery, setSearchQuery] = React62.useState("");
|
|
2630
2634
|
const filterRef = React62.useRef(null);
|
|
2631
2635
|
const sortRef = React62.useRef(null);
|
|
2636
|
+
const searchRef = React62.useRef(null);
|
|
2632
2637
|
const searchInputRef = React62.useRef(null);
|
|
2633
2638
|
const closeSearch = () => {
|
|
2634
2639
|
setSearchState("closing");
|
|
2635
|
-
|
|
2640
|
+
onSearchChange("");
|
|
2641
|
+
};
|
|
2642
|
+
const clearSearch = () => {
|
|
2643
|
+
var _a;
|
|
2644
|
+
onSearchChange("");
|
|
2645
|
+
(_a = searchInputRef.current) == null ? void 0 : _a.focus();
|
|
2636
2646
|
};
|
|
2637
2647
|
React62.useEffect(() => {
|
|
2638
2648
|
const handleMouseDown = (e) => {
|
|
2639
|
-
var _a, _b;
|
|
2649
|
+
var _a, _b, _c;
|
|
2640
2650
|
const target = e.target;
|
|
2641
|
-
if (((_a = filterRef.current) == null ? void 0 : _a.contains(target)) || ((_b = sortRef.current) == null ? void 0 : _b.contains(target)))
|
|
2651
|
+
if (((_a = filterRef.current) == null ? void 0 : _a.contains(target)) || ((_b = sortRef.current) == null ? void 0 : _b.contains(target)) || ((_c = searchRef.current) == null ? void 0 : _c.contains(target)))
|
|
2652
|
+
return;
|
|
2642
2653
|
setOpenDropdown(null);
|
|
2643
2654
|
};
|
|
2644
2655
|
document.addEventListener("mousedown", handleMouseDown);
|
|
@@ -2648,6 +2659,10 @@ function FilterBar({
|
|
|
2648
2659
|
var _a;
|
|
2649
2660
|
if (searchState === "open") (_a = searchInputRef.current) == null ? void 0 : _a.focus();
|
|
2650
2661
|
}, [searchState]);
|
|
2662
|
+
React62.useEffect(() => {
|
|
2663
|
+
var _a;
|
|
2664
|
+
if (openDropdown === "search") (_a = searchInputRef.current) == null ? void 0 : _a.focus();
|
|
2665
|
+
}, [openDropdown]);
|
|
2651
2666
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.filterBar, children: [
|
|
2652
2667
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.viewToggle, children: [
|
|
2653
2668
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -2747,17 +2762,21 @@ function FilterBar({
|
|
|
2747
2762
|
opt.value
|
|
2748
2763
|
)) })
|
|
2749
2764
|
] }),
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
{
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2765
|
+
isMobile ? (
|
|
2766
|
+
/* Mobile — popup panel, mirroring the Filter/Sort dropdowns */
|
|
2767
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.dropdownWrapper, ref: searchRef, children: [
|
|
2768
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2769
|
+
"button",
|
|
2770
|
+
{
|
|
2771
|
+
type: "button",
|
|
2772
|
+
className: clsx23__default.default(ResourcesGridList_module_default.chip, searchValue !== "" && ResourcesGridList_module_default.active),
|
|
2773
|
+
onClick: () => setOpenDropdown(openDropdown === "search" ? null : "search"),
|
|
2774
|
+
"aria-expanded": openDropdown === "search",
|
|
2775
|
+
"aria-label": "Search",
|
|
2776
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "search", size: 20, "aria-hidden": "true" })
|
|
2777
|
+
}
|
|
2756
2778
|
),
|
|
2757
|
-
|
|
2758
|
-
if (searchState === "closing") setSearchState("closed");
|
|
2759
|
-
},
|
|
2760
|
-
children: [
|
|
2779
|
+
openDropdown === "search" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.searchPanel, children: [
|
|
2761
2780
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.searchIconInner, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "search", size: 20, "aria-hidden": "true" }) }),
|
|
2762
2781
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2763
2782
|
"input",
|
|
@@ -2766,24 +2785,90 @@ function FilterBar({
|
|
|
2766
2785
|
type: "text",
|
|
2767
2786
|
className: ResourcesGridList_module_default.searchInput,
|
|
2768
2787
|
placeholder: "Search\u2026",
|
|
2769
|
-
value:
|
|
2770
|
-
onChange: (e) =>
|
|
2788
|
+
value: searchValue,
|
|
2789
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
2771
2790
|
onKeyDown: (e) => {
|
|
2772
|
-
if (e.key === "Escape")
|
|
2773
|
-
|
|
2774
|
-
|
|
2791
|
+
if (e.key === "Escape") {
|
|
2792
|
+
if (searchValue) clearSearch();
|
|
2793
|
+
else setOpenDropdown(null);
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
),
|
|
2798
|
+
searchValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2799
|
+
"button",
|
|
2800
|
+
{
|
|
2801
|
+
type: "button",
|
|
2802
|
+
className: ResourcesGridList_module_default.searchClear,
|
|
2803
|
+
"aria-label": "Clear search",
|
|
2804
|
+
onClick: clearSearch,
|
|
2805
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "xBlack", size: 16, "aria-hidden": "true" })
|
|
2775
2806
|
}
|
|
2776
2807
|
)
|
|
2777
|
-
]
|
|
2778
|
-
}
|
|
2808
|
+
] })
|
|
2809
|
+
] })
|
|
2810
|
+
) : searchState !== "closed" ? (
|
|
2811
|
+
/* Desktop — animated inline expand */
|
|
2812
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
2813
|
+
"div",
|
|
2814
|
+
{
|
|
2815
|
+
className: clsx23__default.default(
|
|
2816
|
+
ResourcesGridList_module_default.searchExpanded,
|
|
2817
|
+
searchState === "closing" && ResourcesGridList_module_default.searchCollapsing
|
|
2818
|
+
),
|
|
2819
|
+
onAnimationEnd: () => {
|
|
2820
|
+
if (searchState === "closing") setSearchState("closed");
|
|
2821
|
+
},
|
|
2822
|
+
children: [
|
|
2823
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.searchIconInner, children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "search", size: 20, "aria-hidden": "true" }) }),
|
|
2824
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2825
|
+
"input",
|
|
2826
|
+
{
|
|
2827
|
+
ref: searchInputRef,
|
|
2828
|
+
type: "text",
|
|
2829
|
+
className: ResourcesGridList_module_default.searchInput,
|
|
2830
|
+
placeholder: "Search\u2026",
|
|
2831
|
+
value: searchValue,
|
|
2832
|
+
onChange: (e) => onSearchChange(e.target.value),
|
|
2833
|
+
onKeyDown: (e) => {
|
|
2834
|
+
if (e.key === "Escape") {
|
|
2835
|
+
if (searchValue) clearSearch();
|
|
2836
|
+
else closeSearch();
|
|
2837
|
+
}
|
|
2838
|
+
},
|
|
2839
|
+
onBlur: () => {
|
|
2840
|
+
if (!searchValue) closeSearch();
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
),
|
|
2844
|
+
searchValue && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2845
|
+
"button",
|
|
2846
|
+
{
|
|
2847
|
+
type: "button",
|
|
2848
|
+
className: ResourcesGridList_module_default.searchClear,
|
|
2849
|
+
"aria-label": "Clear search",
|
|
2850
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
2851
|
+
onClick: clearSearch,
|
|
2852
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "xBlack", size: 16, "aria-hidden": "true" })
|
|
2853
|
+
}
|
|
2854
|
+
)
|
|
2855
|
+
]
|
|
2856
|
+
}
|
|
2857
|
+
)
|
|
2779
2858
|
) : /* @__PURE__ */ jsxRuntime.jsxs("button", { type: "button", className: ResourcesGridList_module_default.chip, onClick: () => setSearchState("open"), children: [
|
|
2780
2859
|
/* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "search", size: 20, "aria-hidden": "true" }),
|
|
2781
|
-
|
|
2860
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.chipLabel, children: "Search" })
|
|
2782
2861
|
] })
|
|
2783
2862
|
] })
|
|
2784
2863
|
] });
|
|
2785
2864
|
}
|
|
2786
|
-
var Sidebar = ({
|
|
2865
|
+
var Sidebar = ({
|
|
2866
|
+
categories,
|
|
2867
|
+
isMobile,
|
|
2868
|
+
onToggle,
|
|
2869
|
+
selectedIndex,
|
|
2870
|
+
onSelect
|
|
2871
|
+
}) => {
|
|
2787
2872
|
if (isMobile) {
|
|
2788
2873
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ResourcesGridList_module_default.sidebarMobile, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2789
2874
|
"button",
|
|
@@ -2801,7 +2886,17 @@ var Sidebar = ({ categories, isMobile, onToggle }) => {
|
|
|
2801
2886
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2802
2887
|
"li",
|
|
2803
2888
|
{
|
|
2804
|
-
className: clsx23__default.default(ResourcesGridList_module_default.sidebarItem,
|
|
2889
|
+
className: clsx23__default.default(ResourcesGridList_module_default.sidebarItem, i === selectedIndex && ResourcesGridList_module_default.active),
|
|
2890
|
+
role: "button",
|
|
2891
|
+
tabIndex: 0,
|
|
2892
|
+
"aria-pressed": i === selectedIndex,
|
|
2893
|
+
onClick: () => onSelect(i),
|
|
2894
|
+
onKeyDown: (e) => {
|
|
2895
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2896
|
+
e.preventDefault();
|
|
2897
|
+
onSelect(i);
|
|
2898
|
+
}
|
|
2899
|
+
},
|
|
2805
2900
|
children: [
|
|
2806
2901
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: cat.label }),
|
|
2807
2902
|
cat.hasNotification && /* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.notificationDot, "aria-label": "New" })
|
|
@@ -2811,14 +2906,19 @@ var Sidebar = ({ categories, isMobile, onToggle }) => {
|
|
|
2811
2906
|
);
|
|
2812
2907
|
}) }) });
|
|
2813
2908
|
};
|
|
2814
|
-
var ResourceIcon = ({ type }) =>
|
|
2909
|
+
var ResourceIcon = ({ image, type }) => {
|
|
2910
|
+
if (!image) return null;
|
|
2911
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ResourcesGridList_module_default.iconWrapper, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: image, alt: type != null ? type : "", width: 32, height: 32 }) });
|
|
2912
|
+
};
|
|
2815
2913
|
var ResourceCardItem = ({ item, view }) => {
|
|
2914
|
+
const hasHref = Boolean(item.href);
|
|
2915
|
+
const linkWrapper = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.href, className: ResourcesGridList_module_default.cardLink, target: "_blank", rel: "noopener noreferrer", children });
|
|
2816
2916
|
if (view === "grid") {
|
|
2817
2917
|
return /* @__PURE__ */ jsxRuntime.jsx("article", { className: ResourcesGridList_module_default.cardGrid, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardBody, children: [
|
|
2818
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardIconTitle, children: [
|
|
2819
|
-
/* @__PURE__ */ jsxRuntime.jsx(ResourceIcon, { type: item.type }),
|
|
2918
|
+
/* @__PURE__ */ jsxRuntime.jsx(ConditionalWrapper, { condition: hasHref, wrapper: linkWrapper, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardIconTitle, children: [
|
|
2919
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResourceIcon, { image: item.image, type: item.type }),
|
|
2820
2920
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.cardTitle, children: item.title })
|
|
2821
|
-
] }),
|
|
2921
|
+
] }) }),
|
|
2822
2922
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardMeta, children: [
|
|
2823
2923
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.cardDate, children: item.date }),
|
|
2824
2924
|
item.hasNotification && /* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.notificationDot, "aria-label": "New" })
|
|
@@ -2827,22 +2927,59 @@ var ResourceCardItem = ({ item, view }) => {
|
|
|
2827
2927
|
}
|
|
2828
2928
|
return /* @__PURE__ */ jsxRuntime.jsxs("article", { className: ResourcesGridList_module_default.cardList, children: [
|
|
2829
2929
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardListLeft, children: [
|
|
2830
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.
|
|
2831
|
-
|
|
2930
|
+
item.hasNotification && /* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.notificationDot, "aria-label": "New" }),
|
|
2931
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.cardDate, children: item.date })
|
|
2832
2932
|
] }),
|
|
2833
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardListRight, children: [
|
|
2834
|
-
/* @__PURE__ */ jsxRuntime.jsx(ResourceIcon, { type: item.type }),
|
|
2933
|
+
/* @__PURE__ */ jsxRuntime.jsx(ConditionalWrapper, { condition: hasHref, wrapper: linkWrapper, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.cardListRight, children: [
|
|
2934
|
+
/* @__PURE__ */ jsxRuntime.jsx(ResourceIcon, { image: item.image, type: item.type }),
|
|
2835
2935
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.cardTitle, children: item.title })
|
|
2836
|
-
] })
|
|
2936
|
+
] }) })
|
|
2837
2937
|
] });
|
|
2838
2938
|
};
|
|
2839
|
-
var Pagination3 = (
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
/* @__PURE__ */ jsxRuntime.
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2939
|
+
var Pagination3 = ({ currentPage, totalPages, onPageChange }) => {
|
|
2940
|
+
const isFirst = currentPage <= 1;
|
|
2941
|
+
const isLast = currentPage >= totalPages;
|
|
2942
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.pagination, "aria-label": "Pagination", children: [
|
|
2943
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2944
|
+
"button",
|
|
2945
|
+
{
|
|
2946
|
+
type: "button",
|
|
2947
|
+
className: ResourcesGridList_module_default.pageArrow,
|
|
2948
|
+
"aria-label": "Previous page",
|
|
2949
|
+
disabled: isFirst,
|
|
2950
|
+
onClick: () => onPageChange(currentPage - 1),
|
|
2951
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "chevronLeftBlack", size: 32, "aria-hidden": "true" })
|
|
2952
|
+
}
|
|
2953
|
+
),
|
|
2954
|
+
Array.from({ length: totalPages }, (_, i) => {
|
|
2955
|
+
const page = i + 1;
|
|
2956
|
+
const isActive = page === currentPage;
|
|
2957
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2958
|
+
"button",
|
|
2959
|
+
{
|
|
2960
|
+
type: "button",
|
|
2961
|
+
className: clsx23__default.default(isActive ? ResourcesGridList_module_default.pageDotActive : ResourcesGridList_module_default.pageDot),
|
|
2962
|
+
"aria-label": `Page ${page}`,
|
|
2963
|
+
"aria-current": isActive ? "page" : void 0,
|
|
2964
|
+
onClick: () => onPageChange(page)
|
|
2965
|
+
},
|
|
2966
|
+
page
|
|
2967
|
+
);
|
|
2968
|
+
}),
|
|
2969
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2970
|
+
"button",
|
|
2971
|
+
{
|
|
2972
|
+
type: "button",
|
|
2973
|
+
className: ResourcesGridList_module_default.pageArrow,
|
|
2974
|
+
"aria-label": "Next page",
|
|
2975
|
+
disabled: isLast,
|
|
2976
|
+
onClick: () => onPageChange(currentPage + 1),
|
|
2977
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { type: "chevronRightBlack", size: 32, "aria-hidden": "true" })
|
|
2978
|
+
}
|
|
2979
|
+
)
|
|
2980
|
+
] });
|
|
2981
|
+
};
|
|
2982
|
+
var ITEMS_PER_PAGE = 12;
|
|
2846
2983
|
var ResourcesGridList = ({
|
|
2847
2984
|
className,
|
|
2848
2985
|
items = [],
|
|
@@ -2851,19 +2988,51 @@ var ResourcesGridList = ({
|
|
|
2851
2988
|
defaultFilter = "all",
|
|
2852
2989
|
defaultSort = "latest"
|
|
2853
2990
|
}) => {
|
|
2991
|
+
var _a;
|
|
2854
2992
|
const [view, setView] = React62.useState(defaultView);
|
|
2855
2993
|
const [isSidebarOpen, setIsSidebarOpen] = React62.useState(false);
|
|
2856
2994
|
const [filterValue, setFilterValue] = React62.useState(defaultFilter);
|
|
2857
2995
|
const [sortValue, setSortValue] = React62.useState(defaultSort);
|
|
2996
|
+
const [searchQuery, setSearchQuery] = React62.useState("");
|
|
2997
|
+
const [currentPage, setCurrentPage] = React62.useState(1);
|
|
2998
|
+
const [selectedCategory, setSelectedCategory] = React62.useState(() => {
|
|
2999
|
+
const activeIndex = categories.findIndex((cat) => cat.active);
|
|
3000
|
+
return activeIndex === -1 ? 0 : activeIndex;
|
|
3001
|
+
});
|
|
2858
3002
|
const { is } = useViewPort_default();
|
|
2859
3003
|
const isMobile = is("tablet", "below");
|
|
2860
|
-
const
|
|
3004
|
+
const selectedValue = (_a = categories[selectedCategory]) == null ? void 0 : _a.value;
|
|
3005
|
+
const handleSelectCategory = (index) => {
|
|
3006
|
+
setSelectedCategory(index);
|
|
3007
|
+
setCurrentPage(1);
|
|
3008
|
+
if (isMobile) setIsSidebarOpen(false);
|
|
3009
|
+
};
|
|
3010
|
+
const handleFilterChange = (value) => {
|
|
3011
|
+
setFilterValue(value);
|
|
3012
|
+
setCurrentPage(1);
|
|
3013
|
+
};
|
|
3014
|
+
const handleSortChange = (value) => {
|
|
3015
|
+
setSortValue(value);
|
|
3016
|
+
setCurrentPage(1);
|
|
3017
|
+
};
|
|
3018
|
+
const handleSearchChange = (value) => {
|
|
3019
|
+
setSearchQuery(value);
|
|
3020
|
+
setCurrentPage(1);
|
|
3021
|
+
};
|
|
3022
|
+
const displayedItems = [...items].filter((item) => filterValue === "all" || item.type === filterValue).filter((item) => selectedValue == null || item.category === selectedValue).filter((item) => {
|
|
3023
|
+
const q = searchQuery.trim().toLowerCase();
|
|
3024
|
+
return q === "" || item.title.toLowerCase().includes(q);
|
|
3025
|
+
}).sort((a, b) => {
|
|
2861
3026
|
if (sortValue === "latest") return new Date(b.date).getTime() - new Date(a.date).getTime();
|
|
2862
3027
|
if (sortValue === "oldest") return new Date(a.date).getTime() - new Date(b.date).getTime();
|
|
2863
3028
|
if (sortValue === "az") return a.title.localeCompare(b.title);
|
|
2864
3029
|
if (sortValue === "za") return b.title.localeCompare(a.title);
|
|
2865
3030
|
return 0;
|
|
2866
3031
|
});
|
|
3032
|
+
const totalPages = Math.max(1, Math.ceil(displayedItems.length / ITEMS_PER_PAGE));
|
|
3033
|
+
const safeCurrentPage = Math.min(currentPage, totalPages);
|
|
3034
|
+
const pageStart = (safeCurrentPage - 1) * ITEMS_PER_PAGE;
|
|
3035
|
+
const paginatedItems = displayedItems.slice(pageStart, pageStart + ITEMS_PER_PAGE);
|
|
2867
3036
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx23__default.default(ResourcesGridList_module_default.widget, className), children: [
|
|
2868
3037
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2869
3038
|
FilterBar,
|
|
@@ -2872,9 +3041,11 @@ var ResourcesGridList = ({
|
|
|
2872
3041
|
onViewChange: setView,
|
|
2873
3042
|
isMobile,
|
|
2874
3043
|
filterValue,
|
|
2875
|
-
onFilterChange:
|
|
3044
|
+
onFilterChange: handleFilterChange,
|
|
2876
3045
|
sortValue,
|
|
2877
|
-
onSortChange:
|
|
3046
|
+
onSortChange: handleSortChange,
|
|
3047
|
+
searchValue: searchQuery,
|
|
3048
|
+
onSearchChange: handleSearchChange
|
|
2878
3049
|
}
|
|
2879
3050
|
),
|
|
2880
3051
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ResourcesGridList_module_default.content, children: [
|
|
@@ -2888,17 +3059,30 @@ var ResourcesGridList = ({
|
|
|
2888
3059
|
"aria-hidden": !isSidebarOpen,
|
|
2889
3060
|
children: [
|
|
2890
3061
|
/* @__PURE__ */ jsxRuntime.jsx("nav", { className: ResourcesGridList_module_default.mobileCategoriesPanel, "aria-label": "Resource categories", children: /* @__PURE__ */ jsxRuntime.jsx("ul", { className: ResourcesGridList_module_default.mobileCategoriesList, children: categories.map((cat, i) => {
|
|
2891
|
-
var
|
|
3062
|
+
var _a2;
|
|
2892
3063
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2893
3064
|
"li",
|
|
2894
3065
|
{
|
|
2895
|
-
className: clsx23__default.default(
|
|
3066
|
+
className: clsx23__default.default(
|
|
3067
|
+
ResourcesGridList_module_default.mobileSidebarItem,
|
|
3068
|
+
i === selectedCategory && ResourcesGridList_module_default.active
|
|
3069
|
+
),
|
|
3070
|
+
role: "button",
|
|
3071
|
+
tabIndex: 0,
|
|
3072
|
+
"aria-pressed": i === selectedCategory,
|
|
3073
|
+
onClick: () => handleSelectCategory(i),
|
|
3074
|
+
onKeyDown: (e) => {
|
|
3075
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3076
|
+
e.preventDefault();
|
|
3077
|
+
handleSelectCategory(i);
|
|
3078
|
+
}
|
|
3079
|
+
},
|
|
2896
3080
|
children: [
|
|
2897
3081
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: cat.label }),
|
|
2898
3082
|
cat.hasNotification && /* @__PURE__ */ jsxRuntime.jsx("span", { className: ResourcesGridList_module_default.notificationDot, "aria-label": "New" })
|
|
2899
3083
|
]
|
|
2900
3084
|
},
|
|
2901
|
-
(
|
|
3085
|
+
(_a2 = cat.label) != null ? _a2 : i
|
|
2902
3086
|
);
|
|
2903
3087
|
}) }) }),
|
|
2904
3088
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: ResourcesGridList_module_default.mobileSidebarCloseColumn, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2919,15 +3103,24 @@ var ResourcesGridList = ({
|
|
|
2919
3103
|
{
|
|
2920
3104
|
categories,
|
|
2921
3105
|
isMobile,
|
|
2922
|
-
onToggle: () => setIsSidebarOpen(true)
|
|
3106
|
+
onToggle: () => setIsSidebarOpen(true),
|
|
3107
|
+
selectedIndex: selectedCategory,
|
|
3108
|
+
onSelect: handleSelectCategory
|
|
2923
3109
|
}
|
|
2924
3110
|
),
|
|
2925
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx23__default.default(ResourcesGridList_module_default.cardsArea, ResourcesGridList_module_default[view]), children:
|
|
2926
|
-
var
|
|
2927
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ResourceCardItem, { item, view }, (
|
|
3111
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx23__default.default(ResourcesGridList_module_default.cardsArea, ResourcesGridList_module_default[view]), children: paginatedItems.map((item, i) => {
|
|
3112
|
+
var _a2;
|
|
3113
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ResourceCardItem, { item, view }, (_a2 = item.title) != null ? _a2 : i);
|
|
2928
3114
|
}) })
|
|
2929
3115
|
] }),
|
|
2930
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3116
|
+
totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3117
|
+
Pagination3,
|
|
3118
|
+
{
|
|
3119
|
+
currentPage: safeCurrentPage,
|
|
3120
|
+
totalPages,
|
|
3121
|
+
onPageChange: setCurrentPage
|
|
3122
|
+
}
|
|
3123
|
+
)
|
|
2931
3124
|
] });
|
|
2932
3125
|
};
|
|
2933
3126
|
function useIntersectionObserver({
|