webcoreui 0.0.11 → 0.1.0

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 (141) hide show
  1. package/README.md +42 -11
  2. package/astro.d.ts +4 -0
  3. package/astro.js +4 -0
  4. package/components/Accordion/Accordion.astro +10 -8
  5. package/components/Accordion/Accordion.svelte +8 -8
  6. package/components/Accordion/Accordion.tsx +7 -6
  7. package/components/Accordion/accordion.module.scss +65 -0
  8. package/components/Alert/Alert.astro +11 -7
  9. package/components/Alert/Alert.svelte +9 -7
  10. package/components/Alert/Alert.tsx +11 -7
  11. package/components/Alert/alert.module.scss +51 -0
  12. package/components/Alert/alert.ts +3 -1
  13. package/components/Avatar/Avatar.astro +4 -4
  14. package/components/Avatar/Avatar.svelte +13 -7
  15. package/components/Avatar/Avatar.tsx +11 -9
  16. package/components/Avatar/{avatar.scss → avatar.module.scss} +11 -8
  17. package/components/Badge/Badge.astro +8 -8
  18. package/components/Badge/Badge.svelte +25 -13
  19. package/components/Badge/Badge.tsx +26 -8
  20. package/components/Badge/badge.module.scss +86 -0
  21. package/components/Badge/badge.ts +8 -1
  22. package/components/Button/Button.astro +9 -7
  23. package/components/Button/Button.svelte +13 -11
  24. package/components/Button/Button.tsx +10 -8
  25. package/components/Button/button.module.scss +87 -0
  26. package/components/Button/button.ts +6 -2
  27. package/components/Card/Card.astro +7 -15
  28. package/components/Card/Card.svelte +16 -13
  29. package/components/Card/Card.tsx +15 -11
  30. package/components/Card/card.module.scss +38 -0
  31. package/components/Checkbox/Checkbox.astro +10 -10
  32. package/components/Checkbox/Checkbox.svelte +19 -18
  33. package/components/Checkbox/Checkbox.tsx +12 -11
  34. package/components/Checkbox/checkbox.module.scss +70 -0
  35. package/components/Checkbox/checkbox.ts +5 -1
  36. package/components/ConditionalWrapper/ConditionalWrapper.svelte +1 -1
  37. package/components/Icon/Icon.astro +2 -2
  38. package/components/Icon/Icon.svelte +1 -8
  39. package/components/Icon/Icon.tsx +1 -8
  40. package/components/Icon/map.ts +23 -0
  41. package/components/Input/Input.astro +50 -52
  42. package/components/Input/Input.svelte +52 -52
  43. package/components/Input/Input.tsx +59 -59
  44. package/components/Input/input.module.scss +79 -0
  45. package/components/Input/input.ts +8 -2
  46. package/components/Menu/Menu.astro +107 -0
  47. package/components/Menu/Menu.svelte +88 -0
  48. package/components/Menu/Menu.tsx +107 -0
  49. package/components/Menu/menu.module.scss +141 -0
  50. package/components/Menu/menu.ts +21 -0
  51. package/components/Progress/Progress.astro +42 -40
  52. package/components/Progress/Progress.svelte +40 -38
  53. package/components/Progress/Progress.tsx +48 -47
  54. package/components/Progress/progress.module.scss +70 -0
  55. package/components/Radio/Radio.astro +57 -57
  56. package/components/Radio/Radio.svelte +58 -56
  57. package/components/Radio/Radio.tsx +69 -68
  58. package/components/Radio/radio.module.scss +84 -0
  59. package/components/Radio/radio.ts +4 -0
  60. package/components/Rating/Rating.astro +13 -10
  61. package/components/Rating/Rating.svelte +15 -15
  62. package/components/Rating/Rating.tsx +22 -11
  63. package/components/Rating/rating.module.scss +45 -0
  64. package/components/Rating/rating.ts +1 -1
  65. package/components/Spinner/Spinner.astro +44 -42
  66. package/components/Spinner/Spinner.svelte +40 -38
  67. package/components/Spinner/Spinner.tsx +45 -44
  68. package/components/Spinner/{spinner.scss → spinner.module.scss} +50 -41
  69. package/components/Switch/Switch.astro +13 -11
  70. package/components/Switch/Switch.svelte +26 -24
  71. package/components/Switch/Switch.tsx +14 -12
  72. package/components/Switch/switch.module.scss +82 -0
  73. package/components/Switch/switch.ts +8 -4
  74. package/components/Table/Table.astro +60 -60
  75. package/components/Table/Table.svelte +56 -54
  76. package/components/Table/Table.tsx +64 -63
  77. package/components/Table/{table.scss → table.module.scss} +60 -65
  78. package/components/Tabs/Tabs.astro +76 -76
  79. package/components/Tabs/Tabs.svelte +56 -54
  80. package/components/Tabs/Tabs.tsx +70 -69
  81. package/components/Tabs/tabs.module.scss +125 -0
  82. package/components/ThemeSwitcher/ThemeSwitcher.astro +106 -0
  83. package/components/ThemeSwitcher/ThemeSwitcher.svelte +76 -0
  84. package/components/ThemeSwitcher/ThemeSwitcher.tsx +89 -0
  85. package/components/ThemeSwitcher/themeswitcher.module.scss +76 -0
  86. package/components/ThemeSwitcher/themeswitcher.ts +13 -0
  87. package/components/Timeline/Timeline.astro +36 -34
  88. package/components/Timeline/Timeline.svelte +32 -30
  89. package/components/Timeline/Timeline.tsx +38 -37
  90. package/components/Timeline/{timeline.scss → timeline.module.scss} +76 -71
  91. package/components/TimelineItem/TimelineItem.astro +27 -26
  92. package/components/TimelineItem/TimelineItem.svelte +24 -22
  93. package/components/TimelineItem/TimelineItem.tsx +33 -32
  94. package/components/TimelineItem/timelineitem.module.scss +29 -0
  95. package/components/Toast/Toast.astro +41 -30
  96. package/components/Toast/Toast.svelte +32 -21
  97. package/components/Toast/Toast.tsx +38 -28
  98. package/components/Toast/toast.module.scss +40 -0
  99. package/components/Toast/toast.ts +8 -6
  100. package/icons/moon.svg +3 -0
  101. package/icons/sun.svg +3 -0
  102. package/icons.d.ts +11 -0
  103. package/icons.js +9 -0
  104. package/index.js +3 -0
  105. package/package.json +5 -1
  106. package/react.d.ts +4 -0
  107. package/react.js +4 -0
  108. package/scss/config/color-palette.scss +23 -0
  109. package/scss/config/css-values.scss +44 -0
  110. package/scss/config/layout.scss +41 -0
  111. package/scss/config/mixins.scss +395 -9
  112. package/scss/config/typography.scss +66 -0
  113. package/scss/config.scss +6 -1
  114. package/scss/global/elements.scss +22 -2
  115. package/scss/global/scrollbar.scss +24 -0
  116. package/scss/global/theme.scss +140 -0
  117. package/scss/global/tooltip.scss +47 -39
  118. package/scss/global/utility.scss +33 -4
  119. package/scss/global.scss +2 -1
  120. package/scss/resets.scss +64 -11
  121. package/scss/setup.scss +25 -31
  122. package/svelte.d.ts +16 -12
  123. package/svelte.js +4 -0
  124. package/utils/classNames.ts +4 -0
  125. package/utils/cookies.ts +28 -0
  126. package/utils/event.ts +17 -0
  127. package/utils/toast.ts +15 -11
  128. package/components/Accordion/accordion.scss +0 -63
  129. package/components/Alert/alert.scss +0 -53
  130. package/components/Badge/badge.scss +0 -85
  131. package/components/Button/button.scss +0 -91
  132. package/components/Card/card.scss +0 -37
  133. package/components/Checkbox/checkbox.scss +0 -85
  134. package/components/Input/input.scss +0 -83
  135. package/components/Progress/progress.scss +0 -66
  136. package/components/Radio/radio.scss +0 -92
  137. package/components/Rating/rating.scss +0 -37
  138. package/components/Switch/switch.scss +0 -84
  139. package/components/Tabs/tabs.scss +0 -134
  140. package/components/TimelineItem/timelineitem.scss +0 -31
  141. package/components/Toast/toast.scss +0 -43
