@licklist/design 0.78.12 → 0.78.15

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.
@@ -62,7 +62,7 @@ pipelines:
62
62
  name: Publish to NPM
63
63
  script:
64
64
  - printf "//`node -p \"require('url').parse(process.env.NPM_REGISTRY_URL || 'https://registry.npmjs.org').host\"`/:_authToken=${NPM_TOKEN}\nregistry=${NPM_REGISTRY_URL:-https://registry.npmjs.org}\n" >> ~/.npmrc
65
- - pipe: atlassian/npm-publish:0.2.0
65
+ - pipe: atlassian/npm-publish:1.1.1
66
66
  variables:
67
67
  NPM_TOKEN: $NPM_TOKEN
68
68
 
@@ -0,0 +1,10 @@
1
+ type CustomDatePickerProps = {
2
+ name: string;
3
+ error?: string;
4
+ label?: string;
5
+ showAge?: boolean;
6
+ required?: boolean;
7
+ };
8
+ export declare function CustomDatePicker({ name, error, showAge, required }: CustomDatePickerProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
10
+ //# sourceMappingURL=CustomDatePicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CustomDatePicker.d.ts","sourceRoot":"","sources":["../../src/CustomDatePicker/CustomDatePicker.tsx"],"names":[],"mappings":"AAMA,KAAK,qBAAqB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,KAAK,EACL,OAAc,EACd,QAAe,EAChB,EAAE,qBAAqB,2CA8OvB"}
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ interface RadioButtonProps {
3
+ name: string;
4
+ value: string;
5
+ checked: boolean;
6
+ onChange: (value: string) => void;
7
+ label?: string;
8
+ }
9
+ declare const RadioButton: React.FC<RadioButtonProps>;
10
+ export default RadioButton;
11
+ //# sourceMappingURL=RadioButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioButton.d.ts","sourceRoot":"","sources":["../../src/customRadioButton/RadioButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,UAAU,gBAAgB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,QAAA,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuE3C,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -0,0 +1,93 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import 'react';
3
+
4
+ var RadioButton = function(param) {
5
+ var name = param.name, value = param.value, checked = param.checked, onChange = param.onChange, label = param.label;
6
+ // Generate a stable id so label could be connected if needed
7
+ var id = "".concat(name, "-").concat(value);
8
+ return /*#__PURE__*/ jsxs("div", {
9
+ className: "tw-flex tw-items-center tw-space-x-3",
10
+ style: {
11
+ display: 'flex',
12
+ alignItems: 'center',
13
+ gap: 12
14
+ },
15
+ children: [
16
+ /*#__PURE__*/ jsxs("div", {
17
+ className: "tw-relative tw-cursor-pointer",
18
+ style: {
19
+ position: 'relative',
20
+ cursor: 'pointer'
21
+ },
22
+ onClick: function() {
23
+ return onChange(value);
24
+ },
25
+ children: [
26
+ /*#__PURE__*/ jsx("input", {
27
+ id: id,
28
+ type: "radio",
29
+ name: name,
30
+ value: value,
31
+ checked: checked,
32
+ onChange: function() {
33
+ return onChange(value);
34
+ },
35
+ className: "tw-sr-only",
36
+ style: {
37
+ position: 'absolute',
38
+ opacity: 0,
39
+ pointerEvents: 'none',
40
+ width: 0,
41
+ height: 0
42
+ }
43
+ }),
44
+ /*#__PURE__*/ jsx("div", {
45
+ className: "tw-w-[47px] tw-h-[47px] tw-border-[3px] tw-border-black tw-rounded-full tw-bg-white tw-flex tw-items-center tw-justify-center tw-transition-all tw-duration-200 hover:tw-shadow-sm",
46
+ style: {
47
+ width: 52,
48
+ height: 52,
49
+ borderWidth: 3,
50
+ borderStyle: 'solid',
51
+ borderColor: '#000',
52
+ borderRadius: 9999,
53
+ background: '#fff',
54
+ display: 'flex',
55
+ alignItems: 'center',
56
+ justifyContent: 'center',
57
+ transition: 'all 200ms'
58
+ },
59
+ children: checked && /*#__PURE__*/ jsx("div", {
60
+ className: "tw-w-[30px] tw-h-[30px] tw-bg-slate-900 tw-rounded-full",
61
+ style: {
62
+ width: 30,
63
+ height: 30,
64
+ background: '#0f172a',
65
+ borderRadius: 9999
66
+ }
67
+ })
68
+ })
69
+ ]
70
+ }),
71
+ label && /*#__PURE__*/ jsx("label", {
72
+ htmlFor: id,
73
+ className: "tw-cursor-pointer tw-text-gray-700 tw-select-none tw-flex tw-items-center tw-leading-none",
74
+ style: {
75
+ cursor: 'pointer',
76
+ color: '#374151',
77
+ userSelect: 'none',
78
+ display: 'inline-flex',
79
+ alignItems: 'center',
80
+ lineHeight: 1,
81
+ position: 'relative',
82
+ top: 5
83
+ },
84
+ onClick: function() {
85
+ return onChange(value);
86
+ },
87
+ children: label
88
+ })
89
+ ]
90
+ });
91
+ };
92
+
93
+ export { RadioButton as default };
package/dist/index.d.ts CHANGED
@@ -43,4 +43,5 @@ export * from './availability-indicator';
43
43
  export * from './number-of-people-input';
44
44
  export * from './fullscreen-loader';
45
45
  export * from './pages';
46
+ export { default as RadioButton } from './customRadioButton/RadioButton';
46
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,2BAA2B,CAAA;AACzC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,wBAAwB,CAAA;AACtC,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA;AACnC,cAAc,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAA;AACtB,cAAc,2BAA2B,CAAA;AACzC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,SAAS,CAAA;AACvB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,UAAU,CAAA;AACxB,cAAc,QAAQ,CAAA;AACtB,cAAc,UAAU,CAAA;AACxB,cAAc,eAAe,CAAA;AAC7B,cAAc,YAAY,CAAA;AAC1B,cAAc,oBAAoB,CAAA;AAClC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,SAAS,CAAA;AACvB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,WAAW,CAAA;AACzB,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,UAAU,CAAA;AACxB,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,UAAU,CAAA;AACxB,cAAc,kBAAkB,CAAA;AAChC,cAAc,aAAa,CAAA;AAC3B,cAAc,oBAAoB,CAAA;AAClC,cAAc,QAAQ,CAAA;AACtB,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,wBAAwB,CAAA;AACtC,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA;AAChC,cAAc,oBAAoB,CAAA;AAClC,cAAc,YAAY,CAAA;AAC1B,cAAc,0BAA0B,CAAA;AACxC,cAAc,0BAA0B,CAAA;AACxC,cAAc,qBAAqB,CAAA;AACnC,cAAc,SAAS,CAAA;AACvB,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,iCAAiC,CAAA"}
package/dist/index.js CHANGED
@@ -205,6 +205,7 @@ export { useFullscreenLoader } from './fullscreen-loader/useFullscreenLoader.js'
205
205
  export { FullscreenLoaderContext } from './fullscreen-loader/context.js';
206
206
  export { PrivacyComponent } from './pages/PrivacyComponent.js';
207
207
  export { TermsComponent } from './pages/TermsComponent.js';
208
+ export { default as RadioButton } from './customRadioButton/RadioButton.js';
208
209
  export { default as CountrySelect } from './static/CountrySelect.js';
209
210
  export { default as FormCard } from './static/FormCard.js';
210
211
  export { default as Image } from './static/Image.js';
@@ -1 +1 @@
1
- {"version":3,"file":"Profile.d.ts","sourceRoot":"","sources":["../../../../src/sales/guest-profile/profile/Profile.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sDAAsD,CAAA;AAO5E,KAAK,YAAY,GAAG;IAClB,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAGrB,CAAA;AAED,eAAO,MAAM,OAAO,aAAc,YAAY,4CAgD7C,CAAA"}
1
+ {"version":3,"file":"Profile.d.ts","sourceRoot":"","sources":["../../../../src/sales/guest-profile/profile/Profile.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sDAAsD,CAAA;AAO5E,KAAK,YAAY,GAAG;IAClB,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;CAGrB,CAAA;AAED,eAAO,MAAM,OAAO,aAAc,YAAY,4CA6C7C,CAAA"}
@@ -10,7 +10,8 @@ var Profile = function(param) {
10
10
  if (!user) {
11
11
  return null;
12
12
  }
13
- var firstName = user.firstName, lastName = user.lastName, gender = user.userDetail.gender;
13
+ var firstName = user.firstName, lastName = user.lastName, userDetail = user.userDetail;
14
+ var gender = userDetail === null || userDetail === void 0 ? void 0 : userDetail.gender;
14
15
  return /*#__PURE__*/ jsx("div", {
15
16
  className: "profile",
16
17
  children: /*#__PURE__*/ jsxs("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@licklist/design",
3
- "version": "0.78.12",
3
+ "version": "0.78.15",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@bitbucket.org/artelogicsoft/licklist_design.git"
@@ -0,0 +1,258 @@
1
+ import { TextInput } from '@mantine/core'
2
+ import { useEffect, useState } from 'react'
3
+ import { Controller, useFormContext } from 'react-hook-form'
4
+ import { DateTime } from 'luxon'
5
+ import { useTranslation } from 'react-i18next'
6
+
7
+ type CustomDatePickerProps = {
8
+ name: string
9
+ error?: string
10
+ label?: string
11
+ showAge?: boolean
12
+ required?: boolean
13
+ }
14
+
15
+ export function CustomDatePicker({
16
+ name,
17
+ error,
18
+ showAge = true,
19
+ required = true
20
+ }: CustomDatePickerProps) {
21
+ const { t } = useTranslation()
22
+ const { control, setValue, watch, getValues, trigger, formState } = useFormContext()
23
+ const [age, setAge] = useState<number | null>(null)
24
+ const [localError, setLocalError] = useState<string | null>(null)
25
+
26
+ // Get current field values
27
+ const day = watch(`${name}_day`) || ''
28
+ const month = watch(`${name}_month`) || ''
29
+ const year = watch(`${name}_year`) || ''
30
+
31
+ // Initialize values from existing date
32
+ useEffect(() => {
33
+ const existingDate = getValues(name)
34
+
35
+ if (existingDate instanceof Date && !day && !month && !year) {
36
+ const dateTime = DateTime.fromJSDate(existingDate)
37
+ if (dateTime.isValid) {
38
+ setValue(`${name}_day`, dateTime.day.toString().padStart(2, '0'))
39
+ setValue(`${name}_month`, dateTime.month.toString().padStart(2, '0'))
40
+ setValue(`${name}_year`, dateTime.year.toString())
41
+ }
42
+ }
43
+ }, [name, setValue, getValues, day, month, year])
44
+
45
+ // Check for empty fields after submit attempt
46
+ useEffect(() => {
47
+ if (formState.isSubmitted && required) {
48
+ const hasEmptyFields = !day || !month || !year
49
+
50
+ if (hasEmptyFields) {
51
+ setLocalError(t('Validation:fieldRequired', { attribute: t('App:dateOfBirth') }))
52
+ // Set the main field to null to trigger form validation
53
+ setValue(name, null, { shouldValidate: true })
54
+ } else {
55
+ setLocalError(null)
56
+ }
57
+ }
58
+ }, [formState.isSubmitted, day, month, year, required, name, setValue, t])
59
+
60
+ // Calculate age and validate date when all fields are filled
61
+ useEffect(() => {
62
+ if (day && month && year) {
63
+ try {
64
+ // Create a date object
65
+ const dateObj = DateTime.fromObject({
66
+ day: parseInt(day, 10),
67
+ month: parseInt(month, 10),
68
+ year: parseInt(year, 10)
69
+ })
70
+
71
+ // Only proceed if date is valid
72
+ if (dateObj.isValid) {
73
+ // Set the main field value
74
+ setValue(name, dateObj.toJSDate(), { shouldValidate: true })
75
+ setLocalError(null)
76
+
77
+ // Calculate age
78
+ if (showAge) {
79
+ const now = DateTime.now()
80
+ const diff = now.diff(dateObj, 'years')
81
+ setAge(Math.floor(diff.years))
82
+ }
83
+ } else {
84
+ setLocalError(t('Validation:fieldInvalid', { attribute: t('App:dateOfBirth') }))
85
+ setValue(name, null, { shouldValidate: true })
86
+ setAge(null)
87
+ }
88
+ } catch (err) {
89
+ // If any parsing fails, just reset the age display
90
+ setLocalError(t('Validation:fieldInvalid', { attribute: t('App:dateOfBirth') }))
91
+ setValue(name, null, { shouldValidate: true })
92
+ setAge(null)
93
+ }
94
+ } else if (formState.isSubmitted && required) {
95
+ // If form was submitted and fields are required but not all filled
96
+ setLocalError(t('Validation:fieldRequired', { attribute: t('App:dateOfBirth') }))
97
+ setValue(name, null, { shouldValidate: true })
98
+ setAge(null)
99
+ } else {
100
+ // Reset if not all fields are filled but not submitted yet
101
+ setValue(name, null, { shouldValidate: false })
102
+ setAge(null)
103
+ }
104
+ }, [day, month, year, name, setValue, showAge, formState.isSubmitted, required, t])
105
+
106
+ // After user completes all fields, validate the form
107
+ useEffect(() => {
108
+ if (day && month && year) {
109
+ trigger(name)
110
+ }
111
+ }, [day, month, year, name, trigger])
112
+
113
+ // Display either the form error or our local error
114
+ const displayError = error || localError
115
+
116
+ return (
117
+ <div className="tw-w-full">
118
+ <div className="tw-flex tw-flex-col">
119
+ <div className="tw-mb-2 tw-flex tw-items-center tw-justify-between">
120
+ <label className="tw-font-semibold">
121
+ {t('App:dateOfBirth')}
122
+ {required && <span className="tw-ml-1 tw-text-red-500"></span>}
123
+ </label>
124
+ {age !== null && (
125
+ <span className="tw-text-sm tw-text-gray-600">
126
+ {t('App:Age')}: {age}
127
+ </span>
128
+ )}
129
+ </div>
130
+
131
+ <div className="tw-flex tw-flex-row tw-gap-4">
132
+ <div className="tw-w-1/3">
133
+ <label className="tw-mb-1 tw-block tw-text-sm">{t('App:Day')}</label>
134
+ <Controller
135
+ control={control}
136
+ name={`${name}_day`}
137
+ defaultValue=""
138
+ render={({ field }) => (
139
+ <TextInput
140
+ {...field}
141
+ value={field.value || ''}
142
+ placeholder="DD"
143
+ maxLength={2}
144
+ error={!!displayError}
145
+ classNames={{ input: 'tw-placeholder-[#626A90]' }}
146
+ styles={{ input: { '&::placeholder': { color: '#626A90' } } }}
147
+ onChange={(e) => {
148
+ const value = e.target.value.replace(/[^0-9]/g, '')
149
+ field.onChange(value)
150
+ }}
151
+ onBlur={(e) => {
152
+ // Validate and format on blur
153
+ let value = e.target.value.replace(/[^0-9]/g, '')
154
+ if (value) {
155
+ const num = parseInt(value, 10)
156
+ if (num < 1) value = '01'
157
+ else if (num > 31) value = '31'
158
+ else value = num.toString().padStart(2, '0')
159
+ }
160
+ field.onChange(value)
161
+ }}
162
+ />
163
+ )}
164
+ />
165
+ </div>
166
+
167
+ <div className="tw-w-1/3">
168
+ <label className="tw-mb-1 tw-block tw-text-sm">{t('App:Month')}</label>
169
+ <Controller
170
+ control={control}
171
+ name={`${name}_month`}
172
+ defaultValue=""
173
+ render={({ field }) => (
174
+ <TextInput
175
+ {...field}
176
+ value={field.value || ''}
177
+ placeholder="MM"
178
+ maxLength={2}
179
+ error={!!displayError}
180
+ classNames={{ input: 'tw-placeholder-[#626A90]' }}
181
+ styles={{ input: { '&::placeholder': { color: '#626A90' } } }}
182
+ onChange={(e) => {
183
+ const value = e.target.value.replace(/[^0-9]/g, '')
184
+ field.onChange(value)
185
+ }}
186
+ onBlur={(e) => {
187
+ // Validate and format on blur
188
+ let value = e.target.value.replace(/[^0-9]/g, '')
189
+ if (value) {
190
+ const num = parseInt(value, 10)
191
+ if (num < 1) value = '01'
192
+ else if (num > 12) value = '12'
193
+ else value = num.toString().padStart(2, '0')
194
+ }
195
+ field.onChange(value)
196
+ }}
197
+ />
198
+ )}
199
+ />
200
+ </div>
201
+
202
+ <div className="tw-w-1/3">
203
+ <label className="tw-mb-1 tw-block tw-text-sm">{t('App:Year')}</label>
204
+ <Controller
205
+ control={control}
206
+ name={`${name}_year`}
207
+ defaultValue=""
208
+ render={({ field }) => (
209
+ <TextInput
210
+ {...field}
211
+ value={field.value || ''}
212
+ placeholder="YYYY"
213
+ maxLength={4}
214
+ error={!!displayError}
215
+ classNames={{ input: 'tw-placeholder-[#626A90]' }}
216
+ styles={{ input: { '&::placeholder': { color: '#626A90' } } }}
217
+ onChange={(e) => {
218
+ const value = e.target.value.replace(/[^0-9]/g, '')
219
+ field.onChange(value)
220
+ }}
221
+ onBlur={(e) => {
222
+ // Validate on blur
223
+ const value = e.target.value.replace(/[^0-9]/g, '')
224
+ if (value) {
225
+ const num = parseInt(value, 10)
226
+ const currentYear = new Date().getFullYear()
227
+ if (num > currentYear) {
228
+ field.onChange(currentYear.toString())
229
+ } else if (num < 1900) {
230
+ field.onChange('1900')
231
+ }
232
+ }
233
+ }}
234
+ />
235
+ )}
236
+ />
237
+ </div>
238
+ </div>
239
+ </div>
240
+
241
+ {/* Hidden field to store the actual date value */}
242
+ <Controller
243
+ control={control}
244
+ name={name}
245
+ defaultValue={null}
246
+ rules={{
247
+ validate: value => {
248
+ if (required && !value) {
249
+ return t('Validation:fieldRequired', { attribute: t('App:dateOfBirth') })
250
+ }
251
+ return true
252
+ }
253
+ }}
254
+ render={() => <input type="hidden" />}
255
+ />
256
+ </div>
257
+ )
258
+ }
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+
3
+ interface RadioButtonProps {
4
+ name: string;
5
+ value: string;
6
+ checked: boolean;
7
+ onChange: (value: string) => void;
8
+ label?: string;
9
+ }
10
+
11
+ const RadioButton: React.FC<RadioButtonProps> = ({
12
+ name,
13
+ value,
14
+ checked,
15
+ onChange,
16
+ label
17
+ }) => {
18
+ // Generate a stable id so label could be connected if needed
19
+ const id = `${name}-${value}`;
20
+
21
+ return (
22
+ <div
23
+ className="tw-flex tw-items-center tw-space-x-3"
24
+ style={{ display: 'flex', alignItems: 'center', gap: 12 }}
25
+ >
26
+ <div
27
+ className="tw-relative tw-cursor-pointer"
28
+ style={{ position: 'relative', cursor: 'pointer' }}
29
+ onClick={() => onChange(value)}
30
+ >
31
+ {/* Hidden native radio input for accessibility */}
32
+ <input
33
+ id={id}
34
+ type="radio"
35
+ name={name}
36
+ value={value}
37
+ checked={checked}
38
+ onChange={() => onChange(value)}
39
+ className="tw-sr-only"
40
+ style={{ position: 'absolute', opacity: 0, pointerEvents: 'none', width: 0, height: 0 }}
41
+ />
42
+
43
+ {/* Custom radio button circle */}
44
+ <div
45
+ className="tw-w-[47px] tw-h-[47px] tw-border-[3px] tw-border-black tw-rounded-full tw-bg-white tw-flex tw-items-center tw-justify-center tw-transition-all tw-duration-200 hover:tw-shadow-sm"
46
+ style={{
47
+ width: 52,
48
+ height: 52,
49
+ borderWidth: 3,
50
+ borderStyle: 'solid',
51
+ borderColor: '#000',
52
+ borderRadius: 9999,
53
+ background: '#fff',
54
+ display: 'flex',
55
+ alignItems: 'center',
56
+ justifyContent: 'center',
57
+ transition: 'all 200ms',
58
+ }}
59
+ >
60
+ {/* Inner filled circle when selected */}
61
+ {checked && (
62
+ <div
63
+ className="tw-w-[30px] tw-h-[30px] tw-bg-slate-900 tw-rounded-full"
64
+ style={{ width: 30, height: 30, background: '#0f172a', borderRadius: 9999 }}
65
+ />
66
+ )}
67
+ </div>
68
+ </div>
69
+
70
+ {label && (
71
+ <label
72
+ htmlFor={id}
73
+ className="tw-cursor-pointer tw-text-gray-700 tw-select-none tw-flex tw-items-center tw-leading-none"
74
+ style={{ cursor: 'pointer', color: '#374151', userSelect: 'none', display: 'inline-flex', alignItems: 'center', lineHeight: 1, position: 'relative', top: 5 }}
75
+ onClick={() => onChange(value)}
76
+ >
77
+ {label}
78
+ </label>
79
+ )}
80
+ </div>
81
+ );
82
+ };
83
+
84
+ export default RadioButton;
package/src/index.ts CHANGED
@@ -43,3 +43,4 @@ export * from './availability-indicator'
43
43
  export * from './number-of-people-input'
44
44
  export * from './fullscreen-loader'
45
45
  export * from './pages'
46
+ export { default as RadioButton } from './customRadioButton/RadioButton'
@@ -16,11 +16,8 @@ export const Profile = ({ user }: ProfileProps) => {
16
16
  return null
17
17
  }
18
18
 
19
- const {
20
- firstName,
21
- lastName,
22
- userDetail: { gender },
23
- } = user
19
+ const { firstName, lastName, userDetail } = user
20
+ const gender = userDetail?.gender
24
21
 
25
22
  return (
26
23
  <div className='profile'>
@@ -1,22 +0,0 @@
1
- import { alertThemes } from "./alertThemes";
2
- export interface AlertConfig {
3
- type: keyof typeof alertThemes;
4
- title?: string;
5
- subTitle?: string;
6
- message?: string | string[];
7
- description?: string;
8
- actionText?: string;
9
- secondaryActionText?: string;
10
- onAction?: (() => void) | null;
11
- onSecondaryAction?: (() => void) | null;
12
- timeout?: number;
13
- closable?: boolean;
14
- titleColor?: string;
15
- subTitleColor?: string;
16
- showArrow?: boolean;
17
- showSecondaryArrow?: boolean;
18
- alignActionsRight?: boolean;
19
- mount?: "container" | "global";
20
- }
21
- export declare function showAlert(config: AlertConfig): void;
22
- //# sourceMappingURL=AlertBox.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AlertBox.d.ts","sourceRoot":"","sources":["../../src/CustomAlertTypes/AlertBox.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,OAAO,WAAW,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,KAAK,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;CAChC;AAqDD,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,QAW5C"}
@@ -1,21 +0,0 @@
1
- import React from "react";
2
- import { AlertConfig } from './AlertBox';
3
- export declare class AlertRenderer {
4
- static createAlert(config: AlertConfig, onClose: () => void): React.DetailedReactHTMLElement<{
5
- style: {
6
- backgroundColor: string;
7
- border: string;
8
- borderRadius: string;
9
- padding: string;
10
- width: string;
11
- maxWidth: string;
12
- margin: string;
13
- pointerEvents: "auto";
14
- fontFamily: string;
15
- position: "relative";
16
- overflow: "hidden";
17
- boxSizing: "border-box";
18
- };
19
- }, HTMLElement>;
20
- }
21
- //# sourceMappingURL=AlertRender.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"AlertRender.d.ts","sourceRoot":"","sources":["../../src/CustomAlertTypes/AlertRender.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,qBAAa,aAAa;IACxB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,IAAI;;;;;;;;;;;;;;;;CAoR5D"}
@@ -1,41 +0,0 @@
1
- import React from "react";
2
- export declare const ErrorIcon: () => React.ReactSVGElement;
3
- export declare const SuccessIcon: () => React.ReactSVGElement;
4
- export declare const InfoIcon: () => React.ReactSVGElement;
5
- export declare const WarningIcon: () => React.ReactSVGElement;
6
- export declare const commonStyle: {
7
- fontFamily: string;
8
- color: string;
9
- borderRad: string;
10
- };
11
- export declare const alertThemes: {
12
- error: {
13
- bg: string;
14
- border: string;
15
- icon: string;
16
- IconComponent: () => React.ReactSVGElement;
17
- defaultTitle: string;
18
- };
19
- success: {
20
- bg: string;
21
- border: string;
22
- icon: string;
23
- IconComponent: () => React.ReactSVGElement;
24
- defaultTitle: string;
25
- };
26
- warning: {
27
- bg: string;
28
- border: string;
29
- icon: string;
30
- IconComponent: () => React.ReactSVGElement;
31
- defaultTitle: string;
32
- };
33
- info: {
34
- bg: string;
35
- border: string;
36
- icon: string;
37
- IconComponent: () => React.ReactSVGElement;
38
- defaultTitle: string;
39
- };
40
- };
41
- //# sourceMappingURL=alertThemes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"alertThemes.d.ts","sourceRoot":"","sources":["../../src/CustomAlertTypes/alertThemes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AA8B1B,eAAO,MAAM,SAAS,6BAA0C,CAAC;AACjE,eAAO,MAAM,WAAW,6BAA4C,CAAC;AACrE,eAAO,MAAM,QAAQ,6BAAyC,CAAC;AAC/D,eAAO,MAAM,WAAW,6BAA4C,CAAC;AAErE,eAAO,MAAM,WAAW;;;;CAIvB,CAAA;AAGD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BvB,CAAC"}
@@ -1,8 +0,0 @@
1
- /**
2
- * Wraps text into multiple lines by word count limit.
3
- * @param text - The input string
4
- * @param limit - Max characters per line
5
- * @returns Wrapped text as a single string with newlines
6
- */
7
- export declare function wrapText(text: string, limit: number): string;
8
- //# sourceMappingURL=textWrapperUtils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"textWrapperUtils.d.ts","sourceRoot":"","sources":["../../../src/CustomAlertTypes/utils/textWrapperUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAmB5D"}