kahuna-base-react-components 1.1.2 → 1.1.4

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 (37) hide show
  1. package/dist/components/KDropdown/KDropdown.d.ts +3 -0
  2. package/dist/components/KSelectDate/KSelectDate.d.ts +3 -0
  3. package/dist/components/KSelectRange/KSelectRange.d.ts +10 -0
  4. package/dist/components/KSelectRange/index.d.ts +1 -0
  5. package/dist/index.d.ts +2 -1
  6. package/dist/index.esm.js +2 -2
  7. package/dist/index.esm.js.map +1 -1
  8. package/dist/index.js +2 -2
  9. package/dist/index.js.map +1 -1
  10. package/dist/types.d.ts +14 -1
  11. package/package.json +1 -1
  12. package/src/assets/calendar-new.svg +3 -0
  13. package/src/assets/platforms/Meta.svg +19 -0
  14. package/src/assets/platforms/Spotify.svg +6 -0
  15. package/src/assets/platforms/all_platforms.svg +6 -0
  16. package/src/assets/platforms/apple-music.svg +27 -0
  17. package/src/assets/platforms/boom-play.svg +5 -0
  18. package/src/assets/platforms/caret-down.svg +3 -0
  19. package/src/assets/platforms/deezer.svg +23 -0
  20. package/src/assets/platforms/fizy.svg +14 -0
  21. package/src/assets/platforms/muud.svg +38 -0
  22. package/src/assets/platforms/ncm.svg +8 -0
  23. package/src/assets/platforms/pandora.svg +1 -0
  24. package/src/assets/platforms/resso.svg +10 -0
  25. package/src/assets/platforms/snap.svg +1 -0
  26. package/src/assets/platforms/soundcloud.svg +13 -0
  27. package/src/assets/platforms/tiktok.svg +9 -0
  28. package/src/assets/platforms/youtube.svg +5 -0
  29. package/src/components/KDropdown/KDropdown.stories.tsx +32 -8
  30. package/src/components/KDropdown/KDropdown.tsx +41 -8
  31. package/src/components/KSelectDate/KSelectDate.stories.tsx +8 -5
  32. package/src/components/KSelectDate/KSelectDate.tsx +105 -53
  33. package/src/components/KSelectRange/KSelectRange.stories.tsx +55 -0
  34. package/src/components/KSelectRange/KSelectRange.tsx +242 -0
  35. package/src/components/KSelectRange/KSelectRangeCustom.css +243 -0
  36. package/src/components/KSelectRange/index.ts +1 -0
  37. package/src/index.ts +2 -1
@@ -8,6 +8,8 @@ import SeparatorIcon from "../../assets/separator.svg"
8
8
  //@ts-ignore
9
9
  import CalendarIcon from "../../assets/calendar.svg"
10
10
  //@ts-ignore
11
+ import CalendarNewIcon from "../../assets/calendar-new.svg"
12
+ //@ts-ignore
11
13
  import RightIcon from "../../assets/chevron-right.svg"
12
14
  import "../../main.css"
13
15
  import KButton from "../KButton"
@@ -16,6 +18,9 @@ import KSpan from "../KSpan"
16
18
  export interface KSelectDateProps {
17
19
  value: Date | undefined
18
20
  onChange: (date: Date | undefined) => void
21
+ minimumDate?: Date
22
+ onlyMonthSelection?: boolean
23
+ hideBody?: boolean
19
24
  }
20
25
  interface MonthSelectorType {
21
26
  monthName: string
@@ -39,6 +44,9 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
39
44
  const [weekDays, setWeekDays] = useState<DaySelectorType[]>([])
40
45
  const [openCalendar, setOpenCalendar] = useState<boolean>(false)
41
46
 
47
+ const onlyMonthSelection = props.onlyMonthSelection || false
48
+ const hideBody = props.hideBody || false
49
+
42
50
  const formatShortWeekday = (locale: string | undefined, date: Date): string => {
43
51
  return date.toLocaleDateString(locale, { weekday: "short" }).charAt(0) // Return only the first letter of the weekday
44
52
  }
@@ -57,6 +65,13 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
57
65
  setCalendarDate(date)
58
66
  }