@@ -1,44 +1,45 @@
1
- import React from 'react'
2
- import type { SpinnerProps } from './spinner'
3
-
4
- import './spinner.scss'
5
-
6
- const Spinner = ({
7
- color,
8
- width,
9
- speed,
10
- size,
11
- dashArray
12
- }: SpinnerProps) => {
13
- const classes = [
14
- 'w-spinner',
15
- dashArray && 'dashed'
16
- ].filter(Boolean).join(' ')
17
-
18
- const styles = {
19
- ...(color && { '--w-spinner-color': color }),
20
- ...(width && { '--w-spinner-width': `${width}px;` }),
21
- ...(speed && { '--w-spinner-speed': `${speed}s;` }),
22
- ...(size && { '--w-spinner-size': `${size}px;` }),
23
- ...(dashArray && { '--w-spinner-dash': dashArray }),
24
- } as React.CSSProperties
25
-
26
- return (
27
- <svg
28
- className={classes}
29
- viewBox="25 25 50 50"
30
- role="status"
31
- style={styles}
32
- >
33
- <circle
34
- className="spinner-path"
35
- cx="50"
36
- cy="50"
37
- r="20"
38
- fill="none"
39
- />
40
- </svg>
41
- )
42
- }
43
-
44
- export default Spinner
1
+ import React from 'react'
2
+ import type { SpinnerProps } from './spinner'
3
+
4
+ import styles from './spinner.module.scss'
5
+ import { classNames } from '../../utils/classNames'
6
+
7
+ const Spinner = ({
8
+ color,
9
+ width,
10
+ speed,
11
+ size,
12
+ dashArray
13
+ }: SpinnerProps) => {
14
+ const classes = classNames([
15
+ styles.spinner,
16
+ dashArray && styles.dashed
17
+ ])
18
+
19
+ const stylesVariable = {
20
+ ...(color && { '--w-spinner-color': color }),
21
+ ...(width && { '--w-spinner-width': `${width}px;` }),
22
+ ...(speed && { '--w-spinner-speed': `${speed}s;` }),
23
+ ...(size && { '--w-spinner-size': `${size}px;` }),
24
+ ...(dashArray && { '--w-spinner-dash': dashArray }),
25
+ } as React.CSSProperties
26
+
27
+ return (
28
+ <svg
29
+ className={classes}
30
+ viewBox="25 25 50 50"
31
+ role="status"
32
+ style={stylesVariable}
33
+ >
34
+ <circle
35
+ className={styles.path}
36
+ cx="50"
37
+ cy="50"
38
+ r="20"
39
+ fill="none"
40
+ />
41
+ </svg>
42
+ )
43
+ }
44
+
45
+ export default Spinner
@@ -1,41 +1,50 @@
1
- @import '../../scss/config.scss';
2
-
3
- .w-spinner {
4
- margin: 0px auto;
5
- width: var(--w-spinner-size);
6
- height: var(--w-spinner-size);
7
- animation: rotate var(--w-spinner-speed) linear infinite;
8
-
9
- &.dashed .spinner-path {
10
- stroke-dasharray: var(--w-spinner-dash);
11
- animation: none;
12
- }
13
-
14
- .spinner-path {
15
- stroke: var(--w-spinner-color);
16
- stroke-width: var(--w-spinner-width);
17
- animation: dash 1.5s ease-in-out infinite;
18
- stroke-linecap: round;
19
- }
20
- }
21
-
22
- @keyframes rotate {
23
- 100% {
24
- transform: rotate(360deg);
25
- }
26
- }
27
-
28
- @keyframes dash {
29
- 0% {
30
- stroke-dasharray: 1, 200;
31
- stroke-dashoffset: 0;
32
- }
33
- 50% {
34
- stroke-dasharray: 89, 200;
35
- stroke-dashoffset: -35;
36
- }
37
- 100% {
38
- stroke-dasharray: 89, 200;
39
- stroke-dashoffset: -124;
40
- }
41
- }
1
+ @use '../../scss/config.scss' as *;
2
+
3
+ body {
4
+ --w-spinner-color: var(--w-color-primary);
5
+ --w-spinner-width: 2px;
6
+ --w-spinner-speed: 2s;
7
+ --w-spinner-size: 30px;
8
+ --w-spinner-dash: 8;
9
+ }
10
+
11
+ .spinner {
12
+ @include spacing(auto-none);
13
+
14
+ width: var(--w-spinner-size);
15
+ height: var(--w-spinner-size);
16
+ animation: rotate var(--w-spinner-speed) linear infinite;
17
+
18
+ &.dashed .path {
19
+ stroke-dasharray: var(--w-spinner-dash);
20
+ animation: none;
21
+ }
22
+
23
+ .path {
24
+ stroke: var(--w-spinner-color);
25
+ stroke-width: var(--w-spinner-width);
26
+ animation: dash 1.5s ease-in-out infinite;
27
+ stroke-linecap: round;
28
+ }
29
+ }
30
+
31
+ @keyframes rotate {
32
+ 100% {
33
+ transform: rotate(360deg);
34
+ }
35
+ }
36
+
37
+ @keyframes dash {
38
+ 0% {
39
+ stroke-dasharray: 1, 200;
40
+ stroke-dashoffset: 0;
41
+ }
42
+ 50% {
43
+ stroke-dasharray: 89, 200;
44
+ stroke-dashoffset: -35;
45
+ }
46
+ 100% {
47
+ stroke-dasharray: 89, 200;
48
+ stroke-dashoffset: -124;
49
+ }
50
+ }
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  import type { SwitchProps } from './switch'
3
- import './switch.scss'
3
+
4
+ import styles from './switch.module.scss'
5
+ import { classNames } from '../../utils/classNames'
4
6
 
