phx-react 1.3.1837 → 1.3.1839

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 (73) hide show
  1. package/dist/cjs/components/Modal/Modal.d.ts +1 -1
  2. package/dist/cjs/components/Modal/Modal.js +53 -19
  3. package/dist/cjs/components/Modal/Modal.js.map +1 -1
  4. package/dist/cjs/components/Onboarding/contexts/onboarding-context.d.ts +63 -0
  5. package/dist/cjs/components/Onboarding/contexts/onboarding-context.js +282 -0
  6. package/dist/cjs/components/Onboarding/contexts/onboarding-context.js.map +1 -0
  7. package/dist/cjs/components/Onboarding/contexts/style.d.ts +1 -0
  8. package/dist/cjs/components/Onboarding/contexts/style.js +77 -0
  9. package/dist/cjs/components/Onboarding/contexts/style.js.map +1 -0
  10. package/dist/cjs/components/Onboarding/hooks/use-onboarding-init.d.ts +7 -0
  11. package/dist/cjs/components/Onboarding/hooks/use-onboarding-init.js +19 -0
  12. package/dist/cjs/components/Onboarding/hooks/use-onboarding-init.js.map +1 -0
  13. package/dist/cjs/components/Onboarding/index.d.ts +3 -0
  14. package/dist/cjs/components/Onboarding/index.js +7 -0
  15. package/dist/cjs/components/Onboarding/index.js.map +1 -0
  16. package/dist/cjs/components/Onboarding/modal-slides/modal-slides.d.ts +10 -0
  17. package/dist/cjs/components/Onboarding/modal-slides/modal-slides.js +59 -0
  18. package/dist/cjs/components/Onboarding/modal-slides/modal-slides.js.map +1 -0
  19. package/dist/cjs/components/Onboarding/onbroading-demo.d.ts +9 -0
  20. package/dist/cjs/components/Onboarding/onbroading-demo.js +208 -0
  21. package/dist/cjs/components/Onboarding/onbroading-demo.js.map +1 -0
  22. package/dist/cjs/components/Slider/index.d.ts +2 -0
  23. package/dist/cjs/components/Slider/index.js +6 -0
  24. package/dist/cjs/components/Slider/index.js.map +1 -0
  25. package/dist/cjs/components/Slider/phx-slider-item.d.ts +6 -0
  26. package/dist/cjs/components/Slider/phx-slider-item.js +38 -0
  27. package/dist/cjs/components/Slider/phx-slider-item.js.map +1 -0
  28. package/dist/cjs/components/Slider/phx-slider.d.ts +18 -0
  29. package/dist/cjs/components/Slider/phx-slider.js +168 -0
  30. package/dist/cjs/components/Slider/phx-slider.js.map +1 -0
  31. package/dist/cjs/components/Slider/ultis/create-animate.d.ts +17 -0
  32. package/dist/cjs/components/Slider/ultis/create-animate.js +38 -0
  33. package/dist/cjs/components/Slider/ultis/create-animate.js.map +1 -0
  34. package/dist/cjs/index.d.ts +2 -0
  35. package/dist/cjs/index.js +2 -0
  36. package/dist/cjs/index.js.map +1 -1
  37. package/dist/esm/components/Modal/Modal.d.ts +1 -1
  38. package/dist/esm/components/Modal/Modal.js +54 -20
  39. package/dist/esm/components/Modal/Modal.js.map +1 -1
  40. package/dist/esm/components/Onboarding/contexts/onboarding-context.d.ts +63 -0
  41. package/dist/esm/components/Onboarding/contexts/onboarding-context.js +276 -0
  42. package/dist/esm/components/Onboarding/contexts/onboarding-context.js.map +1 -0
  43. package/dist/esm/components/Onboarding/contexts/style.d.ts +1 -0
  44. package/dist/esm/components/Onboarding/contexts/style.js +74 -0
  45. package/dist/esm/components/Onboarding/contexts/style.js.map +1 -0
  46. package/dist/esm/components/Onboarding/hooks/use-onboarding-init.d.ts +7 -0
  47. package/dist/esm/components/Onboarding/hooks/use-onboarding-init.js +15 -0
  48. package/dist/esm/components/Onboarding/hooks/use-onboarding-init.js.map +1 -0
  49. package/dist/esm/components/Onboarding/index.d.ts +3 -0
  50. package/dist/esm/components/Onboarding/index.js +4 -0
  51. package/dist/esm/components/Onboarding/index.js.map +1 -0
  52. package/dist/esm/components/Onboarding/modal-slides/modal-slides.d.ts +10 -0
  53. package/dist/esm/components/Onboarding/modal-slides/modal-slides.js +54 -0
  54. package/dist/esm/components/Onboarding/modal-slides/modal-slides.js.map +1 -0
  55. package/dist/esm/components/Onboarding/onbroading-demo.d.ts +9 -0
  56. package/dist/esm/components/Onboarding/onbroading-demo.js +203 -0
  57. package/dist/esm/components/Onboarding/onbroading-demo.js.map +1 -0
  58. package/dist/esm/components/Slider/index.d.ts +2 -0
  59. package/dist/esm/components/Slider/index.js +2 -0
  60. package/dist/esm/components/Slider/index.js.map +1 -0
  61. package/dist/esm/components/Slider/phx-slider-item.d.ts +6 -0
  62. package/dist/esm/components/Slider/phx-slider-item.js +33 -0
  63. package/dist/esm/components/Slider/phx-slider-item.js.map +1 -0
  64. package/dist/esm/components/Slider/phx-slider.d.ts +18 -0
  65. package/dist/esm/components/Slider/phx-slider.js +164 -0
  66. package/dist/esm/components/Slider/phx-slider.js.map +1 -0
  67. package/dist/esm/components/Slider/ultis/create-animate.d.ts +17 -0
  68. package/dist/esm/components/Slider/ultis/create-animate.js +34 -0
  69. package/dist/esm/components/Slider/ultis/create-animate.js.map +1 -0
  70. package/dist/esm/index.d.ts +2 -0
  71. package/dist/esm/index.js +2 -0
  72. package/dist/esm/index.js.map +1 -1
  73. package/package.json +2 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-onboarding-init.js","sourceRoot":"","sources":["../../../../../src/components/Onboarding/hooks/use-onboarding-init.ts"],"names":[],"mappings":";AAAA,YAAY,CAAA;;;AAEZ,iCAAiC;AACjC,uEAAqF;AAErF;;;;GAIG;AACI,MAAM,oBAAoB,GAAG,CAAC,KAAgC,EAAE,EAAE;IACvE,MAAM,EAAE,YAAY,EAAE,GAAG,IAAA,qCAAgB,GAAE,CAAA;IAE3C,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAA;IACzC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAA;AACpB,CAAC,CAAA;AANY,QAAA,oBAAoB,wBAMhC"}
