@enderfall/ui 0.1.0 → 0.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 (45) hide show
  1. package/assets/brand/enderfall-lockup.png +0 -0
  2. package/assets/brand/enderfall-lockup.svg +8 -0
  3. package/assets/brand/enderfall-mark.png +0 -0
  4. package/assets/brand/enderfall-mark.svg +8 -0
  5. package/dist/components/Button.d.ts +2 -1
  6. package/dist/components/Button.d.ts.map +1 -1
  7. package/dist/components/Button.js +8 -1
  8. package/dist/components/Dropdown.d.ts.map +1 -1
  9. package/dist/components/Dropdown.js +2 -2
  10. package/package.json +5 -2
  11. package/src/base.css +160 -0
  12. package/src/components/AccessGate.css +24 -0
  13. package/src/components/AccessGate.tsx +61 -0
  14. package/src/components/BookmarkDropdown.css +220 -0
  15. package/src/components/Button.css +183 -0
  16. package/src/components/Button.tsx +20 -0
  17. package/src/components/Dropdown.tsx +570 -0
  18. package/src/components/FloatingFooter.css +49 -0
  19. package/src/components/FloatingFooter.tsx +27 -0
  20. package/src/components/FormField.tsx +29 -0
  21. package/src/components/HeaderMenu.css +280 -0
  22. package/src/components/Input.css +68 -0
  23. package/src/components/Input.tsx +23 -0
  24. package/src/components/MainHeader.css +167 -0
  25. package/src/components/MainHeader.tsx +51 -0
  26. package/src/components/Modal.css +282 -0
  27. package/src/components/Modal.tsx +142 -0
  28. package/src/components/Panel.css +71 -0
  29. package/src/components/Panel.tsx +31 -0
  30. package/src/components/PreferencesModal.tsx +67 -0
  31. package/src/components/SideMenu.tsx +239 -0
  32. package/src/components/Slider.css +114 -0
  33. package/src/components/Slider.tsx +33 -0
  34. package/src/components/StackedCard.css +180 -0
  35. package/src/components/StackedCard.tsx +125 -0
  36. package/src/components/StatDots.css +122 -0
  37. package/src/components/StatDots.tsx +53 -0
  38. package/src/components/Tabs.css +108 -0
  39. package/src/components/Tabs.tsx +68 -0
  40. package/src/components/Toggle.css +161 -0
  41. package/src/components/Toggle.tsx +38 -0
  42. package/src/components/UserMenu.css +273 -0
  43. package/src/index.ts +45 -0
  44. package/src/theme.css +353 -0
  45. package/styles.css +1 -0