5
7
  interface Props extends SwitchProps {}
6
8
 
@@ -17,22 +19,22 @@ const {
17
19
  } = Astro.props
18
20
 
19
21
  const classes = [
20
- 'w-switch',
21
- reverse && 'reverse',
22
- small && 'small',
23
- square && 'square',
24
- disabled && 'disabled',
22
+ styles.switch,
23
+ reverse && styles.reverse,
24
+ small && styles.small,
25
+ square && styles.square,
26
+ disabled && styles.disabled,
25
27
  className
26
28
  ]
27
29
 
28
- const styles = [
30
+ const styleVariables = classNames([
29
31
  offColor && `--w-switch-off-color: ${offColor};`,
30
32
  onColor && `--w-switch-on-color: ${onColor};`
31
- ].filter(Boolean).join(' ')
33
+ ])
32
34
  ---
33
35
 
34
- <label class:list={classes} style={styles || null}>
36
+ <label class:list={classes} style={styleVariables}>
35
37
  <input type="checkbox" checked={toggled} disabled={disabled} />
36
- <span class="toggle"></span>
37
- {label && <span class="label">{label}</span>}
38
+ <span class={styles.toggle}></span>
39
+ {label && <span class={styles.label}>{label}</span>}
38
40
  </label>
@@ -1,42 +1,44 @@
1
1
  <script lang="ts">