@@ -0,0 +1,3 @@
1
+ export * from './contexts/onboarding-context';
2
+ export * from './hooks/use-onboarding-init';
3
+ export * from './modal-slides/modal-slides';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./contexts/onboarding-context"), exports);
5
+ tslib_1.__exportStar(require("./hooks/use-onboarding-init"), exports);
6
+ tslib_1.__exportStar(require("./modal-slides/modal-slides"), exports);
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Onboarding/index.ts"],"names":[],"mappings":";;;AAAA,wEAA6C;AAC7C,sEAA2C;AAC3C,sEAA2C"}
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { IPHXOnboardingSlideStep } from '../contexts/onboarding-context';
3
+ export interface PHXOnboardingModalProps {
4
+ show: boolean;
5
+ slides: Array<IPHXOnboardingSlideStep>;
6
+ hasTours: boolean;
7
+ onHide(): void;
8
+ onStartTour(): void;
9
+ }
10
+ export declare const PHXOnboardingModal: React.FC<PHXOnboardingModalProps>;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PHXOnboardingModal = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const react_1 = tslib_1.__importStar(require("react"));
7
+ const Slider_1 = require("../../Slider");
8
+ const Box_1 = require("../../Box");
9
+ const HorizontalStack_1 = require("../../HorizontalStack");
10
+ const Button_1 = require("../../Button");
11
+ const Modal_1 = require("../../Modal");
12
+ const PHXOnboardingModal = ({ hasTours, onHide, onStartTour, show, slides, }) => {
13
+ const sliderRef = (0, react_1.useRef)(null);
14
+ const [currentIndex, setCurrentIndex] = (0, react_1.useState)(0);
15
+ // Derive from state — triggers re-render when index changes
16
+ const isFirstSlide = currentIndex === 0;
17
+ const isLastSlide = currentIndex === slides.length - 1;
18
+ /**
19
+ * Goes to previous slide
20
+ * @returns
21
+ */
22
+ const goToPrevious = () => {
23
+ var _a;
24
+ if (isFirstSlide)
25
+ return;
26
+ (_a = sliderRef.current) === null || _a === void 0 ? void 0 : _a.prev();
27
+ };
28
+ /**
29
+ * Goes to next slide
30
+ * @returns
31
+ */
32
+ const goToNext = () => {
33
+ var _a;
34
+ if (isLastSlide)
35
+ return;
36
+ (_a = sliderRef.current) === null || _a === void 0 ? void 0 : _a.next();
37
+ };
38
+ /**
39
+ * Reset slider to first slide when modal opens
40
+ * @returns
41
+ */
42
+ (0, react_1.useEffect)(() => {
43
+ var _a;
44
+ if (show) {
45
+ (_a = sliderRef.current) === null || _a === void 0 ? void 0 : _a.goTo(0);
46
+ setCurrentIndex(0);
47
+ }
48
+ }, [show]);
49
+ const customFooterComponent = (react_1.default.createElement(Box_1.PHXBox, { fullWidth: true, p: 'snappy' },
50
+ react_1.default.createElement(HorizontalStack_1.PHXHorizontalStack, { fullWidth: true, items: 'center', justify: 'between' },
51
+ isFirstSlide ? (react_1.default.createElement("span", null)) : (react_1.default.createElement(Button_1.PHXButton, { onClick: goToPrevious, secondary: true }, "Quay l\u1EA1i")),
52
+ react_1.default.createElement(HorizontalStack_1.PHXHorizontalStack, { gapX: 'tight', items: 'center' },
53
+ react_1.default.createElement(Button_1.PHXButton, { onClick: onHide, secondary: true }, "B\u1ECF qua"),
54
+ isLastSlide ? (hasTours ? (react_1.default.createElement(Button_1.PHXButton, { onClick: onStartTour, primary: true }, "B\u1EAFt \u0111\u1EA7u Tour")) : (react_1.default.createElement(Button_1.PHXButton, { onClick: onHide, primary: true }, "Ho\u00E0n t\u1EA5t"))) : (react_1.default.createElement(Button_1.PHXButton, { onClick: goToNext, primary: true }, "Ti\u1EBFp theo"))))));
55
+ return (react_1.default.createElement(Modal_1.PHXModal, { customFooter: customFooterComponent, inCard: false, onHide: onHide, show: show, size: 'large-plus', title: 'H\u01B0\u1EDBng d\u1EABn s\u1EED d\u1EE5ng' },
56
+ react_1.default.createElement(Slider_1.PHXSlider, { ref: sliderRef, enableNavigate: false, gap: 0, onIndexChange: setCurrentIndex, perView: 1 }, slides.map((slideItem) => (react_1.default.createElement("img", { key: slideItem.id, alt: slideItem.title, src: slideItem.image }))))));
57
+ };
58
+ exports.PHXOnboardingModal = PHXOnboardingModal;
59
+ //# sourceMappingURL=modal-slides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-slides.js","sourceRoot":"","sources":["../../../../../src/components/Onboarding/modal-slides/modal-slides.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { IPHXOnboardingFlow } from './contexts/onboarding-context';
3
+ export declare const slidesOnlyFlow: IPHXOnboardingFlow;
4
+ export declare const tourOnlyFlow: IPHXOnboardingFlow;
5
+ export declare const slidesAndTourFlow: IPHXOnboardingFlow;
6
+ /**
7
+ * Demo cách sử dụng Onboarding
8
+ */
9
+ export default function OnboardingDemo(): React.JSX.Element;
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.slidesAndTourFlow = exports.tourOnlyFlow = exports.slidesOnlyFlow = void 0;
5
+ exports.default = OnboardingDemo;
6
+ const tslib_1 = require("tslib");
7
+ const onboarding_context_1 = require("./contexts/onboarding-context");
8
+ const react_1 = tslib_1.__importDefault(require("react"));
9
+ const use_onboarding_init_1 = require("./hooks/use-onboarding-init");
10
+ const Badge_1 = require("../Badge");
11
+ const TextV2_1 = require("../TextV2");
12
+ const Button_1 = require("../Button");
13
+ const Card_1 = require("../Card");
14
+ const Box_1 = require("../Box");
15
+ const HorizontalStack_1 = require("../HorizontalStack");
16
+ const BlockStack_1 = require("../BlockStack");
17
+ const sharedSlides = [
18
+ {
19
+ id: 1,
20
+ image: 'https://cdn.dribbble.com/userupload/43777200/file/original-b6b996f3118cec5deba3cf770e2943f8.png?resize=1024x768&vertical=center',
21
+ },
22
+ {
23
+ id: 2,
24
+ image: 'https://cdn.dribbble.com/userupload/16613267/file/original-46564ba6e70008893ec7c252183d4376.png?resize=1024x768&vertical=center',
25
+ },
26
+ {
27
+ id: 3,
28
+ image: 'https://cdn.dribbble.com/userupload/11165677/file/original-8f6d2e9ce6891d724ff10cf478b6e1a7.png?resize=1024x763&vertical=center',
29
+ },
30
+ ];
31
+ // ─── Demo Flow 1: Chỉ có Slides (không có Tour) ───────────────────────────────
32
+ exports.slidesOnlyFlow = {
33
+ name: 'demo-slides-only',
34
+ slides: sharedSlides,
35
+ // steps: undefined → không có tour
36
+ };
37
+ // ─── Demo Flow 2: Chỉ có Tour (không có Slides) ───────────────────────────────
38
+ exports.tourOnlyFlow = {
39
+ name: 'demo-tour-only',
40
+ // slides: undefined → không có slides
41
+ steps: [
42
+ {
43
+ element: '#tour-step-1',
44
+ popover: {
45
+ title: 'Bước 1: Tìm kiếm',
46
+ description: 'Sử dụng thanh tìm kiếm để nhanh chóng tìm nội dung cần thiết.',
47
+ side: 'bottom',
48
+ align: 'start',
49
+ },
50
+ },
51
+ {
52
+ element: '#tour-step-2',
53
+ popover: {
54
+ title: 'Bước 2: Bộ lọc',
55
+ description: 'Áp dụng bộ lọc để thu hẹp kết quả theo ngày, loại hoặc trạng thái.',
56
+ side: 'bottom',
57
+ align: 'center',
58
+ },
59
+ },
60
+ {
61
+ element: '#tour-step-3',
62
+ popover: {
63
+ title: 'Bước 3: Tạo mới',
64
+ description: 'Nhấn nút này để tạo chiến dịch hoặc nội dung mới.',
65
+ side: 'left',
66
+ align: 'center',
67
+ },
68
+ },
69
+ ],
70
+ };
71
+ // ─── Demo Flow 3: Cả Slides lẫn Tour ─────────────────────────────────────────
72
+ exports.slidesAndTourFlow = {
73
+ name: 'demo-slides-and-tour',
74
+ slides: [
75
+ {
76
+ id: 1,
77
+ title: 'Tổng quan hệ thống',
78
+ description: 'Xem qua các tính năng chính trước khi hướng dẫn chi tiết.',
79
+ content: 'Phần hướng dẫn này sẽ giới thiệu tổng quan rồi dẫn bạn qua từng tính năng cụ thể trên giao diện thật.',
80
+ image: 'https://cdn.dribbble.com/userupload/15135632/file/original-00d7aa66ca52d41e6fdaeaefc96af599.png?resize=1024x768&vertical=center',
81
+ },
82
+ {
83
+ id: 2,
84
+ title: 'Sẵn sàng bắt đầu?',
85
+ description: 'Nhấn "Bắt đầu Tour" để xem hướng dẫn trực tiếp trên màn hình.',
86
+ content: 'Tour sẽ dẫn bạn qua từng thành phần quan trọng. Bạn có thể đóng bất cứ lúc nào.',
87
+ image: 'https://cdn.dribbble.com/userupload/43777200/file/original-b6b996f3118cec5deba3cf770e2943f8.png?resize=1024x768&vertical=center',
88
+ },
89
+ ],
90
+ steps: [
91
+ {
92
+ element: '#combo-step-1',
93
+ popover: {
94
+ title: 'Bảng điều khiển',
95
+ description: 'Đây là trung tâm điều hành. Mọi thứ bắt đầu từ đây.',
96
+ side: 'right',
97
+ align: 'start',
98
+ },
99
+ },
100
+ {
101
+ element: '#combo-step-2',
102
+ popover: {
103
+ title: 'Danh sách chiến dịch',
104
+ description: 'Xem toàn bộ chiến dịch đang hoạt động và đã lưu trữ.',
105
+ side: 'bottom',
106
+ align: 'center',
107
+ },
108
+ },
109
+ {
110
+ element: '#combo-step-3',
111
+ popover: {
112
+ title: 'Tạo chiến dịch mới',
113
+ description: 'Nhấn đây để bắt đầu một chiến dịch hoàn toàn mới.',
114
+ side: 'left',
115
+ align: 'end',
116
+ },
117
+ },
118
+ ],
119
+ };
120
+ const demoFlows = [exports.slidesOnlyFlow, exports.tourOnlyFlow, exports.slidesAndTourFlow];
121
+ /**
122
+ * Demo OnBroading
123
+ */
124
+ function DemoContent() {
125
+ (0, use_onboarding_init_1.usePHXOnboardingInit)(demoFlows);
126
+ const { getFlowStatus, resetStatusOnboarding, startFlow } = (0, onboarding_context_1.usePHXOnboarding)();
127
+ const demos = [
128
+ {
129
+ flowName: 'demo-slides-only',
130
+ badge: 'Slides Only',
131
+ badgeColor: '#3b82f6',
132
+ title: 'Chỉ có Slides',
133
+ description: 'Hiển thị modal giới thiệu tổng quan với nhiều trang slide. Không có tour hướng dẫn trực tiếp trên màn hình.',
134
+ features: ['✅ Modal slides', '❌ Không có Tour'],
135
+ buttonLabel: 'Mở Slides',
136
+ elements: null,
137
+ },
138
+ {
139
+ flowName: 'demo-tour-only',
140
+ badge: 'Tour Only',
141
+ badgeColor: '#10b981',
142
+ title: 'Chỉ có Tour',
143
+ description: 'Hướng dẫn trực tiếp từng thành phần trên giao diện thật. Không có modal slides giới thiệu.',
144
+ features: ['❌ Không có Slides', '✅ Tour trực tiếp'],
145
+ buttonLabel: 'Bắt đầu Tour',
146
+ elements: [
147
+ { id: 'tour-step-1', label: '🔍 Tìm kiếm' },
148
+ { id: 'tour-step-2', label: '🗂 Bộ lọc' },
149
+ { id: 'tour-step-3', label: '➕ Tạo mới' },
150
+ ],
151
+ },
152
+ {
153
+ flowName: 'demo-slides-and-tour',
154
+ badge: 'Slides + Tour',
155
+ badgeColor: '#8b5cf6',
156
+ title: 'Slides & Tour kết hợp',
157
+ description: 'Mở slides giới thiệu tổng quan trước. Sau đó có nút "Bắt đầu Tour" để chuyển sang hướng dẫn chi tiết.',
158
+ features: ['✅ Modal slides', '✅ Tour trực tiếp'],
159
+ buttonLabel: 'Bắt đầu',
160
+ elements: [
161
+ { id: 'combo-step-1', label: '🏠 Dashboard' },
162
+ { id: 'combo-step-2', label: '📋 Chiến dịch' },
163
+ { id: 'combo-step-3', label: '🆕 Tạo mới' },
164
+ ],
165
+ },
166
+ ];
167
+ return (react_1.default.createElement("div", { className: 'mx-auto max-w-6xl' },
168
+ react_1.default.createElement("div", { className: 'mb-12' },
169
+ react_1.default.createElement("h1", { className: 'mb-3 text-3xl font-bold text-slate-900' }, "Onboarding Demo"),
170
+ react_1.default.createElement("p", { className: 'text-base text-slate-500' }, "3 tr\u01B0\u1EDDng h\u1EE3p: ch\u1EC9 slides, ch\u1EC9 tour, v\u00E0 k\u1EBFt h\u1EE3p c\u1EA3 hai.")),
171
+ react_1.default.createElement("div", { className: 'grid gap-6 [grid-template-columns:repeat(auto-fit,minmax(280px,1fr))]' }, demos.map((demo) => {
172
+ const status = getFlowStatus(demo.flowName);
173
+ return (react_1.default.createElement(Card_1.PHXCard, { key: demo.flowName },
174
+ react_1.default.createElement(Badge_1.PHXBadge, { text: demo.badge, type: 'success' }),
175
+ react_1.default.createElement(BlockStack_1.PHXBlockStack, { gap: 'base' },
176
+ react_1.default.createElement(TextV2_1.PHXTextV2, { size: 'body', color: 'primary', lineHeight: 'loose' }, demo.title),
177
+ react_1.default.createElement(TextV2_1.PHXTextV2, { size: 'caption', lineHeight: 'base' }, demo.description),
178
+ react_1.default.createElement("ul", { className: 'flex flex-col gap-3' }, demo.features.map((feature) => (react_1.default.createElement(TextV2_1.PHXTextV2, { size: 'caption', key: feature },
179
+ "\u2022 ",
180
+ feature))))),
181
+ react_1.default.createElement("div", { className: 'flex flex-col gap-1 mt-5 rounded-lg bg-slate-50 p-3 text-xs text-slate-500' },
182
+ react_1.default.createElement("span", { className: 'mb-1 font-semibold text-slate-600' }, "Tr\u1EA1ng th\u00E1i (in-memory):"),
183
+ react_1.default.createElement(HorizontalStack_1.PHXHorizontalStack, { gapX: 'base', items: 'center' },
184
+ "Slides:",
185
+ ' ',
186
+ react_1.default.createElement(Box_1.PHXBox, { pt: 'atomic' },
187
+ react_1.default.createElement(TextV2_1.PHXTextV2, { color: status.slidesCompleted ? 'success' : 'default', size: 'caption', weight: 'bold' }, status.slidesCompleted ? '✅ Đã xem' : '⏳ Chưa xem'))),
188
+ react_1.default.createElement(Box_1.PHXBox, { pt: 'atomic' },
189
+ react_1.default.createElement(HorizontalStack_1.PHXHorizontalStack, { gapX: 'base', items: 'center' },
190
+ "Tour:",
191
+ ' ',
192
+ react_1.default.createElement(TextV2_1.PHXTextV2, { color: 'success', size: 'caption', weight: 'bold' }, status.toursCompleted ? '✅ Đã hoàn thành' : '⏳ Chưa làm')))),
193
+ demo.elements && (react_1.default.createElement("div", { className: 'flex flex-wrap gap-2 border-t border-slate-100 pt-4' }, demo.elements.map((el) => (react_1.default.createElement("div", { key: el.id, id: el.id, className: 'cursor-default rounded-lg border border-slate-200 bg-slate-50 px-3.5 py-1.5 text-sm font-medium text-slate-600' }, el.label))))),
194
+ react_1.default.createElement("div", { className: 'mt-5 flex flex-col gap-2' },
195
+ react_1.default.createElement(Button_1.PHXButton, { id: `btn-${demo.flowName}`, primary: true, onClick: () => {
196
+ resetStatusOnboarding(demo.flowName);
197
+ startFlow(demo.flowName);
198
+ } }, demo.buttonLabel))));
199
+ }))));
200
+ }
201
+ /**
202
+ * Demo cách sử dụng Onboarding
203
+ */
204
+ function OnboardingDemo() {
205
+ return (react_1.default.createElement(onboarding_context_1.PHXOnboardingProvider, null,
206
+ react_1.default.createElement(DemoContent, null)));
207
+ }
208
+ //# sourceMappingURL=onbroading-demo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onbroading-demo.js","sourceRoot":"","sources":["../../../../src/components/Onboarding/onbroading-demo.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { PHXSlider } from './phx-slider';
2
+ export type { PHXSliderProps, PHXSliderRef } from './phx-slider';
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PHXSlider = void 0;
4
+ var phx_slider_1 = require("./phx-slider");
5
+ Object.defineProperty(exports, "PHXSlider", { enumerable: true, get: function () { return phx_slider_1.PHXSlider; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/Slider/index.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAA/B,uGAAA,SAAS,OAAA"}
@@ -0,0 +1,6 @@
1
+ import { FC, ReactNode } from 'react';
2
+ export interface PHXSliderItemProps {
3
+ children: ReactNode;
4
+ onWidthChange?(width: number): void;
5
+ }
6
+ export declare const PHXSliderItem: FC<PHXSliderItemProps>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PHXSliderItem = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const react_1 = tslib_1.__importStar(require("react"));
7
+ const PHXSliderItem = ({ children, onWidthChange }) => {
8
+ const observerRef = (0, react_1.useRef)(null);
9
+ const prevWidthRef = (0, react_1.useRef)(0);
10
+ const containerRef = (0, react_1.useRef)(null);
11
+ /**
12
+ * Callback when observer get the width of children
13
+ * @param entries
14
+ */
15
+ const handleObserver = (entries) => {
16
+ for (const entry of entries) {
17
+ if (prevWidthRef.current !== entry.contentRect.width) {
18
+ onWidthChange === null || onWidthChange === void 0 ? void 0 : onWidthChange(entry.contentRect.width);
19
+ prevWidthRef.current = entry.contentRect.width;
20
+ }
21
+ }
22
+ };
23
+ /**
24
+ * Observes the width of the child element
25
+ * @returns
26
+ */
27
+ (0, react_1.useEffect)(() => {
28
+ observerRef.current = new ResizeObserver(handleObserver);
29
+ observerRef.current.observe(containerRef.current);
30
+ return () => {
31
+ var _a;
32
+ (_a = observerRef.current) === null || _a === void 0 ? void 0 : _a.disconnect();
33
+ };
34
+ }, []);
35
+ return (react_1.default.createElement("div", { ref: containerRef, className: 'shrink-0 [&_img]:pointer-events-none [&_img]:block', style: { width: 'var(--phx-slider-item-width)' } }, children));
36
+ };
37
+ exports.PHXSliderItem = PHXSliderItem;
38
+ //# sourceMappingURL=phx-slider-item.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phx-slider-item.js","sourceRoot":"","sources":["../../../../src/components/Slider/phx-slider-item.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAA;;;;AAEZ,uDAA+D;AAOxD,MAAM,aAAa,GAA2B,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,EAAE;IACnF,MAAM,WAAW,GAAG,IAAA,cAAM,EAAwB,IAAI,CAAC,CAAA;IACvD,MAAM,YAAY,GAAG,IAAA,cAAM,EAAS,CAAC,CAAC,CAAA;IACtC,MAAM,YAAY,GAAG,IAAA,cAAM,EAAiB,IAAI,CAAC,CAAA;IACjD;;;OAGG;IACH,MAAM,cAAc,GAAG,CAAC,OAAmC,EAAE,EAAE;QAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,YAAY,CAAC,OAAO,KAAK,KAAK,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;gBACrD,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;gBACxC,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC,WAAW,CAAC,KAAK,CAAA;YAChD,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IACD;;;OAGG;IACH,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,WAAW,CAAC,OAAO,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC,CAAA;QACxD,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,OAAQ,CAAC,CAAA;QAElD,OAAO,GAAG,EAAE;;YACV,MAAA,WAAW,CAAC,OAAO,0CAAE,UAAU,EAAE,CAAA;QACnC,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,uCACE,GAAG,EAAE,YAAY,EACjB,SAAS,EAAC,oDAAoD,EAC9D,KAAK,EAAE,EAAE,KAAK,EAAE,8BAA8B,EAAE,IAE/C,QAAQ,CACL,CACP,CAAA;AACH,CAAC,CAAA;AAtCY,QAAA,aAAa,iBAsCzB"}
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ import React from 'react';
3
+ export interface PHXSliderProps {
4
+ perView?: number;
5
+ gap?: number;
6
+ children: ReactNode;
7
+ onIndexChange?(index: number): void;
8
+ enableNavigate?: boolean;
9
+ }
10
+ export interface PHXSliderRef {
11
+ prev(): void;
12
+ next(): void;
13
+ goTo(index: number): void;
14
+ currentIndex: number;
15
+ isFirstSlide: boolean;
16
+ isLastSlide: boolean;
17
+ }
18
+ export declare const PHXSlider: React.ForwardRefExoticComponent<PHXSliderProps & React.RefAttributes<PHXSliderRef>>;
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.PHXSlider = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const outline_1 = require("@heroicons/react/24/outline");
7
+ const react_1 = require("react");
8
+ const phx_slider_item_1 = require("./phx-slider-item");
9
+ const create_animate_1 = require("./ultis/create-animate");
10
+ const react_2 = tslib_1.__importDefault(require("react"));
11
+ exports.PHXSlider = (0, react_1.forwardRef)(({ children, enableNavigate = true, gap = 0, onIndexChange, perView = 1 }, ref) => {
12
+ const [itemWidth, setItemWidth] = (0, react_1.useState)('');
13
+ const [x, setX] = (0, react_1.useState)(0);
14
+ const [currentIndex, setCurrentIndex] = (0, react_1.useState)(0);
15
+ const [isFirstSlide, setIsFirstSlide] = (0, react_1.useState)(true);
16
+ const [isLastSlide, setIsLastSlide] = (0, react_1.useState)(false);
17
+ const [prevDisabled, setPrevDisabled] = (0, react_1.useState)(true);
18
+ const [nextDisabled, setNextDisabled] = (0, react_1.useState)(false);
19
+ const childs = react_1.Children.toArray(children).flatMap((child) => {
20
+ if (react_2.default.isValidElement(child) && child.type === react_2.default.Fragment) {
21
+ return react_1.Children.toArray(child.props.children);
22
+ }
23
+ return child;
24
+ });
25
+ const containerRef = (0, react_1.useRef)(null);
26
+ /**
27
+ * Giới hạn giá trị trong khoảng min và max
28
+ * @param value Giá trị cần clamp
29
+ * @param min Giá trị nhỏ nhất
30
+ * @param max Giá trị lớn nhất
31
+ */
32
+ const clampValue = (value, min, max) => Math.min(Math.max(value, min), max);
33
+ /**
34
+ * Scroll tới vị trí X bất kỳ
35
+ * @param targetX Vị trí X cần scroll
36
+ */
37
+ const scrollTo = (targetX) => {
38
+ const containerEl = containerRef.current;
39
+ if (!containerEl) {
40
+ return;
41
+ }
42
+ const innerEl = containerEl.firstElementChild;
43
+ const minX = containerEl.clientWidth - innerEl.scrollWidth;
44
+ const nextX = clampValue(targetX, minX, 0);
45
+ (0, create_animate_1.createAnimate)({
46
+ from: x,
47
+ to: nextX,
48
+ duration: 250,
49
+ /**
50
+ * Callback khi cập nhật giá trị
51
+ * @param value Giá trị hiện tại
52
+ */
53
+ onUpdate(value) {
54
+ setX(value);
55
+ },
56
+ /**
57
+ * Callback khi kết thúc animation
58
+ */
59
+ onEnd() {
60
+ const containerCurrent = containerRef.current;
61
+ if (!containerCurrent || containerCurrent.clientWidth === 0)
62
+ return;
63
+ const index = Math.round(Math.abs(nextX) / containerCurrent.clientWidth);
64
+ setCurrentIndex(index);
65
+ setIsFirstSlide(index === 0);
66
+ setIsLastSlide(index === childs.length - 1);
67
+ onIndexChange === null || onIndexChange === void 0 ? void 0 : onIndexChange(index);
68
+ },
69
+ });
70
+ };
71
+ /**
72
+ * Lấy các element cần thiết cho animation
73
+ */
74
+ const getElements = () => {
75
+ const containerEl = containerRef.current;
76
+ if (!containerEl) {
77
+ return null;
78
+ }
79
+ return {
80
+ containerEl,
81
+ innerEl: containerEl.firstElementChild,
82
+ width: containerEl.clientWidth,
83
+ };
84
+ };
85
+ /**
86
+ * Đến slide index bất kỳ
87
+ * @param index Index cần đến
88
+ */
89
+ const goTo = (index) => {
90
+ const containerEl = getElements();
91
+ if (!containerEl) {
92
+ return;
93
+ }
94
+ const width = containerEl.width;
95
+ scrollTo(-index * width);
96
+ };
97
+ const vars = {
98
+ '--phx-slider-item-width': itemWidth,
99
+ '--phx-slider-gap': `${gap}px`,
100
+ '--phx-slider-translate': `${x}px`,
101
+ };
102
+ /**
103
+ * Vô hiệu hóa nút next và prev khi đến cuối hoặc đầu
104
+ */
105
+ const handleDisable = () => {
106
+ const elements = getElements();
107
+ if (!elements) {
108
+ return;
109
+ }
110
+ const innerEl = elements.innerEl;
111
+ setPrevDisabled(x === 0);
112
+ setNextDisabled(x === elements.width - innerEl.scrollWidth);
113
+ };
114
+ (0, react_1.useLayoutEffect)(() => {
115
+ setItemWidth(`calc(${100 / perView}% - ${(gap * (perView - 1)) / perView}px)`);
116
+ }, [perView, gap]);
117
+ (0, react_1.useLayoutEffect)(() => {
118
+ handleDisable();
119
+ }, [x]);
120
+ /**
121
+ * Slide về slide trước
122
+ */
123
+ const handlePrev = () => {
124
+ const container = getElements();
125
+ if (!container) {
126
+ return;
127
+ }
128
+ const width = container.width;
129
+ scrollTo(x + width);
130
+ };
131
+ /**
132
+ * Slide tới slide sau
133
+ */
134
+ const handleNext = () => {
135
+ const el = getElements();
136
+ if (!el) {
137
+ return;
138
+ }
139
+ const width = el.width;
140
+ scrollTo(x - width);
141
+ };
142
+ /**
143
+ * exposes methods tới component cha
144
+ */
145
+ (0, react_1.useImperativeHandle)(ref, () => ({
146
+ prev: handlePrev,
147
+ next: handleNext,
148
+ goTo,
149
+ currentIndex,
150
+ isFirstSlide,
151
+ isLastSlide,
152
+ }));
153
+ return (react_2.default.createElement("div", { ref: containerRef, className: 'relative select-none overflow-hidden', style: vars },
154
+ react_2.default.createElement("div", { className: 'flex will-change-transform', style: {
155
+ gap: 'var(--phx-slider-gap)',
156
+ transform: 'translate3d(var(--phx-slider-translate), 0, 0)',
157
+ } }, childs.map((child) => {
158
+ const _child = child;
159
+ return react_2.default.createElement(phx_slider_item_1.PHXSliderItem, { key: _child.key }, _child);
160
+ })),
161
+ enableNavigate && (react_2.default.createElement(react_2.default.Fragment, null,
162
+ react_2.default.createElement("button", { className: `absolute inset-y-0 left-0 z-10 flex w-20 cursor-pointer items-center justify-center bg-gradient-to-r from-white via-white/80 to-transparent ${prevDisabled ? 'hidden' : ''}`, onClick: handlePrev, type: 'button' },
163
+ react_2.default.createElement(outline_1.ChevronLeftIcon, { className: 'h-8 w-8' })),
164
+ react_2.default.createElement("button", { className: `absolute inset-y-0 right-0 z-10 flex w-20 cursor-pointer items-center justify-center bg-gradient-to-l from-white via-white/80 to-transparent ${nextDisabled ? 'hidden' : ''}`, onClick: handleNext, type: 'button' },
165
+ react_2.default.createElement(outline_1.ChevronRightIcon, { className: 'h-8 w-8' }))))));
166
+ });
167
+ exports.PHXSlider.displayName = 'PHXSlider';
168
+ //# sourceMappingURL=phx-slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phx-slider.js","sourceRoot":"","sources":["../../../../src/components/Slider/phx-slider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ interface ICreateAnimateProps {
2
+ from: number;
3
+ to: number;
4
+ duration: number;
5
+ onUpdate(value: number): void;
6
+ onEnd?(): void;
7
+ }
8
+ /**
9
+ * Tạo animation
10
+ * @param duration Thời lượng animation
11
+ * @param from Giá trị bắt đầu
12
+ * @param onUpdate Callback khi cập nhật giá trị
13
+ * @param onEnd Callback khi kết thúc
14
+ * @param to Giá trị kết thúc
15
+ */
16
+ export declare const createAnimate: ({ duration, from, onEnd, onUpdate, to }: ICreateAnimateProps) => void;
17
+ export {};