59
67
  }
68
+ const onClickMonth = (date: Date) => {
69
+ if (date.getTime() === calendarDate?.getTime()) {
70
+ setCalendarDate(undefined)
71
+ } else {
72
+ setCalendarDate(date)
73
+ }
74
+ }
60
75
 
61
76
  const getNextMonths = (date: Date | undefined) => {
62
77
  if (date) {
@@ -98,6 +113,8 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
98
113
  <div className="flex flex-col gap-0">
99
114
  <Calendar
100
115
  onClickDay={onClickDay}
116
+ {...(onlyMonthSelection && { onClickMonth: onClickMonth })}
117
+ {...(onlyMonthSelection && { maxDetail: "year" })}
101
118
  locale="en-US"
102
119
  value={calendarDate || null}
103
120
  defaultValue={null}
@@ -107,6 +124,7 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
107
124
  nextLabel={<img src={RightIcon} />}
108
125
  formatShortWeekday={formatShortWeekday}
109
126
  formatMonthYear={formatMonthYear}
127
+ minDate={props.minimumDate || undefined}
110
128
  />
111
129
  <div className="h-19 w-[350px] bg-[#FFF] flex flex-row gap-4 py-4 justify-center border-[1px] border-[#E7E7E7] border-t-0 rounded-b-[10px]">
112
130
  <KButton
@@ -173,7 +191,7 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
173
191
  }
174
192
  }}
175
193
  background={inMonth ? "#111" : "#FFF"}
176
- textColor={inMonth? "#FFF" : "#111"}
194
+ textColor={inMonth ? "#FFF" : "#111"}
177
195
  borderRadius={999}
178
196
  padding="8px 16px"
179
197
  height="34px"
@@ -183,13 +201,23 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
183
201
  }
184
202
 