2
- import type { SwitchProps } from './switch'
3
- import './switch.scss'
2
+ import type { SvelteSwitchProps } from './switch'
3
+
4
+ import styles from './switch.module.scss'
5
+ import { classNames } from '../../utils/classNames'
4
6
 
5
- export let label: SwitchProps['label'] = ''
6
- export let toggled: SwitchProps['toggled'] = false
7
- export let offColor: SwitchProps['offColor'] = ''
8
- export let onColor: SwitchProps['onColor'] = ''
9
- export let reverse: SwitchProps['reverse'] = false
10
- export let small: SwitchProps['small'] = false
11
- export let square: SwitchProps['square'] = false
12
- export let disabled: SwitchProps['disabled'] = false
13
- export let className: SwitchProps['className'] = ''
14
- export let onClick: () => any = () => {}
7
+ export let label: SvelteSwitchProps['label'] = ''
8
+ export let toggled: SvelteSwitchProps['toggled'] = false
9
+ export let offColor: SvelteSwitchProps['offColor'] = ''
10
+ export let onColor: SvelteSwitchProps['onColor'] = ''
11
+ export let reverse: SvelteSwitchProps['reverse'] = false
12
+ export let small: SvelteSwitchProps['small'] = false
13
+ export let square: SvelteSwitchProps['square'] = false
14
+ export let disabled: SvelteSwitchProps['disabled'] = false
15
+ export let className: SvelteSwitchProps['className'] = ''
16
+ export let onClick: SvelteSwitchProps['onClick'] = () => {}
15
17
 