@@ -0,0 +1,122 @@
1
+ .ef-stat-dots {
2
+ display: grid;
3
+ grid-template-columns: var(--ef-stat-label-width, 180px) 1fr;
4
+ align-items: center;
5
+ gap: 12px;
6
+ font-size: 16px;
7
+ }
8
+
9
+
10
+ .ef-stat-dots__dots {
11
+ display: inline-flex;
12
+ gap: 4px;
13
+ }
14
+
15
+ .ef-stat-dots__input {
16
+ appearance: none;
17
+ width: 18px;
18
+ height: 18px;
19
+ border: 2px solid var(--line);
20
+ border-radius: var(--ef-stat-dots-radius, 6px);
21
+ background: var(--card);
22
+ cursor: pointer;
23
+ position: relative;
24
+ display: inline-grid;
25
+ place-items: center;
26
+ transition: border-color 0.2s ease, background 0.2s ease;
27
+ }
28
+
29
+ .ef-stat-dots__input::before {
30
+ content: "";
31
+ width: 8px;
32
+ height: 8px;
33
+ border-radius: var(--ef-stat-dots-check-radius, 2px);
34
+ background: var(--ef-toggle-check-bg, var(--ef-slider-border-color, var(--line-strong)));
35
+ transform: scale(0);
36
+ transition: transform 0.2s ease;
37
+ }
38
+
39
+ .ef-stat-dots__input:disabled {
40
+ cursor: not-allowed;
41
+ opacity: 0.6;
42
+ }
43
+
44
+ .ef-stat-dots__input:checked {
45
+ border-color: transparent;
46
+ background:
47
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
48
+ var(--ef-border-gradient) border-box;
49
+ box-shadow: none;
50
+ }
51
+
52
+ .ef-stat-dots__input:checked::before {
53
+ transform: scale(1);
54
+ }
55
+
56
+ :root[data-theme="galaxy"] .ef-stat-dots__input,
57
+ :root[data-theme="plain-dark"] .ef-stat-dots__input,
58
+ :root[data-theme="light"] .ef-stat-dots__input,
59
+ :root[data-theme="plain-light"] .ef-stat-dots__input,
60
+ [data-theme="galaxy"] .ef-stat-dots__input,
61
+ [data-theme="plain-dark"] .ef-stat-dots__input,
62
+ [data-theme="light"] .ef-stat-dots__input,
63
+ [data-theme="plain-light"] .ef-stat-dots__input,
64
+ .ef-stat-dots[data-ef-theme="galaxy"] .ef-stat-dots__input,
65
+ .ef-stat-dots[data-ef-theme="plain-dark"] .ef-stat-dots__input,
66
+ .ef-stat-dots[data-ef-theme="light"] .ef-stat-dots__input,
67
+ .ef-stat-dots[data-ef-theme="plain-light"] .ef-stat-dots__input {
68
+ background:
69
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
70
+ var(--ef-border-gradient) border-box;
71
+ border-color: transparent;
72
+ background-clip: padding-box, border-box;
73
+ background-origin: border-box;
74
+ }
75
+
76
+ :root[data-theme="galaxy"] .ef-stat-dots__input::before,
77
+ :root[data-theme="plain-dark"] .ef-stat-dots__input::before,
78
+ :root[data-theme="light"] .ef-stat-dots__input::before,
79
+ :root[data-theme="plain-light"] .ef-stat-dots__input::before,
80
+ [data-theme="galaxy"] .ef-stat-dots__input::before,
81
+ [data-theme="plain-dark"] .ef-stat-dots__input::before,
82
+ [data-theme="light"] .ef-stat-dots__input::before,
83
+ [data-theme="plain-light"] .ef-stat-dots__input::before,
84
+ .ef-stat-dots[data-ef-theme="galaxy"] .ef-stat-dots__input::before,
85
+ .ef-stat-dots[data-ef-theme="plain-dark"] .ef-stat-dots__input::before,
86
+ .ef-stat-dots[data-ef-theme="light"] .ef-stat-dots__input::before,
87
+ .ef-stat-dots[data-ef-theme="plain-light"] .ef-stat-dots__input::before {
88
+ background: var(--ef-border-gradient);
89
+ }
90
+
91
+ :root[data-theme="galaxy"] .ef-stat-dots__input:checked,
92
+ :root[data-theme="plain-dark"] .ef-stat-dots__input:checked,
93
+ :root[data-theme="light"] .ef-stat-dots__input:checked,
94
+ :root[data-theme="plain-light"] .ef-stat-dots__input:checked,
95
+ [data-theme="galaxy"] .ef-stat-dots__input:checked,
96
+ [data-theme="plain-dark"] .ef-stat-dots__input:checked,
97
+ [data-theme="light"] .ef-stat-dots__input:checked,
98
+ [data-theme="plain-light"] .ef-stat-dots__input:checked,
99
+ .ef-stat-dots[data-ef-theme="galaxy"] .ef-stat-dots__input:checked,
100
+ .ef-stat-dots[data-ef-theme="plain-dark"] .ef-stat-dots__input:checked,
101
+ .ef-stat-dots[data-ef-theme="light"] .ef-stat-dots__input:checked,
102
+ .ef-stat-dots[data-ef-theme="plain-light"] .ef-stat-dots__input:checked {
103
+ background:
104
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
105
+ var(--ef-border-gradient) border-box;
106
+ border-color: transparent;
107
+ background-clip: padding-box, border-box;
108
+ background-origin: border-box;
109
+ box-shadow: none;
110
+ }
111
+
112
+ :root[data-theme="atelier"] .ef-stat-dots__input,
113
+ [data-theme="atelier"] .ef-stat-dots__input,
114
+ .ef-stat-dots[data-ef-theme="atelier"] .ef-stat-dots__input {
115
+ border-radius: 0;
116
+ }
117
+
118
+ :root[data-theme="atelier"] .ef-stat-dots__input::before,
119
+ [data-theme="atelier"] .ef-stat-dots__input::before,
120
+ .ef-stat-dots[data-ef-theme="atelier"] .ef-stat-dots__input::before {
121
+ border-radius: 0;
122
+ }
@@ -0,0 +1,53 @@
1
+ import { useState, type HTMLAttributes } from "react";
2
+ import { Panel } from "./Panel";
3
+
4
+ type StatDotsProps = HTMLAttributes<HTMLDivElement> & {
5
+ label: string;
6
+ count?: number;
7
+ value?: number;
8
+ defaultValue?: number;
9
+ disabled?: boolean;
10
+ onChange?: (value: number) => void;
11
+ };
12
+
13
+ export const StatDots = ({
14
+ label,
15
+ count = 4,
16
+ value,
17
+ defaultValue = 0,
18
+ disabled = false,
19
+ onChange,
20
+ className,
21
+ ...rest
22
+ }: StatDotsProps) => {
23
+ const [internalValue, setInternalValue] = useState(defaultValue);
24
+ const currentValue = Math.max(0, Math.min(count, value ?? internalValue));
25
+ const handleSelect = (nextValue: number) => {
26
+ if (disabled) return;
27
+ const resolvedValue = nextValue === currentValue ? 0 : nextValue;
28
+ if (value === undefined) {
29
+ setInternalValue(resolvedValue);
30
+ }
31
+ onChange?.(resolvedValue);
32
+ };
33
+ const classes = ["ef-stat-dots", className].filter(Boolean).join(" ");
34
+ return (
35
+ <div className={classes} {...rest}>
36
+ <Panel variant="highlight" borderWidth={1} className="ef-stat-dots__label">
37
+ {label}
38
+ </Panel>
39
+ <div className="ef-stat-dots__dots" role="group" aria-label={label}>
40
+ {Array.from({ length: count }, (_, index) => (
41
+ <input
42
+ key={`${label}-${index}`}
43
+ className="ef-stat-dots__input"
44
+ type="checkbox"
45
+ checked={index < currentValue}
46
+ disabled={disabled}
47
+ onChange={() => handleSelect(index + 1)}
48
+ />
49
+ ))}
50
+ </div>
51
+ </div>
52
+ );
53
+ };
@@ -0,0 +1,108 @@
1
+ .ef-tabs {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 12px;
5
+ width: 100%;
6
+ }
7
+
8
+ .ef-tabs--vertical {
9
+ flex-direction: row;
10
+ align-items: flex-start;
11
+ }
12
+
13
+ .ef-tabs-list {
14
+ display: flex;
15
+ flex-wrap: wrap;
16
+ gap: 10px;
17
+ padding: 10px;
18
+ border-radius: 16px;
19
+ background:
20
+ linear-gradient(#0b0c1a, #0b0c1a) padding-box,
21
+ linear-gradient(135deg, rgba(0, 229, 255, 0.5), rgba(124, 77, 255, 0.5), rgba(255, 77, 210, 0.5)) border-box;
22
+ border: 1px solid transparent;
23
+ }
24
+
25
+ .ef-tabs-list--vertical {
26
+ flex-direction: column;
27
+ min-width: 220px;
28
+ }
29
+
30
+ .ef-tab {
31
+ border: 2px solid transparent;
32
+ padding: 8px 18px;
33
+ border-radius: 8px;
34
+ background: rgba(15, 18, 28, 0.7);
35
+ color: rgba(238, 241, 246, 0.75);
36
+ font-weight: 600;
37
+ cursor: pointer;
38
+ font-family: inherit;
39
+ letter-spacing: 0.08em;
40
+ transition: color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
41
+ display: inline-flex;
42
+ align-items: center;
43
+ gap: 8px;
44
+ }
45
+
46
+ .ef-tab:hover {
47
+ color: #eef1f6;
48
+ box-shadow: 0 0 18px rgba(124, 77, 255, 0.35);
49
+ transform: translateY(-1px);
50
+ }
51
+
52
+ .ef-tab.is-active {
53
+ background:
54
+ linear-gradient(#0b0c1a, #0b0c1a) padding-box,
55
+ linear-gradient(135deg, #00e5ff, #7c4dff, #ff4dd2, #ffb74d) border-box;
56
+ color: #f6f5ff;
57
+ box-shadow: 0 0 32px rgba(124, 77, 255, 0.65);
58
+ }
59
+
60
+ .ef-tab--vertical {
61
+ width: 100%;
62
+ justify-content: flex-start;
63
+ }
64
+
65
+ .ef-tab-icon {
66
+ display: inline-flex;
67
+ }
68
+
69
+ .ef-tab-text {
70
+ display: inline-flex;
71
+ }
72
+
73
+ .ef-tab-active-indicator {
74
+ margin-left: auto;
75
+ width: 2px;
76
+ height: 22px;
77
+ border-radius: 999px;
78
+ background: linear-gradient(180deg, #00e5ff, #7c4dff, #ff4dd2);
79
+ }
80
+
81
+ .ef-tabs-content {
82
+ min-width: 0;
83
+ flex: 1;
84
+ }
85
+
86
+ .ef-tabs-content--background {
87
+ border-radius: 16px;
88
+ padding: 12px;
89
+ background:
90
+ linear-gradient(#0b0c1a, #0b0c1a) padding-box,
91
+ linear-gradient(135deg, rgba(0, 229, 255, 0.35), rgba(124, 77, 255, 0.35), rgba(255, 77, 210, 0.35)) border-box;
92
+ border: 1px solid transparent;
93
+ }
94
+
95
+ @media (max-width: 768px) {
96
+ .ef-tabs--vertical {
97
+ flex-direction: column;
98
+ }
99
+
100
+ .ef-tabs-list--vertical {
101
+ min-width: 100%;
102
+ }
103
+
104
+ .ef-tab {
105
+ width: 100%;
106
+ justify-content: flex-start;
107
+ }
108
+ }
@@ -0,0 +1,68 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ export type TabsItem = {
4
+ id: string;
5
+ label: string;
6
+ icon?: ReactNode;
7
+ content?: ReactNode;
8
+ };
9
+
10
+ type TabsProps = {
11
+ tabs: TabsItem[];
12
+ activeTab: string;
13
+ onChange: (tabId: string) => void;
14
+ orientation?: "horizontal" | "vertical";
15
+ showContentBackground?: boolean;
16
+ className?: string;
17
+ tabContentClassName?: string;
18
+ renderTabContent?: (tab: TabsItem) => ReactNode;
19
+ };
20
+
21
+ export const Tabs = ({
22
+ tabs,
23
+ activeTab,
24
+ onChange,
25
+ orientation = "horizontal",
26
+ showContentBackground = false,
27
+ className,
28
+ tabContentClassName,
29
+ renderTabContent,
30
+ }: TabsProps) => {
31
+ const isVertical = orientation === "vertical";
32
+ const active = tabs.find((tab) => tab.id === activeTab);
33
+
34
+ return (
35
+ <div className={["ef-tabs", isVertical ? "ef-tabs--vertical" : "", className].filter(Boolean).join(" ")}>
36
+ <div className={["ef-tabs-list", isVertical ? "ef-tabs-list--vertical" : ""].filter(Boolean).join(" ")}>
37
+ {tabs.map((tab) => (
38
+ <button
39
+ key={tab.id}
40
+ type="button"
41
+ className={["ef-tab", isVertical ? "ef-tab--vertical" : "", tab.id === activeTab ? "is-active" : ""]
42
+ .filter(Boolean)
43
+ .join(" ")}
44
+ onClick={() => onChange(tab.id)}
45
+ >
46
+ {tab.icon ? <span className="ef-tab-icon">{tab.icon}</span> : null}
47
+ <span className="ef-tab-text">{tab.label}</span>
48
+ {isVertical && tab.id === activeTab ? <span className="ef-tab-active-indicator" /> : null}
49
+ </button>
50
+ ))}
51
+ </div>
52
+
53
+ {(active?.content || renderTabContent) && (
54
+ <div
55
+ className={[
56
+ "ef-tabs-content",
57
+ showContentBackground ? "ef-tabs-content--background" : "",
58
+ tabContentClassName,
59
+ ]
60
+ .filter(Boolean)
61
+ .join(" ")}
62
+ >
63
+ {renderTabContent ? renderTabContent(active as TabsItem) : active?.content}
64
+ </div>
65
+ )}
66
+ </div>
67
+ );
68
+ };
@@ -0,0 +1,161 @@
1
+ .ef-toggle {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ gap: 12px;
5
+ cursor: pointer;
6
+ color: var(--text-strong);
7
+ font-weight: 600;
8
+ }
9
+
10
+ .ef-toggle-input {
11
+ position: absolute;
12
+ opacity: 0;
13
+ width: 1px;
14
+ height: 1px;
15
+ pointer-events: none;
16
+ }
17
+
18
+ .ef-toggle-track {
19
+ width: 46px;
20
+ height: 26px;
21
+ padding: 2px;
22
+ border-radius: var(--ef-toggle-track-radius, 999px);
23
+ border: 2px solid var(--line);
24
+ background: var(--card);
25
+ display: inline-flex;
26
+ align-items: center;
27
+ transition: border-color 0.2s ease, background 0.2s ease;
28
+ }
29
+
30
+ .ef-toggle-thumb {
31
+ width: 20px;
32
+ height: 20px;
33
+ border-radius: var(--ef-toggle-thumb-radius, 999px);
34
+ background: var(--ef-slider-surface, var(--ef-surface));
35
+ border: 2px solid var(--ef-slider-border-color, var(--line));
36
+ -webkit-mask-image: radial-gradient(circle, #fff 99%, transparent 100%);
37
+ mask-image: radial-gradient(circle, #fff 99%, transparent 100%);
38
+ transform: translateX(0);
39
+ transition: transform 0.2s ease, background 0.2s ease;
40
+ }
41
+
42
+ .ef-toggle-input:checked + .ef-toggle-track {
43
+ border-color: transparent;
44
+ background:
45
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
46
+ var(--ef-border-gradient) border-box;
47
+ }
48
+
49
+ .ef-toggle-input:checked + .ef-toggle-track .ef-toggle-thumb {
50
+ transform: translateX(18px);
51
+ background: var(--ef-border-gradient);
52
+ border-color: transparent;
53
+ background-clip: border-box;
54
+ background-origin: border-box;
55
+ }
56
+
57
+ .ef-toggle-label {
58
+ display: grid;
59
+ gap: 4px;
60
+ }
61
+
62
+ .ef-toggle-description {
63
+ font-size: 0.85rem;
64
+ color: var(--text-muted);
65
+ font-weight: 500;
66
+ }
67
+
68
+ .ef-toggle-input:disabled + .ef-toggle-track {
69
+ opacity: 0.5;
70
+ }
71
+
72
+ .ef-toggle-input:disabled ~ .ef-toggle-label {
73
+ opacity: 0.6;
74
+ cursor: not-allowed;
75
+ }
76
+
77
+ :root[data-theme="galaxy"] .ef-toggle-track,
78
+ :root[data-theme="plain-dark"] .ef-toggle-track,
79
+ :root[data-theme="light"] .ef-toggle-track,
80
+ :root[data-theme="plain-light"] .ef-toggle-track {
81
+ background:
82
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
83
+ var(--ef-border-gradient) border-box;
84
+ border-color: transparent;
85
+ }
86
+
87
+ :root[data-theme="atelier"] .ef-toggle-thumb {
88
+ border-radius: var(--ef-toggle-thumb-radius, 0px);
89
+ -webkit-mask-image: none;
90
+ mask-image: none;
91
+ }
92
+
93
+ .ef-toggle-box {
94
+ width: 22px;
95
+ height: 22px;
96
+ border-radius: var(--ef-toggle-box-radius, 6px);
97
+ border: 2px solid var(--line);
98
+ background: var(--card);
99
+ display: grid;
100
+ place-items: center;
101
+ transition: border-color 0.2s ease, background 0.2s ease;
102
+ }
103
+
104
+ .ef-toggle-check {
105
+ width: 10px;
106
+ height: 10px;
107
+ border-radius: var(--ef-toggle-check-radius, 2px);
108
+ background: var(--ef-toggle-check-bg, var(--ef-slider-border-color, var(--line-strong)));
109
+ transform: scale(0);
110
+ transition: transform 0.2s ease;
111
+ }
112
+
113
+ .ef-toggle-input:checked + .ef-toggle-box {
114
+ border-color: transparent;
115
+ background:
116
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
117
+ var(--ef-border-gradient) border-box;
118
+ }
119
+
120
+ .ef-toggle-input:checked + .ef-toggle-box .ef-toggle-check {
121
+ transform: scale(1);
122
+ }
123
+
124
+ :root[data-theme="galaxy"] .ef-toggle-box,
125
+ :root[data-theme="plain-dark"] .ef-toggle-box,
126
+ :root[data-theme="light"] .ef-toggle-box,
127
+ :root[data-theme="plain-light"] .ef-toggle-box {
128
+ background:
129
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
130
+ var(--ef-border-gradient) border-box;
131
+ border-color: transparent;
132
+ }
133
+
134
+ :root[data-theme="galaxy"] .ef-toggle-thumb,
135
+ :root[data-theme="plain-dark"] .ef-toggle-thumb,
136
+ :root[data-theme="light"] .ef-toggle-thumb,
137
+ :root[data-theme="plain-light"] .ef-toggle-thumb {
138
+ background:
139
+ linear-gradient(var(--ef-surface), var(--ef-surface)) padding-box,
140
+ var(--ef-border-gradient) border-box;
141
+ border-color: transparent;
142
+ background-clip: padding-box, border-box;
143
+ background-origin: border-box;
144
+ }
145
+
146
+ :root[data-theme="galaxy"] .ef-toggle-input:checked + .ef-toggle-track .ef-toggle-thumb,
147
+ :root[data-theme="plain-dark"] .ef-toggle-input:checked + .ef-toggle-track .ef-toggle-thumb,
148
+ :root[data-theme="light"] .ef-toggle-input:checked + .ef-toggle-track .ef-toggle-thumb,
149
+ :root[data-theme="plain-light"] .ef-toggle-input:checked + .ef-toggle-track .ef-toggle-thumb {
150
+ background: var(--ef-border-gradient);
151
+ border-color: transparent;
152
+ background-clip: border-box;
153
+ background-origin: border-box;
154
+ }
155
+
156
+ :root[data-theme="galaxy"] .ef-toggle-check,
157
+ :root[data-theme="plain-dark"] .ef-toggle-check,
158
+ :root[data-theme="light"] .ef-toggle-check,
159
+ :root[data-theme="plain-light"] .ef-toggle-check {
160
+ background: var(--ef-border-gradient);
161
+ }
@@ -0,0 +1,38 @@
1
+ import type { InputHTMLAttributes } from "react";
2
+
3
+ type ToggleProps = Omit<InputHTMLAttributes<HTMLInputElement>, "type"> & {
4
+ label?: string;
5
+ description?: string;
6
+ variant?: "switch" | "checkbox";
7
+ };
8
+
9
+ export const Toggle = ({
10
+ label,
11
+ description,
12
+ className,
13
+ variant = "switch",
14
+ ...props
15
+ }: ToggleProps) => (
16
+ <label
17
+ className={["ef-toggle", `ef-toggle--${variant}`, className]
18
+ .filter(Boolean)
19
+ .join(" ")}
20
+ >
21
+ <input type="checkbox" className="ef-toggle-input" {...props} />
22
+ {variant === "switch" ? (
23
+ <span className="ef-toggle-track" aria-hidden="true">
24
+ <span className="ef-toggle-thumb" />
25
+ </span>
26
+ ) : (
27
+ <span className="ef-toggle-box" aria-hidden="true">
28
+ <span className="ef-toggle-check" />
29
+ </span>
30
+ )}
31
+ {label ? (
32
+ <span className="ef-toggle-label">
33
+ <span className="ef-toggle-text">{label}</span>
34
+ {description ? <span className="ef-toggle-description">{description}</span> : null}
35
+ </span>
36
+ ) : null}
37
+ </label>
38
+ );