185
203
  const daySelector = (text: string, date: Date) => {
204
+ const dateNotAllowed = props.minimumDate && date < props.minimumDate
186
205
  return (
187
206
  <div
188
207
  key={`${text}-${date}`}
189
- className={`w-[85px] h-[104px] flex flex-col justify-between py-3 px-2.5 rounded-[10px] ${
190
- date.getTime() === value?.getTime() ? "bg-[#F8FEA3]" : "bg-[#F5F5F5]"
191
- } cursor-pointer`}
208
+ className={`w-[85px] h-[104px] flex flex-col justify-between py-3 px-2.5 rounded-[10px] cursor-pointer`}
209
+ style={{
210
+ background: dateNotAllowed
211
+ ? "rgb(170, 170, 170, 0.7)"
212
+ : date.getTime() === value?.getTime()
213
+ ? "#F8FEA3"
214
+ : "#F5F5F5"
215
+ }}
192
216
  onClick={() => {
217
+ if (dateNotAllowed) {
218
+ return
219
+ }
220
+
193
221
  if (date.getTime() === value?.getTime()) {
194
222
  setValue(undefined)
195
223
  } else {
@@ -228,6 +256,8 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
228
256
  useEffect(() => {
229
257
  if (value) {
230
258
  setDummyDate(value)
259
+ } else if (props.minimumDate) {
260
+ setDummyDate(props.minimumDate)
231
261
  }
232
262
  props.onChange(value)
233
263
  }, [value])
@@ -235,14 +265,19 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
235
265
  useEffect(() => {
236
266
  const today = new Date()
237
267
  if (!props.value) {
238
- getNextMonths(today)
239
- getWeekDays(today)
268
+ getNextMonths(props.minimumDate || today)
269
+ getWeekDays(props.minimumDate || today)
240
270
  }
241
271
  }, [])
242
-
272
+
243
273
  useEffect(() => {
244
- getNextMonths(dummyDate)
245
- getWeekDays(dummyDate)
274
+ if (dummyDate && props.minimumDate && dummyDate < props.minimumDate) {
275
+ getNextMonths(props.minimumDate)
276
+ getWeekDays(props.minimumDate)
277
+ } else {
278
+ getNextMonths(dummyDate)
279
+ getWeekDays(dummyDate)
280
+ }
246
281
  }, [dummyDate])
247
282
 
248
283
  return (
@@ -252,61 +287,78 @@ const KSelectDate: React.FC<KSelectDateProps> = (props) => {
252
287
  <div>{renderPopUpCalendar()}</div>
253
288
  </div>
254
289
  )}
255
- <div>
256
- <div className={`flex flex-col gap-4 ${openCalendar && "blur-2xl"}`}>
257
- <div className="flex flex-row justify-between gap-2 items-center">
258
- <div className="flex flex-row gap-2">
259
- {nextMonths.map((month, i) => {
260
- return monthSelector(month.monthName, month.year, month.date)
261
- })}
290
+ {!hideBody ? (
291
+ <div>
292
+ <div className={`flex flex-col gap-4 ${openCalendar && "blur-2xl"}`}>
293
+ <div className="flex flex-row justify-between gap-2 items-center">
294
+ <div className="flex flex-row gap-2">
295
+ {nextMonths.map((month, i) => {
296
+ return monthSelector(month.monthName, month.year, month.date)
297
+ })}
298
+ </div>
299
+ <div>
300
+ <img src={SeparatorIcon} />
301
+ </div>
302
+ <div>
303
+ <KButton
304
+ icon={CalendarIcon}
305
+ onClick={() => {
306
+ setOpenCalendar(true)
307
+ setCalendarDate(value)
308
+ }}
309
+ padding="8px"
310
+ height="36px"
311
+ background="#FFF"
312
+ />
313
+ </div>
262
314
  </div>
263
- <div>
264
- <img src={SeparatorIcon} />
315
+ <div className="flex flex-row justify-between gap-1 items-center">
316
+ {weekDays.map((day, i) => {
317
+ return daySelector(`${day.dayOrderInMonth}, ${day.dayName}`, day.date)
318
+ })}
265
319
  </div>
266
- <div>
320
+ <div className="flex flex-row justify-between items-center">
321
+ <KButton
322
+ text="Previous Week"
323
+ padding="6px"
324
+ leftIcon={LeftIcon}
325
+ onClick={() => {
326
+ changeWeeks(dummyDate, false)
327
+ }}
328
+ width="130px"
329
+ height="32px"
330
+ background="#FFF"
331
+ />
267
332
  <KButton
268
- icon={CalendarIcon}
333
+ text="Next Week"
334
+ padding="6px"
335
+ rightIcon={RightIcon}
269
336
  onClick={() => {
270
- setOpenCalendar(true)
271
- setCalendarDate(value)
337
+ changeWeeks(dummyDate, true)
272
338
  }}
273
- padding="8px"
274
- height="36px"
339
+ width="130px"
340
+ height="32px"
275
341
  background="#FFF"
276
342
  />
277
343
  </div>
278
344
  </div>
279
- <div className="flex flex-row justify-between gap-1 items-center">
280
- {weekDays.map((day, i) => {
281
- return daySelector(`${day.dayOrderInMonth}, ${day.dayName}`, day.date)
282
- })}
283
- </div>
284
- <div className="flex flex-row justify-between items-center">
285
- <KButton
286
- text="Previous Week"
287
- padding="6px"
288
- leftIcon={LeftIcon}
289
- onClick={() => {
290
- changeWeeks(dummyDate, false)
291
- }}
292
- width="130px"
293
- height="32px"
294
- background="#FFF"
295
- />
296
- <KButton
297
- text="Next Week"
298
- padding="6px"
299
- rightIcon={RightIcon}
300
- onClick={() => {
301
- changeWeeks(dummyDate, true)
302
- }}
303
- width="130px"
304
- height="32px"
305
- background="#FFF"
306
- />
307
- </div>
308
345
  </div>
346
+ ) : (
347
+ <div>
348
+ <KButton
349
+ icon={CalendarNewIcon}
350
+ onClick={() => {
351
+ setOpenCalendar(true)
352
+ setCalendarDate(value)
353
+ }}
354
+ padding="14px"
355
+ width="48px"
356
+ height="48px"
357
+ background="#F7F7F7"
358
+ hoverBackground="#F3F3F3"
359
+ />
309
360
  </div>
361
+ )}
310
362
  </React.Fragment>
311
363
  )
312
364
  }
@@ -0,0 +1,55 @@
1
+ import { Meta, StoryFn } from "@storybook/react"
2
+ import KSelectRange, { KSelectRangeProps, DateRangeType } from "./KSelectRange"
3
+ import { useEffect, useState } from "react"
4
+
5
+ export default {
6
+ title: "ReactComponentLibrary/KSelectRange",
7
+ component: KSelectRange,
8
+ parameters: {
9
+ layout: "centered"
10
+ }
11
+ } as Meta<typeof KSelectRange>
12
+
13
+ const KSelectRangeWrapper: React.FC<KSelectRangeProps> = (args) => {
14
+ const [selectedDate, setSelectedDate] = useState<DateRangeType>([
15
+ new Date(new Date().setMonth(new Date().getMonth() - 10)), // Start date: 3 months ago
16
+ new Date() // End date: today
17
+ ])
18
+ useEffect(() => {
19
+ // console.log("selectedDate: ", selectedDate)
20
+ }, [selectedDate])
21
+
22
+ return (
23
+ <div><KSelectRange
24
+ {...args}
25
+ value={selectedDate}
26
+ onChange={(date: DateRangeType) => {
27
+ // console.log("date: ", date)
28
+ if (date) {
29
+ setSelectedDate(date)
30
+ console.log("updating is completed: ", date)
31
+ // console.log("updating is completed date.toISOString(): ", date?.toISOString())
32
+ } else {
33
+ setSelectedDate(null)
34
+ // console.log("Deleting is completed")
35
+ }
36
+ }}
37
+ /></div>
38
+ )
39
+ }
40
+
41
+ const Template: StoryFn<typeof KSelectRangeWrapper> = (args) => <KSelectRangeWrapper {...args} />
42
+
43
+ export const KSelectRangePrimary = Template.bind({})
44
+ KSelectRangePrimary.args = {
45
+ onChange: (value) => {
46
+ if (value) {
47
+ console.log("value is updated using this value:", value)
48
+ } else {
49
+ console.log("value is deleted, because it is: ", value)
50
+ }
51
+ }
52
+ }
53
+
54
+ export const KSelectRangeHoverText = Template.bind({})
55
+ KSelectRangeHoverText.args = {}
@@ -0,0 +1,242 @@
1
+ import React, { CSSProperties, useEffect, useState } from "react"
2
+ import Calendar from "react-calendar"
3
+ import "./KSelectRangeCustom.css"
4
+ //@ts-ignore
5
+ import LeftIcon from "../../assets/chevron-left.svg"
6
+ //@ts-ignore
7
+ import CalendarNewIcon from "../../assets/calendar-new.svg"
8
+ //@ts-ignore
9
+ import RightIcon from "../../assets/chevron-right.svg"
10
+ import "../../main.css"
11
+ import KButton from "../KButton"
12
+
13
+ export interface KSelectRangeProps {
14
+ value: DateRangeType
15
+ onChange: (date: DateRangeType) => void
16
+ }
17
+
18
+ export type DateRangeType = Date | null | [Date | null, Date | null]
19
+
20
+ const KSelectRange: React.FC<KSelectRangeProps> = (props) => {
21
+ const [value, setValue] = useState<DateRangeType>(props.value)
22
+ const [range, setRange] = useState<DateRangeType>(props.value)
23
+ const [loading, setLoading] = useState(false)
24
+
25
+ const [openCalendar, setOpenCalendar] = useState<boolean>(false)
26
+ const [shorthandIndex, setShorthandIndex] = useState<{ current: number; approved: number }>({
27
+ current: -1,
28
+ approved: -1
29
+ })
30
+
31
+ const formatShortWeekday = (locale: string | undefined, date: Date): string => {
32
+ return date.toLocaleDateString(locale, { weekday: "short" }).charAt(0) // Return only the first letter of the weekday
33
+ }
34
+
35
+ const formatMonthYear = (locale: string | undefined, date: Date): string => {
36
+ const formattedDate = date.toLocaleDateString(locale, { month: "short", year: "numeric" })
37
+ const [month, year] = formattedDate.split(" ")
38
+ const capitalizedMonth = month.charAt(0).toUpperCase() + month.slice(1).toLowerCase()
39
+ return `${capitalizedMonth}, ${year}`
40
+ }
41
+
42
+ const shorthandDateSelection = (isMonth: boolean, range: number) => {
43
+ const theDate = new Date()
44
+ // if isMonth is false, then it is year
45
+ const year = theDate.getFullYear()
46
+ const month = theDate.getMonth()
47
+ if (isMonth) {
48
+ const endDate = new Date(year, month)
49
+ const startDate = new Date(year, month - (range - 1))
50
+ setRange([startDate, endDate])
51
+ } else {
52
+ const endDate = new Date(year + range, 11)
53
+ const startDate = new Date(year + range, 0)
54
+ setRange([startDate, endDate])
55
+ }
56
+
57
+ setOpenCalendar(false)
58
+ setTimeout(() => {
59
+ setOpenCalendar(true)
60
+ }, 10)
61
+ }
62
+
63
+ useEffect(() => {
64
+ props.onChange(value)
65
+ }, [value])
66
+
67
+ const renderPopUpCalendar = () => {
68
+ return (
69
+ <div className="flex flex-row">
70
+ <div className="flex flex-col gap-0">
71
+ <Calendar
72
+ className="kselect-range"
73
+ locale="en-US"
74
+ value={range}
75
+ onChange={(dates) => {
76
+ setRange(dates)
77
+ setTimeout(() => {
78
+ setLoading(false)
79
+ }, 200)
80
+ }}
81
+ onClickMonth={() => {
82
+ setLoading(true)
83
+ setShorthandIndex({ ...shorthandIndex, current: -1 })
84
+ }}
85
+ defaultValue={null}
86
+ next2Label={null}
87
+ prev2Label={null}
88
+ prevLabel={<img src={LeftIcon} />}
89
+ nextLabel={<img src={RightIcon} />}
90
+ formatShortWeekday={formatShortWeekday}
91
+ formatMonthYear={formatMonthYear}
92
+ selectRange
93
+ maxDetail="year"
94
+ />
95
+ <div
96
+ className="h-19 w-[350px] bg-[#FFF] flex flex-row gap-4 py-4 justify-center border-[1px] border-[#E7E7E7] border-t-0 rounded-b-[10px]"
97
+ style={{
98
+ borderBottomRightRadius: "0px"
99
+ }}
100
+ >
101
+ <KButton
102
+ text="Cancel"
103
+ height="44px"
104
+ width="160px"
105
+ background="#FFF"
106
+ textColor="#111"
107
+ onClick={() => {
108
+ setRange(value)
109
+ setOpenCalendar(false)
110
+ const approvedIndex = shorthandIndex.approved
111
+ setShorthandIndex({ ...shorthandIndex, current: approvedIndex })
112
+ }}
113
+ />
114
+ <KButton
115
+ text="Apply"
116
+ height="44px"
117
+ width="160px"
118
+ background="#F2FE67"
119
+ textColor="#111"
120
+ disabled={loading}
121
+ onClick={() => {
122
+ setValue(range)
123
+ setOpenCalendar(false)
124
+ const currentIndex = shorthandIndex.current
125
+ setShorthandIndex({ ...shorthandIndex, approved: currentIndex })
126
+ }}
127
+ />
128
+ </div>
129
+ </div>
130
+ <div
131
+ className="w-[160px] bg-[#FFF] flex flex-col items-center justify-between px-2.5 pt-5 pb-4"
132
+ style={{
133
+ border: "1px solid #E7E7E7",
134
+ borderLeft: "0px",
135
+ borderTopRightRadius: "16px",
136
+ borderBottomRightRadius: "16px"
137
+ }}
138
+ >
139
+ <KButton
140
+ onClick={() => {
141
+ shorthandDateSelection(true, 3)
142
+ setShorthandIndex({ ...shorthandIndex, current: 0 })
143
+ }}
144
+ width="140px"
145
+ background={shorthandIndex.current === 0 ? "#000" : "#FFF"}
146
+ textColor={shorthandIndex.current === 0 ? "#FFF" : "#000"}
147
+ text="Last 3 months"
148
+ borderRadius={1}
149
+ shadowDisabled
150
+ hoverBackground="#F0F0F0"
151
+ height="40px"
152
+ />
153
+ <KButton
154
+ onClick={() => {
155
+ shorthandDateSelection(true, 6)
156
+ setShorthandIndex({ ...shorthandIndex, current: 1 })
157
+ }}
158
+ width="140px"
159
+ background={shorthandIndex.current === 1 ? "#000" : "#FFF"}
160
+ textColor={shorthandIndex.current === 1 ? "#FFF" : "#000"}
161
+ text="Last 6 months"
162
+ borderRadius={1}
163
+ shadowDisabled
164
+ hoverBackground="#F0F0F0"
165
+ height="40px"
166
+ />
167
+ <KButton
168
+ onClick={() => {
169
+ shorthandDateSelection(true, 12)
170
+ setShorthandIndex({ ...shorthandIndex, current: 2 })
171
+ }}
172
+ width="140px"
173
+ background={shorthandIndex.current === 2 ? "#000" : "#FFF"}
174
+ textColor={shorthandIndex.current === 2 ? "#FFF" : "#000"}
175
+ text="Last 12 months"
176
+ borderRadius={1}
177
+ shadowDisabled
178
+ hoverBackground="#F0F0F0"
179
+ height="40px"
180
+ />
181
+ <KButton
182
+ onClick={() => {
183
+ shorthandDateSelection(false, 0)
184
+ setShorthandIndex({ ...shorthandIndex, current: 3 })
185
+ }}
186
+ width="140px"
187
+ background={shorthandIndex.current === 3 ? "#000" : "#FFF"}
188
+ textColor={shorthandIndex.current === 3 ? "#FFF" : "#000"}
189
+ text="This year"
190
+ borderRadius={1}
191
+ shadowDisabled
192
+ hoverBackground="#F0F0F0"
193
+ height="40px"
194
+ />
195
+ <KButton
196
+ onClick={() => {
197
+ shorthandDateSelection(false, -1)
198
+ setShorthandIndex({ ...shorthandIndex, current: 4 })
199
+ }}
200
+ width="140px"
201
+ background={shorthandIndex.current === 4 ? "#000" : "#FFF"}
202
+ textColor={shorthandIndex.current === 4 ? "#FFF" : "#000"}
203
+ text="Last year"
204
+ borderRadius={1}
205
+ shadowDisabled
206
+ hoverBackground="#F0F0F0"
207
+ height="40px"
208
+ />
209
+ </div>
210
+ </div>
211
+ )
212
+ }
213
+
214
+ return (
215
+ <React.Fragment>
216
+ {openCalendar && (
217
+ <div className="w-[100vw] h-[100vh] fixed left-0 top-0 flex items-center justify-center z-50">
218
+ <div>{renderPopUpCalendar()}</div>
219
+ </div>
220
+ )}
221
+ <div>
222
+ <div className="flex flex-row justify-between gap-2 items-center">
223
+ <div>
224
+ <KButton
225
+ icon={CalendarNewIcon}
226
+ onClick={() => {
227
+ setOpenCalendar(true)
228
+ }}
229
+ padding="14px"
230
+ width="48px"
231
+ height="48px"
232
+ background="#F7F7F7"
233
+ hoverBackground="#F3F3F3"
234
+ />
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </React.Fragment>
239
+ )
240
+ }
241
+
242
+ export default KSelectRange