16
- const classes = [
17
- 'w-switch',
18
- reverse && 'reverse',
19
- small && 'small',
20
- square && 'square',
21
- disabled && 'disabled',
18
+ const classes = classNames([
19
+ styles.switch,
20
+ reverse && styles.reverse,
21
+ small && styles.small,
22
+ square && styles.square,
23
+ disabled && styles.disabled,
22
24
  className
23
- ].filter(Boolean).join(' ')
25
+ ])
24
26
 
25
- const styles = [
27
+ const styleVariables = classNames([
26
28
  offColor && `--w-switch-off-color: ${offColor};`,
27
29
  onColor && `--w-switch-on-color: ${onColor};`
28
- ].filter(Boolean).join(' ')
30
+ ])
29
31
  </script>
30
32
 
31
- <label class={classes} style={styles || null}>
33
+ <label class={classes} style={styleVariables || null}>
32
34
  <input
33
35
  type="checkbox"
34
36
  checked={toggled}
35
37
  disabled={disabled}
36
38
  on:click={onClick}
37
39
  />
38
- <span class="toggle"></span>
40
+ <span class={styles.toggle}></span>
39
41
  {#if label}
40
- <span class="label">{label}</span>
42
+ <span class={styles.label}>{label}</span>
41
43
  {/if}
42
44
  </label>
@@ -1,6 +1,8 @@
1
1
  import React from 'react'
2
2
  import type { ReactSwitchProps } from './switch'
3
- import './switch.scss'
3
+
4
+ import styles from './switch.module.scss'
5
+ import { classNames } from '../../utils/classNames'
4
6
 
5
7
  const Switch = ({
6
8
  label,
@@ -14,30 +16,30 @@ const Switch = ({
14
16
  className,
15
17
  onClick
16
18
  }: ReactSwitchProps) => {
17
- const classes = [
18
- 'w-switch',
19
- reverse && 'reverse',
20
- small && 'small',
21
- square && 'square',
22
- disabled && 'disabled',
19
+ const classes = classNames([
20
+ styles.switch,
21
+ reverse && styles.reverse,
22
+ small && styles.small,
23
+ square && styles.square,
24
+ disabled && styles.disabled,
23
25
  className
24
- ].filter(Boolean).join(' ')
26
+ ])
25
27
 
26
- const styles = {
28
+ const styleVariables = {
27
29
  ...(offColor && { '--w-switch-off-color': offColor }),
28
30
  ...(onColor && { '--w-switch-on-color': onColor })
29
31
  } as React.CSSProperties
30
32
 
31
33
  return (
32
- <label className={classes} style={styles || null}>
34
+ <label className={classes} style={styleVariables || null}>
33
35
  <input
34
36
  type="checkbox"
35
37
  defaultChecked={toggled}
36
38
  disabled={disabled}
37
39
  onClick={onClick}
38
40
  />
39
- <span className="toggle"></span>
40
- {label && <span className="label">{label}</span>}
41
+ <span className={styles.toggle}></span>
42
+ {label && <span className={styles.label}>{label}</span>}
41
43
  </label>
42
44
  )
43
45
 
@@ -0,0 +1,82 @@
1
+ @use '../../scss/config.scss' as *;
2
+
3
+ body {
4
+ --w-switch-off-color: var(--w-color-primary-50);
5
+ --w-switch-on-color: var(--w-color-primary);
6
+ }
7
+
8
+ .switch {
9
+ @include layout(inline-flex, v-center, sm);
10
+ cursor: pointer;
11
+
12
+ &.reverse {
13
+ @include layout(row-reverse);
14
+ }
15
+
16
+ &.disabled .toggle {
17
+ @include background(primary-40);
18
+ cursor: no-drop;
19
+
20
+ &::before {
21
+ @include background(primary-50);
22
+ }
23
+ }
24
+
25
+ &.small {
26
+ input:checked + span::before {
27
+ transform: translateX(20px);
28
+ }
29
+
30
+ .toggle {
31
+ @include size(w40px, h20px);
32
+
33
+ &::before {
34
+ @include size(14px);
35
+ }
36
+ }
37
+
38
+ .label {
39
+ @include typography(sm);
40
+ }
41
+ }
42
+
43
+ &.square .toggle {
44
+ @include border-radius(md);
45
+
46
+ &::before {
47
+ @include border-radius(md);
48
+ }
49
+ }
50
+
51
+ input {
52
+ @include visibility(none);
53
+
54
+ &:checked + span {
55
+ @include background(var(--w-switch-on-color));
56
+
57
+ &::before {
58
+ transform: translateX(30px);
59
+ }
60
+ }
61
+ }
62
+
63
+ .toggle {
64
+ @include transition(background);
65
+ @include position(relative);
66
+ @include size(w60px, h30px);
67
+ @include border-radius(xl);
68
+ @include background(var(--w-switch-off-color));
69
+
70
+ &::before {
71
+ @include position(absolute, l3px, b3px);
72
+ @include size(24px);
73
+ @include border-radius(max);
74
+ @include background(primary-70);
75
+
76
+ content: '';
77
+ transition: 0.3s;
78
+ }
79
+ }
80
+ }
81
+
82
+
@@ -1,15 +1,19 @@
1
1
  export type SwitchProps = {
2
2
  label?: string
3
- toggled?: boolean
4
- offColor?: string
5
- onColor?: string
6
3
  reverse?: boolean
4
+ toggled?: boolean
5
+ disabled?: boolean
7
6
  small?: boolean
8
7
  square?: boolean
9
- disabled?: boolean
8
+ onColor?: string
9
+ offColor?: string
10
10
  className?: string
11
11
  }
12
12
 
13
+ export type SvelteSwitchProps = {
14
+ onClick?: (key: any) => any
15
+ } & SwitchProps
16
+
13
17
  export type ReactSwitchProps = {
14
18
  onClick?: (key: any) => any
15
19
  } & SwitchProps
@@ -1,60 +1,60 @@
1
- ---
2
- import type { TableProps } from './table'
3
- import './table.scss'
4
-
5
- interface Props extends TableProps {}
6
-
7
- const {
8
- headings,
9
- footer,
10
- data,
11
- hover,
12
- striped,
13
- offsetStripe,
14
- compact,
15
- className
16
- } = Astro.props
17
-
18
- const classes = [
19
- 'w-table',
20
- hover && 'hover',
21
- striped && `striped-${striped}s`,
22
- offsetStripe && 'offset',
23
- compact && 'compact',
24
- className
25
- ]
26
- ---
27
-
28
- <div class:list={classes}>
29
- <table>
30
- {headings?.length && (
31
- <thead>
32
- <tr>
33
- {headings.map(heading => (
34
- <th>{heading}</th>
35
- ))}
36
- </tr>
37
- </thead>
38
- )}
39
- <tbody>
40
- {data.map(row => (
41
- <tr>
42
- {row.map(column => (
43
- <td>
44
- <Fragment set:html={column} />
45
- </td>
46
- ))}
47
- </tr>
48
- ))}
49
- </tbody>
50
- {footer?.length && (
51
- <tfoot>
52
- <tr>
53
- {footer.map(data => (
54
- <td>{data}</td>
55
- ))}
56
- </tr>
57
- </tfoot>
58
- )}
59
- </table>
60
- </div>
1
+ ---
2
+ import type { TableProps } from './table'
3
+ import styles from './table.module.scss'
4
+
5
+ interface Props extends TableProps {}
6
+
7
+ const {
8
+ headings,
9
+ footer,
10
+ data,
11
+ hover,
12
+ striped,
13
+ offsetStripe,
14
+ compact,
15
+ className
16
+ } = Astro.props
17
+
18
+ const classes = [
19
+ styles.table,
20
+ hover && styles.hover,
21
+ striped && styles[`striped-${striped}s`],
22
+ offsetStripe && styles.offset,
23
+ compact && styles.compact,
24
+ className
25
+ ]
26
+ ---
27
+
28
+ <div class:list={classes}>
29
+ <table>
30
+ {headings?.length && (
31
+ <thead>
32
+ <tr>
33
+ {headings.map(heading => (
34
+ <th>{heading}</th>
35
+ ))}
36
+ </tr>
37
+ </thead>
38
+ )}
39
+ <tbody>
40
+ {data.map(row => (
41
+ <tr>
42
+ {row.map(column => (
43
+ <td>
44
+ <Fragment set:html={column} />
45
+ </td>
46
+ ))}
47
+ </tr>
48
+ ))}
49
+ </tbody>
50
+ {footer?.length && (
51
+ <tfoot>
52
+ <tr>
53
+ {footer.map(data => (
54
+ <td>{data}</td>
55
+ ))}
56
+ </tr>
57
+ </tfoot>
58
+ )}
59
+ </table>
60
+ </div>