beem-component 2.1.4 → 2.1.6

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.
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ const hexToRgba = function (hex) {
11
+ let opacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.6;
12
+ try {
13
+ const normalizedHex = hex === null || hex === void 0 ? void 0 : hex.replace('#', '');
14
+ if (!normalizedHex || normalizedHex.length !== 6 || !/^[0-9a-fA-F]{6}$/.test(normalizedHex)) {
15
+ throw new Error('Invalid hex');
16
+ }
17
+ const r = parseInt(normalizedHex.slice(0, 2), 16);
18
+ const g = parseInt(normalizedHex.slice(2, 4), 16);
19
+ const b = parseInt(normalizedHex.slice(4, 6), 16);
20
+ return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(opacity, ")");
21
+ } catch (e) {
22
+ return "rgba(0, 0, 0, ".concat(opacity, ")");
23
+ }
24
+ };
25
+ const AlertWrapper = _styledComponents.default.div.withConfig({
26
+ displayName: "Alert__AlertWrapper"
27
+ })(["border:1px solid ", ";background-color:", ";border-radius:0.5rem;padding:0.75rem;@media (min-width:640px){padding:1rem;}"], _ref => {
28
+ let {
29
+ themeColor
30
+ } = _ref;
31
+ return hexToRgba(themeColor, 0.2);
32
+ }, _ref2 => {
33
+ let {
34
+ themeColor
35
+ } = _ref2;
36
+ return hexToRgba(themeColor, 0.05);
37
+ });
38
+ const Content = _styledComponents.default.div.withConfig({
39
+ displayName: "Alert__Content"
40
+ })(["display:flex;align-items:flex-start;gap:0.75rem;"]);
41
+ const IconContainer = _styledComponents.default.div.withConfig({
42
+ displayName: "Alert__IconContainer"
43
+ })(["background-color:", ";border-radius:9999px;display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;margin-top:0.125rem;@media (min-width:640px){width:2.1rem;height:2.1rem;}svg{width:1rem;height:1rem;color:", ";@media (min-width:640px){width:1.25rem;height:1.25rem;}}"], _ref3 => {
44
+ let {
45
+ themeColor
46
+ } = _ref3;
47
+ return hexToRgba(themeColor, 0.1);
48
+ }, _ref4 => {
49
+ let {
50
+ themeColor
51
+ } = _ref4;
52
+ return themeColor;
53
+ });
54
+ const TextContent = _styledComponents.default.div.withConfig({
55
+ displayName: "Alert__TextContent"
56
+ })(["flex:1;"]);
57
+ const Title = _styledComponents.default.h3.withConfig({
58
+ displayName: "Alert__Title"
59
+ })(["font-weight:500;color:", ";font-size:0.875rem;margin-bottom:0.25rem;"], _ref5 => {
60
+ let {
61
+ themeColor
62
+ } = _ref5;
63
+ return themeColor;
64
+ });
65
+ const Description = _styledComponents.default.p.withConfig({
66
+ displayName: "Alert__Description"
67
+ })(["color:#6b7280;font-size:0.75rem;@media (min-width:640px){font-size:0.875rem;}"]);
68
+ const AlertBox = _ref6 => {
69
+ let {
70
+ icon: Icon,
71
+ themeColor = '#EF4444',
72
+ title,
73
+ description
74
+ } = _ref6;
75
+ return /*#__PURE__*/_react.default.createElement(AlertWrapper, {
76
+ themeColor: themeColor
77
+ }, /*#__PURE__*/_react.default.createElement(Content, null, Icon && /*#__PURE__*/_react.default.createElement(IconContainer, {
78
+ themeColor: themeColor
79
+ }, /*#__PURE__*/_react.default.createElement(Icon, null)), /*#__PURE__*/_react.default.createElement(TextContent, null, /*#__PURE__*/_react.default.createElement(Title, {
80
+ themeColor: themeColor
81
+ }, title), /*#__PURE__*/_react.default.createElement(Description, null, description))));
82
+ };
83
+ var _default = exports.default = AlertBox;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Example = exports.Default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _AccessTime = _interopRequireDefault(require("@mui/icons-material/AccessTime"));
9
+ var _Person = _interopRequireDefault(require("@mui/icons-material/Person"));
10
+ var _CalendarTodayOutlined = _interopRequireDefault(require("@mui/icons-material/CalendarTodayOutlined"));
11
+ var _Alert = _interopRequireDefault(require("./Alert"));
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const iconOptions = {
14
+ AccessTimeIcon: _AccessTime.default,
15
+ PersonIcon: _Person.default,
16
+ CalendarTodayOutlinedIcon: _CalendarTodayOutlined.default,
17
+ None: null
18
+ };
19
+ const Template = args => {
20
+ return /*#__PURE__*/_react.default.createElement("div", {
21
+ style: {
22
+ maxWidth: 500,
23
+ margin: '2rem auto'
24
+ }
25
+ }, /*#__PURE__*/_react.default.createElement(_Alert.default, args));
26
+ };
27
+ const Default = exports.Default = Template.bind({});
28
+ Default.args = {
29
+ icon: _AccessTime.default,
30
+ themeColor: '#EF4444',
31
+ title: 'Submission Failed',
32
+ description: 'There was an issue processing your request. Please try again later.'
33
+ };
34
+ Default.argTypes = {
35
+ icon: {
36
+ control: {
37
+ type: 'select',
38
+ labels: Object.keys(iconOptions)
39
+ },
40
+ options: Object.keys(iconOptions),
41
+ mapping: iconOptions
42
+ },
43
+ themeColor: {
44
+ control: 'color'
45
+ },
46
+ title: {
47
+ control: 'text'
48
+ },
49
+ description: {
50
+ control: 'text'
51
+ }
52
+ };
53
+ var _default = exports.default = {
54
+ title: 'Components/AlertBox',
55
+ component: _Alert.default,
56
+ argTypes: Default.argTypes
57
+ };
58
+ const Example = () => {
59
+ return /*#__PURE__*/_react.default.createElement(_Alert.default, {
60
+ icon: _AccessTime.default,
61
+ themeColor: "#DC2626",
62
+ title: "Payment Error",
63
+ description: "We couldn't process your payment. Please try again later or contact support."
64
+ });
65
+ };
66
+ exports.Example = Example;
@@ -0,0 +1,174 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _styledComponents = _interopRequireDefault(require("styled-components"));
9
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
+ const hexToRgba = function (hex) {
11
+ let opacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0.6;
12
+ try {
13
+ const normalizedHex = hex === null || hex === void 0 ? void 0 : hex.replace('#', '');
14
+ if (!normalizedHex || normalizedHex.length !== 6 || !/^[0-9a-fA-F]{6}$/.test(normalizedHex)) {
15
+ throw new Error('Invalid hex');
16
+ }
17
+ const r = parseInt(normalizedHex.slice(0, 2), 16);
18
+ const g = parseInt(normalizedHex.slice(2, 4), 16);
19
+ const b = parseInt(normalizedHex.slice(4, 6), 16);
20
+ return "rgba(".concat(r, ", ").concat(g, ", ").concat(b, ", ").concat(opacity, ")");
21
+ } catch (e) {
22
+ return "rgba(0, 0, 0, ".concat(opacity, ")");
23
+ }
24
+ };
25
+ const BackgroundStripe = _styledComponents.default.div.withConfig({
26
+ displayName: "CustomCardTitle__BackgroundStripe"
27
+ })(["background-color:", ";padding-top:", ";padding-bottom:", ";padding-left:1rem;padding-right:1rem;@media (min-width:640px){padding-top:", ";padding-bottom:", ";padding-left:1.5rem;padding-right:1.5rem;}"], _ref => {
28
+ let {
29
+ themeColor
30
+ } = _ref;
31
+ return hexToRgba(themeColor, 0.1);
32
+ }, _ref2 => {
33
+ let {
34
+ variant
35
+ } = _ref2;
36
+ return variant === 'confirmation' ? '1rem' : '1.5rem';
37
+ }, _ref3 => {
38
+ let {
39
+ variant
40
+ } = _ref3;
41
+ return variant === 'confirmation' ? '1rem' : '2rem';
42
+ }, _ref4 => {
43
+ let {
44
+ variant
45
+ } = _ref4;
46
+ return variant === 'confirmation' ? '1.5rem' : '2rem';
47
+ }, _ref5 => {
48
+ let {
49
+ variant
50
+ } = _ref5;
51
+ return variant === 'confirmation' ? '1.5rem' : '2.5rem';
52
+ });
53
+ const CardContainer = _styledComponents.default.div.withConfig({
54
+ displayName: "CustomCardTitle__CardContainer"
55
+ })(["background-color:", ";padding:1rem;border-radius:0.75rem;@media (min-width:640px){padding:1.5rem;}"], hexToRgba('#ffffff', 0.7));
56
+ const IconWrapper = _styledComponents.default.div.withConfig({
57
+ displayName: "CustomCardTitle__IconWrapper"
58
+ })(["background-color:", ";border:2px solid ", ";height:", ";width:", ";border-radius:9999px;display:flex;align-items:center;justify-content:center;margin:0 auto ", ";@media (min-width:640px){height:", ";width:", ";margin-bottom:", ";}svg{height:", ";width:", ";color:", ";@media (min-width:640px){height:", ";width:", ";}}"], _ref6 => {
59
+ let {
60
+ themeColor
61
+ } = _ref6;
62
+ return hexToRgba(themeColor, 0.1);
63
+ }, _ref7 => {
64
+ let {
65
+ themeColor
66
+ } = _ref7;
67
+ return themeColor;
68
+ }, _ref8 => {
69
+ let {
70
+ variant
71
+ } = _ref8;
72
+ return variant === 'confirmation' ? '3.5rem' : '4rem';
73
+ }, _ref9 => {
74
+ let {
75
+ variant
76
+ } = _ref9;
77
+ return variant === 'confirmation' ? '3.5rem' : '4rem';
78
+ }, _ref0 => {
79
+ let {
80
+ variant
81
+ } = _ref0;
82
+ return variant === 'confirmation' ? '0.75rem' : '1rem';
83
+ }, _ref1 => {
84
+ let {
85
+ variant
86
+ } = _ref1;
87
+ return variant === 'confirmation' ? '4rem' : '5rem';
88
+ }, _ref10 => {
89
+ let {
90
+ variant
91
+ } = _ref10;
92
+ return variant === 'confirmation' ? '4rem' : '5rem';
93
+ }, _ref11 => {
94
+ let {
95
+ variant
96
+ } = _ref11;
97
+ return variant === 'confirmation' ? '1rem' : '1.25rem';
98
+ }, _ref12 => {
99
+ let {
100
+ variant
101
+ } = _ref12;
102
+ return variant === 'confirmation' ? '1.75rem' : '2rem';
103
+ }, _ref13 => {
104
+ let {
105
+ variant
106
+ } = _ref13;
107
+ return variant === 'confirmation' ? '1.75rem' : '2rem';
108
+ }, _ref14 => {
109
+ let {
110
+ themeColor
111
+ } = _ref14;
112
+ return themeColor;
113
+ }, _ref15 => {
114
+ let {
115
+ variant
116
+ } = _ref15;
117
+ return variant === 'confirmation' ? '2rem' : '2.5rem';
118
+ }, _ref16 => {
119
+ let {
120
+ variant
121
+ } = _ref16;
122
+ return variant === 'confirmation' ? '2rem' : '2.5rem';
123
+ });
124
+ const Title = _styledComponents.default.h2.withConfig({
125
+ displayName: "CustomCardTitle__Title"
126
+ })(["text-align:center;font-size:1.125rem;margin-bottom:", ";@media (min-width:640px){font-size:1.25rem;margin-bottom:", ";}"], _ref17 => {
127
+ let {
128
+ variant
129
+ } = _ref17;
130
+ return variant === 'confirmation' ? '0.25rem' : '0.5rem';
131
+ }, _ref18 => {
132
+ let {
133
+ variant
134
+ } = _ref18;
135
+ return variant === 'confirmation' ? '0.5rem' : '0.75rem';
136
+ });
137
+ const Description = _styledComponents.default.p.withConfig({
138
+ displayName: "CustomCardTitle__Description"
139
+ })(["text-align:center;font-size:", ";color:#6b7280;@media (min-width:640px){font-size:", ";}"], _ref19 => {
140
+ let {
141
+ variant
142
+ } = _ref19;
143
+ return variant === 'confirmation' ? '0.75rem' : '0.875rem';
144
+ }, _ref20 => {
145
+ let {
146
+ variant
147
+ } = _ref20;
148
+ return variant === 'confirmation' ? '0.875rem' : '1rem';
149
+ });
150
+ const BmCustomCardTitle = _ref21 => {
151
+ let {
152
+ icon: Icon,
153
+ themeColor = '#33B1BA',
154
+ title,
155
+ description,
156
+ variant = 'booking',
157
+ withStripe = false
158
+ } = _ref21;
159
+ const content = /*#__PURE__*/_react.default.createElement(CardContainer, {
160
+ variant: variant
161
+ }, /*#__PURE__*/_react.default.createElement(IconWrapper, {
162
+ themeColor: themeColor,
163
+ variant: variant
164
+ }, Icon && /*#__PURE__*/_react.default.createElement(Icon, null)), title && /*#__PURE__*/_react.default.createElement(Title, {
165
+ variant: variant
166
+ }, title), description && /*#__PURE__*/_react.default.createElement(Description, {
167
+ variant: variant
168
+ }, description));
169
+ return withStripe ? /*#__PURE__*/_react.default.createElement(BackgroundStripe, {
170
+ themeColor: themeColor,
171
+ variant: variant
172
+ }, content) : content;
173
+ };
174
+ var _default = exports.default = BmCustomCardTitle;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.Example = exports.Default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _CalendarTodayOutlined = _interopRequireDefault(require("@mui/icons-material/CalendarTodayOutlined"));
9
+ var _Check = _interopRequireDefault(require("@mui/icons-material/Check"));
10
+ var _AccessTime = _interopRequireDefault(require("@mui/icons-material/AccessTime"));
11
+ var _Favorite = _interopRequireDefault(require("@mui/icons-material/Favorite"));
12
+ var _CustomCardTitle = _interopRequireDefault(require("./CustomCardTitle"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ // MUI icons
15
+
16
+ // Icon options mapped by name
17
+ const iconOptions = {
18
+ Calendar: _CalendarTodayOutlined.default,
19
+ Check: _Check.default,
20
+ Clock: _AccessTime.default,
21
+ Heart: _Favorite.default
22
+ };
23
+ const Template = args => {
24
+ return /*#__PURE__*/_react.default.createElement("div", {
25
+ style: {
26
+ maxWidth: 500,
27
+ margin: '2rem auto'
28
+ }
29
+ }, /*#__PURE__*/_react.default.createElement(_CustomCardTitle.default, args));
30
+ };
31
+ const Default = exports.Default = Template.bind({});
32
+ Default.args = {
33
+ icon: _CalendarTodayOutlined.default,
34
+ themeColor: '#33B1BA',
35
+ title: 'Book Your Medical Appointment',
36
+ description: 'Schedule a 30-minute consultation with our healthcare specialists',
37
+ variant: 'booking',
38
+ withStripe: true
39
+ };
40
+ Default.argTypes = {
41
+ icon: {
42
+ control: {
43
+ type: 'select',
44
+ labels: Object.keys(iconOptions)
45
+ },
46
+ options: Object.keys(iconOptions),
47
+ mapping: iconOptions
48
+ },
49
+ themeColor: {
50
+ control: 'color'
51
+ },
52
+ title: {
53
+ control: 'text'
54
+ },
55
+ description: {
56
+ control: 'text'
57
+ },
58
+ variant: {
59
+ control: {
60
+ type: 'radio'
61
+ },
62
+ options: ['booking', 'confirmation']
63
+ },
64
+ withStripe: {
65
+ control: {
66
+ type: 'boolean'
67
+ }
68
+ }
69
+ };
70
+ var _default = exports.default = {
71
+ title: 'Components/BmCustomCardTitle',
72
+ component: _CustomCardTitle.default,
73
+ argTypes: Default.argTypes
74
+ };
75
+ const Example = () => {
76
+ /*#__PURE__*/_react.default.createElement(_CustomCardTitle.default, {
77
+ icon: _CalendarTodayOutlined.default,
78
+ themeColor: "#33B1BA",
79
+ title: "Book Your Medical Appointment",
80
+ description: "Schedule a 30-minute consultation with our healthcare specialists",
81
+ variant: "booking",
82
+ withStripe: true
83
+ });
84
+ };
85
+ exports.Example = Example;
@@ -30,7 +30,7 @@ const SectionSummaryContainer = _styledComponents.default.div.withConfig({
30
30
  })(["display:flex;align-items:center;margin-bottom:1rem;@media (min-width:45.7143rem){margin-bottom:1.25rem;}"]);
31
31
  const IconBox = _styledComponents.default.div.withConfig({
32
32
  displayName: "InfoPanel__IconBox"
33
- })(["display:flex;align-items:center;justify-content:center;text-align:center;margin-right:0.5rem;padding:0.5rem;border-radius:714.2143rem;background-color:", ";svg{height:1.2rem;width:1.2rem;color:", ";@media (min-width:45.7143rem){height:1.5rem;width:1.5rem;}}"], _ref => {
33
+ })(["display:flex;align-items:center;justify-content:center;text-align:center;margin-right:0.5rem;padding:0.5rem;border-radius:714.2143rem;background-color:", ";svg{height:1.2rem;width:1.2rem;color:", ";@media (min-width:45.7143rem){height:1.4rem;width:1.4rem;}}"], _ref => {
34
34
  let {
35
35
  iconBackgroundColor,
36
36
  iconColor
@@ -166,6 +166,12 @@ Object.defineProperty(exports, "BmCounter", {
166
166
  return _messageCounter.default;
167
167
  }
168
168
  });
169
+ Object.defineProperty(exports, "BmCustomCardTitle", {
170
+ enumerable: true,
171
+ get: function () {
172
+ return _CustomCardTitle.default;
173
+ }
174
+ });
169
175
  Object.defineProperty(exports, "BmEmojiIcon", {
170
176
  enumerable: true,
171
177
  get: function () {
@@ -465,5 +471,6 @@ var _LabelWithIcon = _interopRequireDefault(require("./LabelWithIcon/LabelWithIc
465
471
  var _Card = require("./Card_v2/Card");
466
472
  var _InfoPanel = _interopRequireDefault(require("./InfoPanel/InfoPanel"));
467
473
  var _BmSelector = _interopRequireDefault(require("./BmSelector/BmSelector"));
474
+ var _CustomCardTitle = _interopRequireDefault(require("./BmCustomCardTitle/CustomCardTitle"));
468
475
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
469
476
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beem-component",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "private": false,
5
5
  "main": "dist/components/index.js",
6
6
  "scripts": {
package/src/App.js CHANGED
@@ -7,6 +7,8 @@ import React, { useState } from 'react';
7
7
  // import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
8
8
  import AccessTimeIcon from '@mui/icons-material/AccessTime';
9
9
  import PersonIcon from '@mui/icons-material/Person';
10
+ import CalendarTodayOutlinedIcon from '@mui/icons-material/CalendarTodayOutlined';
11
+ import CheckIcon from '@mui/icons-material/Check';
10
12
  // import { Tooltip } from '@mui/material';
11
13
  import PeopleIcon from '@mui/icons-material/People';
12
14
  // import BusinessIcon from '@mui/icons-material/Business';
@@ -33,7 +35,9 @@ import {
33
35
  BmButton,
34
36
  BmSelectionNotice,
35
37
  BmSelector,
38
+ BmCustomCardTitle,
36
39
  } from './lib/components';
40
+ import AlertBox from './lib/components/Alert/Alert';
37
41
  // import ProgressIndicator from './lib/components/newProgress';
38
42
 
39
43
  // const datsa = JSON.stringify({
@@ -1006,7 +1010,42 @@ const Chat = () => {
1006
1010
  return (
1007
1011
  <>
1008
1012
  <GlobalStyle />
1009
-
1013
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '2rem' }}>
1014
+ <div>
1015
+ <BmInfoPanel.SectionSummary
1016
+ iconColor="#33B1BA"
1017
+ textColor="#fcba03"
1018
+ icon={CalendarTodayOutlinedIcon}
1019
+ title={formData.departmentName}
1020
+ subtitle="Department"
1021
+ // iconBackgroundColor
1022
+ />
1023
+ <AlertBox
1024
+ icon={AccessTimeIcon}
1025
+ themeColor="#DC2626"
1026
+ title="Payment Error"
1027
+ description="We couldn't process your payment. Please try again later or contact support."
1028
+ />
1029
+ <BmCustomCardTitle
1030
+ icon={CalendarTodayOutlinedIcon}
1031
+ themeColor="#33B1BA"
1032
+ title="Book Your Medical Appointment"
1033
+ description="Schedule a 30-minute consultation with our healthcare specialists"
1034
+ variant="booking"
1035
+ withStripe
1036
+ />
1037
+ </div>
1038
+ <div>
1039
+ <BmCustomCardTitle
1040
+ icon={CheckIcon}
1041
+ themeColor="#33B1BA"
1042
+ title="Appointment Confirmed!"
1043
+ description="Your booking has been successfully scheduled"
1044
+ variant="confirmation"
1045
+ withStripe
1046
+ />
1047
+ </div>
1048
+ </div>
1010
1049
  <div style={{ maxWidth: '600px', margin: '2rem auto' }}>
1011
1050
  <div style={{ padding: '2rem' }}>
1012
1051
  <h1>Progress Indicator Demo</h1>
@@ -0,0 +1,111 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ const hexToRgba = (hex, opacity = 0.6) => {
5
+ try {
6
+ const normalizedHex = hex?.replace('#', '');
7
+ if (
8
+ !normalizedHex ||
9
+ normalizedHex.length !== 6 ||
10
+ !/^[0-9a-fA-F]{6}$/.test(normalizedHex)
11
+ ) {
12
+ throw new Error('Invalid hex');
13
+ }
14
+
15
+ const r = parseInt(normalizedHex.slice(0, 2), 16);
16
+ const g = parseInt(normalizedHex.slice(2, 4), 16);
17
+ const b = parseInt(normalizedHex.slice(4, 6), 16);
18
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
19
+ } catch (e) {
20
+ return `rgba(0, 0, 0, ${opacity})`;
21
+ }
22
+ };
23
+
24
+ const AlertWrapper = styled.div`
25
+ border: 1px solid ${({ themeColor }) => hexToRgba(themeColor, 0.2)};
26
+ background-color: ${({ themeColor }) => hexToRgba(themeColor, 0.05)};
27
+ border-radius: 0.5rem;
28
+ padding: 0.75rem;
29
+
30
+ @media (min-width: 640px) {
31
+ padding: 1rem;
32
+ }
33
+ `;
34
+
35
+ const Content = styled.div`
36
+ display: flex;
37
+ align-items: flex-start;
38
+ gap: 0.75rem;
39
+ `;
40
+
41
+ const IconContainer = styled.div`
42
+ background-color: ${({ themeColor }) => hexToRgba(themeColor, 0.1)};
43
+ border-radius: 9999px;
44
+ display: flex;
45
+ align-items: center;
46
+ justify-content: center;
47
+ width: 2rem;
48
+ height: 2rem;
49
+ margin-top: 0.125rem;
50
+
51
+ @media (min-width: 640px) {
52
+ width: 2.1rem;
53
+ height: 2.1rem;
54
+ }
55
+
56
+ svg {
57
+ width: 1rem;
58
+ height: 1rem;
59
+ color: ${({ themeColor }) => themeColor};
60
+
61
+ @media (min-width: 640px) {
62
+ width: 1.25rem;
63
+ height: 1.25rem;
64
+ }
65
+ }
66
+ `;
67
+
68
+ const TextContent = styled.div`
69
+ flex: 1;
70
+ `;
71
+
72
+ const Title = styled.h3`
73
+ font-weight: 500;
74
+ color: ${({ themeColor }) => themeColor};
75
+ font-size: 0.875rem;
76
+ margin-bottom: 0.25rem;
77
+ `;
78
+
79
+ const Description = styled.p`
80
+ color: #6b7280;
81
+ font-size: 0.75rem;
82
+
83
+ @media (min-width: 640px) {
84
+ font-size: 0.875rem;
85
+ }
86
+ `;
87
+
88
+ const AlertBox = ({
89
+ icon: Icon,
90
+ themeColor = '#EF4444',
91
+ title,
92
+ description,
93
+ }) => {
94
+ return (
95
+ <AlertWrapper themeColor={themeColor}>
96
+ <Content>
97
+ {Icon && (
98
+ <IconContainer themeColor={themeColor}>
99
+ <Icon />
100
+ </IconContainer>
101
+ )}
102
+ <TextContent>
103
+ <Title themeColor={themeColor}>{title}</Title>
104
+ <Description>{description}</Description>
105
+ </TextContent>
106
+ </Content>
107
+ </AlertWrapper>
108
+ );
109
+ };
110
+
111
+ export default AlertBox;
@@ -0,0 +1,66 @@
1
+ import React from 'react';
2
+ import AccessTimeIcon from '@mui/icons-material/AccessTime';
3
+ import PersonIcon from '@mui/icons-material/Person';
4
+ import CalendarTodayOutlinedIcon from '@mui/icons-material/CalendarTodayOutlined';
5
+ import AlertBox from './Alert';
6
+
7
+ const iconOptions = {
8
+ AccessTimeIcon,
9
+ PersonIcon,
10
+ CalendarTodayOutlinedIcon,
11
+ None: null,
12
+ };
13
+
14
+ const Template = (args) => {
15
+ return (
16
+ <div style={{ maxWidth: 500, margin: '2rem auto' }}>
17
+ <AlertBox {...args} />
18
+ </div>
19
+ );
20
+ };
21
+
22
+ export const Default = Template.bind({});
23
+ Default.args = {
24
+ icon: AccessTimeIcon,
25
+ themeColor: '#EF4444',
26
+ title: 'Submission Failed',
27
+ description:
28
+ 'There was an issue processing your request. Please try again later.',
29
+ };
30
+
31
+ Default.argTypes = {
32
+ icon: {
33
+ control: {
34
+ type: 'select',
35
+ labels: Object.keys(iconOptions),
36
+ },
37
+ options: Object.keys(iconOptions),
38
+ mapping: iconOptions,
39
+ },
40
+ themeColor: {
41
+ control: 'color',
42
+ },
43
+ title: {
44
+ control: 'text',
45
+ },
46
+ description: {
47
+ control: 'text',
48
+ },
49
+ };
50
+
51
+ export default {
52
+ title: 'Components/AlertBox',
53
+ component: AlertBox,
54
+ argTypes: Default.argTypes,
55
+ };
56
+
57
+ export const Example = () => {
58
+ return (
59
+ <AlertBox
60
+ icon={AccessTimeIcon}
61
+ themeColor="#DC2626"
62
+ title="Payment Error"
63
+ description="We couldn't process your payment. Please try again later or contact support."
64
+ />
65
+ );
66
+ };
@@ -0,0 +1,142 @@
1
+ import React from 'react';
2
+ import styled from 'styled-components';
3
+
4
+ const hexToRgba = (hex, opacity = 0.6) => {
5
+ try {
6
+ const normalizedHex = hex?.replace('#', '');
7
+ if (
8
+ !normalizedHex ||
9
+ normalizedHex.length !== 6 ||
10
+ !/^[0-9a-fA-F]{6}$/.test(normalizedHex)
11
+ ) {
12
+ throw new Error('Invalid hex');
13
+ }
14
+
15
+ const r = parseInt(normalizedHex.slice(0, 2), 16);
16
+ const g = parseInt(normalizedHex.slice(2, 4), 16);
17
+ const b = parseInt(normalizedHex.slice(4, 6), 16);
18
+ return `rgba(${r}, ${g}, ${b}, ${opacity})`;
19
+ } catch (e) {
20
+ return `rgba(0, 0, 0, ${opacity})`;
21
+ }
22
+ };
23
+
24
+ const BackgroundStripe = styled.div`
25
+ background-color: ${({ themeColor }) => hexToRgba(themeColor, 0.1)};
26
+ padding-top: ${({ variant }) =>
27
+ variant === 'confirmation' ? '1rem' : '1.5rem'};
28
+ padding-bottom: ${({ variant }) =>
29
+ variant === 'confirmation' ? '1rem' : '2rem'};
30
+ padding-left: 1rem;
31
+ padding-right: 1rem;
32
+
33
+ @media (min-width: 640px) {
34
+ padding-top: ${({ variant }) =>
35
+ variant === 'confirmation' ? '1.5rem' : '2rem'};
36
+ padding-bottom: ${({ variant }) =>
37
+ variant === 'confirmation' ? '1.5rem' : '2.5rem'};
38
+ padding-left: 1.5rem;
39
+ padding-right: 1.5rem;
40
+ }
41
+ `;
42
+
43
+ const CardContainer = styled.div`
44
+ background-color: ${hexToRgba('#ffffff', 0.7)};
45
+ padding: 1rem;
46
+ border-radius: 0.75rem;
47
+
48
+ @media (min-width: 640px) {
49
+ padding: 1.5rem;
50
+ }
51
+ `;
52
+
53
+ const IconWrapper = styled.div`
54
+ background-color: ${({ themeColor }) => hexToRgba(themeColor, 0.1)};
55
+ border: 2px solid ${({ themeColor }) => themeColor};
56
+ height: ${({ variant }) => (variant === 'confirmation' ? '3.5rem' : '4rem')};
57
+ width: ${({ variant }) => (variant === 'confirmation' ? '3.5rem' : '4rem')};
58
+ border-radius: 9999px;
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ margin: 0 auto
63
+ ${({ variant }) => (variant === 'confirmation' ? '0.75rem' : '1rem')};
64
+
65
+ @media (min-width: 640px) {
66
+ height: ${({ variant }) => (variant === 'confirmation' ? '4rem' : '5rem')};
67
+ width: ${({ variant }) => (variant === 'confirmation' ? '4rem' : '5rem')};
68
+ margin-bottom: ${({ variant }) =>
69
+ variant === 'confirmation' ? '1rem' : '1.25rem'};
70
+ }
71
+
72
+ svg {
73
+ height: ${({ variant }) =>
74
+ variant === 'confirmation' ? '1.75rem' : '2rem'};
75
+ width: ${({ variant }) =>
76
+ variant === 'confirmation' ? '1.75rem' : '2rem'};
77
+ color: ${({ themeColor }) => themeColor};
78
+
79
+ @media (min-width: 640px) {
80
+ height: ${({ variant }) =>
81
+ variant === 'confirmation' ? '2rem' : '2.5rem'};
82
+ width: ${({ variant }) =>
83
+ variant === 'confirmation' ? '2rem' : '2.5rem'};
84
+ }
85
+ }
86
+ `;
87
+
88
+ const Title = styled.h2`
89
+ text-align: center;
90
+ font-size: 1.125rem;
91
+ margin-bottom: ${({ variant }) =>
92
+ variant === 'confirmation' ? '0.25rem' : '0.5rem'};
93
+
94
+ @media (min-width: 640px) {
95
+ font-size: 1.25rem;
96
+ margin-bottom: ${({ variant }) =>
97
+ variant === 'confirmation' ? '0.5rem' : '0.75rem'};
98
+ }
99
+ `;
100
+
101
+ const Description = styled.p`
102
+ text-align: center;
103
+ font-size: ${({ variant }) =>
104
+ variant === 'confirmation' ? '0.75rem' : '0.875rem'};
105
+ color: #6b7280;
106
+
107
+ @media (min-width: 640px) {
108
+ font-size: ${({ variant }) =>
109
+ variant === 'confirmation' ? '0.875rem' : '1rem'};
110
+ }
111
+ `;
112
+
113
+ const BmCustomCardTitle = ({
114
+ icon: Icon,
115
+ themeColor = '#33B1BA',
116
+ title,
117
+ description,
118
+ variant = 'booking',
119
+ withStripe = false,
120
+ }) => {
121
+ const content = (
122
+ <CardContainer variant={variant}>
123
+ <IconWrapper themeColor={themeColor} variant={variant}>
124
+ {Icon && <Icon />}
125
+ </IconWrapper>
126
+ {title && <Title variant={variant}>{title}</Title>}
127
+ {description && (
128
+ <Description variant={variant}>{description}</Description>
129
+ )}
130
+ </CardContainer>
131
+ );
132
+
133
+ return withStripe ? (
134
+ <BackgroundStripe themeColor={themeColor} variant={variant}>
135
+ {content}
136
+ </BackgroundStripe>
137
+ ) : (
138
+ content
139
+ );
140
+ };
141
+
142
+ export default BmCustomCardTitle;
@@ -0,0 +1,83 @@
1
+ import React from 'react';
2
+
3
+ // MUI icons
4
+ import CalendarTodayOutlinedIcon from '@mui/icons-material/CalendarTodayOutlined';
5
+ import CheckIcon from '@mui/icons-material/Check';
6
+ import AccessTimeIcon from '@mui/icons-material/AccessTime';
7
+ import FavoriteIcon from '@mui/icons-material/Favorite';
8
+ import BmCustomCardTitle from './CustomCardTitle';
9
+
10
+ // Icon options mapped by name
11
+ const iconOptions = {
12
+ Calendar: CalendarTodayOutlinedIcon,
13
+ Check: CheckIcon,
14
+ Clock: AccessTimeIcon,
15
+ Heart: FavoriteIcon,
16
+ };
17
+
18
+ const Template = (args) => {
19
+ return (
20
+ <div style={{ maxWidth: 500, margin: '2rem auto' }}>
21
+ <BmCustomCardTitle {...args} />
22
+ </div>
23
+ );
24
+ };
25
+
26
+ export const Default = Template.bind({});
27
+ Default.args = {
28
+ icon: CalendarTodayOutlinedIcon,
29
+ themeColor: '#33B1BA',
30
+ title: 'Book Your Medical Appointment',
31
+ description:
32
+ 'Schedule a 30-minute consultation with our healthcare specialists',
33
+ variant: 'booking',
34
+ withStripe: true,
35
+ };
36
+
37
+ Default.argTypes = {
38
+ icon: {
39
+ control: {
40
+ type: 'select',
41
+ labels: Object.keys(iconOptions),
42
+ },
43
+ options: Object.keys(iconOptions),
44
+ mapping: iconOptions,
45
+ },
46
+ themeColor: {
47
+ control: 'color',
48
+ },
49
+ title: {
50
+ control: 'text',
51
+ },
52
+ description: {
53
+ control: 'text',
54
+ },
55
+ variant: {
56
+ control: {
57
+ type: 'radio',
58
+ },
59
+ options: ['booking', 'confirmation'],
60
+ },
61
+ withStripe: {
62
+ control: {
63
+ type: 'boolean',
64
+ },
65
+ },
66
+ };
67
+
68
+ export default {
69
+ title: 'Components/BmCustomCardTitle',
70
+ component: BmCustomCardTitle,
71
+ argTypes: Default.argTypes,
72
+ };
73
+
74
+ export const Example = () => {
75
+ <BmCustomCardTitle
76
+ icon={CalendarTodayOutlinedIcon}
77
+ themeColor="#33B1BA"
78
+ title="Book Your Medical Appointment"
79
+ description="Schedule a 30-minute consultation with our healthcare specialists"
80
+ variant="booking"
81
+ withStripe
82
+ />;
83
+ };
@@ -53,8 +53,8 @@ const IconBox = styled.div`
53
53
  color: ${({ iconColor }) => iconColor || '#00000'};
54
54
 
55
55
  @media (min-width: 45.7143rem) {
56
- height: 1.5rem;
57
- width: 1.5rem;
56
+ height: 1.4rem;
57
+ width: 1.4rem;
58
58
  }
59
59
  }
60
60
  `;
@@ -81,6 +81,7 @@ import BmLabelWithIcon from './LabelWithIcon/LabelWithIcon';
81
81
  import { BmCardv2 } from './Card_v2/Card';
82
82
  import BmInfoPanel from './InfoPanel/InfoPanel';
83
83
  import BmSelector from './BmSelector/BmSelector';
84
+ import BmCustomCardTitle from './BmCustomCardTitle/CustomCardTitle';
84
85
 
85
86
  export {
86
87
  BmAccordion,
@@ -159,4 +160,5 @@ export {
159
160
  BmInfoPanel,
160
161
  BmProgressIndicator,
161
162
  BmSelector,
163
+ BmCustomCardTitle,
162
164
  };