@bailaya/react 1.0.20 → 1.0.21
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/components/StudioTypesList.d.ts +51 -0
- package/dist/components/StudioTypesList.d.ts.map +1 -0
- package/dist/components/StudioTypesList.js +70 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/styles.css +100 -8
- package/package.json +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { StudioType, StudioProfile } from "@bailaya/core";
|
|
3
|
+
export interface StudioTypesListProps {
|
|
4
|
+
overrideId?: string;
|
|
5
|
+
locale?: string;
|
|
6
|
+
/** Root list wrapper */
|
|
7
|
+
className?: string;
|
|
8
|
+
/** Each row/card wrapper */
|
|
9
|
+
itemClassName?: string;
|
|
10
|
+
/** Wrapper around the image */
|
|
11
|
+
imageWrapperClassName?: string;
|
|
12
|
+
/** The `<img>` element itself */
|
|
13
|
+
imageClassName?: string;
|
|
14
|
+
/** Container for title/desc/CTA */
|
|
15
|
+
bodyClassName?: string;
|
|
16
|
+
/** Dance name heading */
|
|
17
|
+
titleClassName?: string;
|
|
18
|
+
/** Optional description paragraph */
|
|
19
|
+
descriptionClassName?: string;
|
|
20
|
+
/** CTA button/link class */
|
|
21
|
+
buttonClassName?: string;
|
|
22
|
+
/** Text for the CTA (i18n-friendly). Default: "See Classes" */
|
|
23
|
+
seeClassesText?: string;
|
|
24
|
+
/** Prefix for the href. Default: "/classes/" */
|
|
25
|
+
hrefPrefix?: string;
|
|
26
|
+
/** Hide the CTA entirely. Default: false */
|
|
27
|
+
hideButton?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Optional link renderer.
|
|
30
|
+
* If not provided, a plain <a> will be rendered.
|
|
31
|
+
*/
|
|
32
|
+
renderLink?: (opts: {
|
|
33
|
+
href: string;
|
|
34
|
+
className?: string;
|
|
35
|
+
children: React.ReactNode;
|
|
36
|
+
}) => React.ReactNode;
|
|
37
|
+
/** Optional custom render per item; bypasses default */
|
|
38
|
+
renderItem?: (type: StudioType, profile: StudioProfile) => React.ReactNode;
|
|
39
|
+
/** Show localized description text. Default: true (since your sample includes it) */
|
|
40
|
+
showDescription?: boolean;
|
|
41
|
+
/** Optional filter/sort hook before render */
|
|
42
|
+
transformTypes?: (types: StudioType[]) => StudioType[];
|
|
43
|
+
/** Optional custom href builder; defaults to hrefPrefix + slug(name) */
|
|
44
|
+
hrefBuilder?: (type: StudioType) => string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* List-style display of studio dance types (Salsa, Bachata, etc.) with optional CTA.
|
|
48
|
+
* Matches your sample Tailwind layout but implemented with low-specificity CSS classes.
|
|
49
|
+
*/
|
|
50
|
+
export declare const StudioTypesList: React.FC<StudioTypesListProps>;
|
|
51
|
+
//# sourceMappingURL=StudioTypesList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StudioTypesList.d.ts","sourceRoot":"","sources":["../../src/components/StudioTypesList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAyB/D,MAAM,WAAW,oBAAoB;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iCAAiC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mCAAmC;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4BAA4B;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE;QAChB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;KAC7B,KAAK,KAAK,CAAC,SAAS,CAAC;IAEtB,wDAAwD;IACxD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,KAAK,KAAK,CAAC,SAAS,CAAC;IAE3E,qFAAqF;IACrF,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8CAA8C;IAC9C,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,CAAC;IAEvD,wEAAwE;IACxE,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,MAAM,CAAC;CAC9C;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4E1D,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.StudioTypesList = void 0;
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const lucide_react_1 = require("lucide-react");
|
|
10
|
+
const useStudioProfile_1 = require("../hooks/useStudioProfile");
|
|
11
|
+
const LoadingIcon_1 = require("./ui/LoadingIcon");
|
|
12
|
+
/** Picks localized text with fallback to first available. */
|
|
13
|
+
function pickLocalizedText(map, locale) {
|
|
14
|
+
const obj = map !== null && map !== void 0 ? map : {};
|
|
15
|
+
if (locale && obj[locale])
|
|
16
|
+
return obj[locale];
|
|
17
|
+
const keys = Object.keys(obj);
|
|
18
|
+
return keys.length ? obj[keys[0]] : "";
|
|
19
|
+
}
|
|
20
|
+
/** Slugify dance names: lower, spaces→hyphens, strip accents & non-alphanum. */
|
|
21
|
+
function slugifyName(name) {
|
|
22
|
+
return name
|
|
23
|
+
.normalize("NFD")
|
|
24
|
+
.replace(/[\u0300-\u036f]/g, "") // strip accents
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
.replace(/[^a-z0-9\s-]/g, "") // remove special chars
|
|
27
|
+
.trim()
|
|
28
|
+
.replace(/\s+/g, "-");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* List-style display of studio dance types (Salsa, Bachata, etc.) with optional CTA.
|
|
32
|
+
* Matches your sample Tailwind layout but implemented with low-specificity CSS classes.
|
|
33
|
+
*/
|
|
34
|
+
const StudioTypesList = ({ overrideId, locale, className = "by-classesList", itemClassName = "by-listCard", imageWrapperClassName = "by-listImageWrap", imageClassName = "by-listImg", bodyClassName = "by-listBody", titleClassName = "by-listTitle", descriptionClassName = "by-listDesc", buttonClassName = "by-btn by-btnList", seeClassesText = "See Classes", hrefPrefix = "/classes/", hideButton = false, renderLink, renderItem, showDescription = true, transformTypes, hrefBuilder, }) => {
|
|
35
|
+
var _a;
|
|
36
|
+
const { data: profile, loading, error } = (0, useStudioProfile_1.useStudioProfile)(overrideId);
|
|
37
|
+
if (loading)
|
|
38
|
+
return react_1.default.createElement("div", { className: className },
|
|
39
|
+
react_1.default.createElement(LoadingIcon_1.LoadingIcon, null));
|
|
40
|
+
if (error)
|
|
41
|
+
return react_1.default.createElement("div", { className: className }, error.message);
|
|
42
|
+
if (!profile || !((_a = profile.studioTypes) === null || _a === void 0 ? void 0 : _a.length))
|
|
43
|
+
return react_1.default.createElement("div", { className: className });
|
|
44
|
+
const types = transformTypes ? transformTypes(profile.studioTypes) : profile.studioTypes;
|
|
45
|
+
return (react_1.default.createElement("div", { className: className }, types.map((type) => {
|
|
46
|
+
if (renderItem) {
|
|
47
|
+
return react_1.default.createElement(react_1.default.Fragment, { key: type.name }, renderItem(type, profile));
|
|
48
|
+
}
|
|
49
|
+
const href = hrefBuilder ? hrefBuilder(type) : `${hrefPrefix}${slugifyName(type.name)}`;
|
|
50
|
+
return (react_1.default.createElement("div", { key: type.name, className: itemClassName },
|
|
51
|
+
type.image && (react_1.default.createElement("div", { className: imageWrapperClassName },
|
|
52
|
+
react_1.default.createElement("img", { src: type.image, alt: type.name, className: imageClassName }))),
|
|
53
|
+
react_1.default.createElement("div", { className: bodyClassName },
|
|
54
|
+
react_1.default.createElement("h3", { className: titleClassName }, type.name),
|
|
55
|
+
showDescription && type.description && (react_1.default.createElement("p", { className: descriptionClassName }, pickLocalizedText(type.description, locale))),
|
|
56
|
+
!hideButton &&
|
|
57
|
+
(renderLink ? (renderLink({
|
|
58
|
+
href,
|
|
59
|
+
className: buttonClassName,
|
|
60
|
+
children: (react_1.default.createElement(react_1.default.Fragment, null,
|
|
61
|
+
seeClassesText,
|
|
62
|
+
" ",
|
|
63
|
+
react_1.default.createElement(lucide_react_1.ArrowRight, null))),
|
|
64
|
+
})) : (react_1.default.createElement("a", { href: href, className: buttonClassName },
|
|
65
|
+
seeClassesText,
|
|
66
|
+
" ",
|
|
67
|
+
react_1.default.createElement(lucide_react_1.ArrowRight, null)))))));
|
|
68
|
+
})));
|
|
69
|
+
};
|
|
70
|
+
exports.StudioTypesList = StudioTypesList;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { ClassSchedule, ClassScheduleProps } from './components/ClassSchedule';
|
|
|
21
21
|
export { ClassScheduleByType, ClassScheduleByTypeProps } from './components/ClassScheduleByType';
|
|
22
22
|
export { InstructorList, InstructorListProps } from './components/InstructorList';
|
|
23
23
|
export { StudioProfileCard, StudioProfileCardProps } from './components/StudioProfileCard';
|
|
24
|
+
export { StudioTypesList, StudioTypesListProps } from './components/StudioTypesList';
|
|
24
25
|
export { StudioTypesGrid, StudioTypesGridProps } from './components/StudioTypesGrid';
|
|
25
26
|
export { UserProfileCard, UserProfileCardProps } from './components/UserProfileCard';
|
|
26
27
|
export { StudioDescription } from './components/StudioDescription';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE9E;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE;;GAEG;AACH,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE9E;;GAEG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D;;GAEG;AACH,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE;;GAEG;AACH,cAAc,SAAS,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
19
19
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.StudioDescription = exports.UserProfileCard = exports.StudioTypesGrid = exports.StudioProfileCard = exports.InstructorList = exports.ClassScheduleByType = exports.ClassSchedule = exports.useClassesByType = exports.useClasses = exports.useInstructors = exports.useStudioProfile = exports.useBailayaClient = exports.BailayaProvider = void 0;
|
|
22
|
+
exports.StudioDescription = exports.UserProfileCard = exports.StudioTypesGrid = exports.StudioTypesList = exports.StudioProfileCard = exports.InstructorList = exports.ClassScheduleByType = exports.ClassSchedule = exports.useClassesByType = exports.useClasses = exports.useInstructors = exports.useStudioProfile = exports.useBailayaClient = exports.BailayaProvider = void 0;
|
|
23
23
|
/**
|
|
24
24
|
* Re-exported context and hooks for easy import
|
|
25
25
|
*/
|
|
@@ -48,6 +48,8 @@ var InstructorList_1 = require("./components/InstructorList");
|
|
|
48
48
|
Object.defineProperty(exports, "InstructorList", { enumerable: true, get: function () { return InstructorList_1.InstructorList; } });
|
|
49
49
|
var StudioProfileCard_1 = require("./components/StudioProfileCard");
|
|
50
50
|
Object.defineProperty(exports, "StudioProfileCard", { enumerable: true, get: function () { return StudioProfileCard_1.StudioProfileCard; } });
|
|
51
|
+
var StudioTypesList_1 = require("./components/StudioTypesList");
|
|
52
|
+
Object.defineProperty(exports, "StudioTypesList", { enumerable: true, get: function () { return StudioTypesList_1.StudioTypesList; } });
|
|
51
53
|
var StudioTypesGrid_1 = require("./components/StudioTypesGrid");
|
|
52
54
|
Object.defineProperty(exports, "StudioTypesGrid", { enumerable: true, get: function () { return StudioTypesGrid_1.StudioTypesGrid; } });
|
|
53
55
|
var UserProfileCard_1 = require("./components/UserProfileCard");
|
package/dist/styles.css
CHANGED
|
@@ -85,15 +85,9 @@
|
|
|
85
85
|
font-weight: 600;
|
|
86
86
|
color: var(--by-color-heading);
|
|
87
87
|
padding-bottom: var(--by-title-pb);
|
|
88
|
-
text-align:
|
|
88
|
+
text-align: center;
|
|
89
89
|
line-height: 1.1;
|
|
90
|
-
font-size:
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
@media (min-width: 768px) {
|
|
94
|
-
:where(.by-title) {
|
|
95
|
-
font-size: 3rem;
|
|
96
|
-
}
|
|
90
|
+
font-size: 1rem;
|
|
97
91
|
}
|
|
98
92
|
|
|
99
93
|
/* Description */
|
|
@@ -133,3 +127,101 @@
|
|
|
133
127
|
:where(.by-btn svg) {
|
|
134
128
|
flex-shrink: 0;
|
|
135
129
|
}
|
|
130
|
+
|
|
131
|
+
/* Container */
|
|
132
|
+
:where(.by-classesList) {
|
|
133
|
+
margin-top: 1.5rem;
|
|
134
|
+
display: flex;
|
|
135
|
+
flex-direction: column;
|
|
136
|
+
row-gap: 2rem;
|
|
137
|
+
}
|
|
138
|
+
@media (min-width: 768px) {
|
|
139
|
+
:where(.by-classesList) {
|
|
140
|
+
margin-top: 3rem;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Card */
|
|
145
|
+
:where(.by-listCard) {
|
|
146
|
+
display: flex;
|
|
147
|
+
flex-direction: column;
|
|
148
|
+
align-items: center;
|
|
149
|
+
border: 1px solid var(--by-border);
|
|
150
|
+
border-radius: var(--by-radius-lg);
|
|
151
|
+
box-shadow: var(--by-shadow);
|
|
152
|
+
overflow: hidden;
|
|
153
|
+
background: #fff;
|
|
154
|
+
}
|
|
155
|
+
@media (min-width: 768px) {
|
|
156
|
+
:where(.by-listCard) {
|
|
157
|
+
flex-direction: row;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Image wrapper */
|
|
162
|
+
:where(.by-listImageWrap) {
|
|
163
|
+
width: 100%;
|
|
164
|
+
padding: 1rem;
|
|
165
|
+
aspect-ratio: 1 / 1;
|
|
166
|
+
}
|
|
167
|
+
@media (min-width: 768px) {
|
|
168
|
+
:where(.by-listImageWrap) {
|
|
169
|
+
width: 25%;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* Image */
|
|
174
|
+
:where(.by-listImg) {
|
|
175
|
+
width: 100%;
|
|
176
|
+
height: 100%;
|
|
177
|
+
object-fit: cover;
|
|
178
|
+
display: block;
|
|
179
|
+
border-radius: 1rem;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* Body */
|
|
183
|
+
:where(.by-listBody) {
|
|
184
|
+
padding: 1.5rem;
|
|
185
|
+
padding-top: 0;
|
|
186
|
+
flex: 1 1 auto;
|
|
187
|
+
text-align: left;
|
|
188
|
+
font-family: var(--by-body-font);
|
|
189
|
+
color: var(--by-color-text);
|
|
190
|
+
}
|
|
191
|
+
@media (min-width: 768px) {
|
|
192
|
+
:where(.by-listBody) {
|
|
193
|
+
padding-top: 1.5rem;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/* Title */
|
|
198
|
+
:where(.by-listTitle) {
|
|
199
|
+
font-family: var(--by-heading-font);
|
|
200
|
+
font-weight: 600;
|
|
201
|
+
color: var(--by-color-heading);
|
|
202
|
+
line-height: 1.1;
|
|
203
|
+
font-size: 1.875rem;
|
|
204
|
+
}
|
|
205
|
+
@media (min-width: 768px) {
|
|
206
|
+
:where(.by-listTitle) {
|
|
207
|
+
font-size: 3rem;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/* Description */
|
|
212
|
+
:where(.by-listDesc) {
|
|
213
|
+
margin-top: 0.5rem;
|
|
214
|
+
color: var(--by-color-text);
|
|
215
|
+
font-weight: 600;
|
|
216
|
+
font-size: 0.75rem;
|
|
217
|
+
}
|
|
218
|
+
@media (min-width: 768px) {
|
|
219
|
+
:where(.by-listDesc) {
|
|
220
|
+
font-size: 1.25rem;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* Button spacing */
|
|
225
|
+
:where(.by-btnList) {
|
|
226
|
+
margin-top: 1rem;
|
|
227
|
+
}
|