@licklist/design 0.78.5-dev.110 → 0.78.5-dev.112
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.
- package/dist/Maintenance/Maintenance.scss.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/v2/components/AccountManagerCard/AccountManagerCard.scss.js +1 -1
- package/dist/v2/components/ActionMenu/ActionMenu.scss.js +1 -1
- package/dist/v2/components/Alert/Alert.scss.js +1 -1
- package/dist/v2/components/AvatarUpload/AvatarUpload.scss.js +1 -1
- package/dist/v2/components/Badge/Badge.scss.js +1 -1
- package/dist/v2/components/Button/Button.scss.js +1 -1
- package/dist/v2/components/Button/GhostButton.scss.js +1 -1
- package/dist/v2/components/Checkbox/Checkbox.d.ts.map +1 -1
- package/dist/v2/components/Checkbox/Checkbox.js +10 -50
- package/dist/v2/components/Checkbox/Checkbox.scss.js +1 -1
- package/dist/v2/components/ColorPicker/ColorPicker.d.ts +15 -0
- package/dist/v2/components/ColorPicker/ColorPicker.d.ts.map +1 -0
- package/dist/v2/components/ColorPicker/ColorPicker.js +40 -0
- package/dist/v2/components/ColorPicker/ColorPicker.scss.js +6 -0
- package/dist/v2/components/ColorPicker/index.d.ts +2 -0
- package/dist/v2/components/ColorPicker/index.d.ts.map +1 -0
- package/dist/v2/components/DataTable/DataTable.scss.js +1 -1
- package/dist/v2/components/EmptyState/EmptyState.scss.js +1 -1
- package/dist/v2/components/FeatureCard/FeatureCard.d.ts +11 -0
- package/dist/v2/components/FeatureCard/FeatureCard.d.ts.map +1 -0
- package/dist/v2/components/FeatureCard/FeatureCard.js +40 -0
- package/dist/v2/components/FeatureCard/FeatureCard.scss.js +6 -0
- package/dist/v2/components/FeatureCard/index.d.ts +3 -0
- package/dist/v2/components/FeatureCard/index.d.ts.map +1 -0
- package/dist/v2/components/FeatureToggle/FeatureToggle.scss.js +1 -1
- package/dist/v2/components/FormField/FormField.scss.js +1 -1
- package/dist/v2/components/IconButton/IconButton.d.ts +5 -1
- package/dist/v2/components/IconButton/IconButton.d.ts.map +1 -1
- package/dist/v2/components/IconButton/IconButton.js +28 -3
- package/dist/v2/components/IconButton/IconButton.scss.js +1 -1
- package/dist/v2/components/InfoGrid/InfoGrid.scss.js +1 -1
- package/dist/v2/components/Modal/DeleteModal.scss.js +1 -1
- package/dist/v2/components/NPSScore/NPSScore.scss.js +1 -1
- package/dist/v2/components/NewTabs/NewTabs.scss.js +1 -1
- package/dist/v2/components/NotificationBanner/NotificationBanner.scss.js +1 -1
- package/dist/v2/components/PeriodCard/PeriodCard.d.ts +18 -4
- package/dist/v2/components/PeriodCard/PeriodCard.d.ts.map +1 -1
- package/dist/v2/components/PeriodCard/PeriodCard.js +46 -6
- package/dist/v2/components/Select/Select.scss.js +1 -1
- package/dist/v2/components/StatusBadge/StatusBadge.scss.js +1 -1
- package/dist/v2/components/StepIndicator/StepIndicator.scss.js +1 -1
- package/dist/v2/components/TableControls/TableControls.scss.js +1 -1
- package/dist/v2/components/Tabs/Tabs.scss.js +1 -1
- package/dist/v2/components/Tooltip/Tooltip.scss.js +1 -1
- package/dist/v2/components/UserAvatar/UserAvatar.scss.js +1 -1
- package/dist/v2/components/UserPanel/UserPanel.scss.js +1 -1
- package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +1 -1
- package/dist/v2/components/ZoneCard/ZoneCard.scss.js +1 -1
- package/dist/v2/components/index.d.ts +4 -0
- package/dist/v2/components/index.d.ts.map +1 -1
- package/dist/v2/dashboard-analytics/chart/Chart.scss.js +1 -1
- package/dist/v2/dashboard-analytics/metric-card/MetricCard.scss.js +1 -1
- package/dist/v2/dashboard-analytics/venue-card/VenueCard.scss.js +1 -1
- package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.scss.js +1 -1
- package/dist/v2/icons/index.d.ts +19 -2
- package/dist/v2/icons/index.d.ts.map +1 -1
- package/dist/v2/icons/index.js +21 -4
- package/dist/v2/navigation/DashboardLayout/AdminSidebar.scss.js +1 -1
- package/dist/v2/navigation/DashboardLayout/DashboardLayout.scss.js +1 -1
- package/dist/v2/navigation/DashboardLayout/ProviderSidebar.scss.js +1 -1
- package/dist/v2/navigation/DashboardLayout/TopNavigation.scss.js +1 -1
- package/dist/v2/pages/DeleteEntity/DeleteEntityPage.d.ts +29 -0
- package/dist/v2/pages/DeleteEntity/DeleteEntityPage.d.ts.map +1 -0
- package/dist/v2/pages/DeleteEntity/DeleteEntityPage.js +294 -0
- package/dist/v2/pages/DeleteEntity/DeleteEntityPage.scss.js +6 -0
- package/dist/v2/pages/DeleteEntity/index.d.ts +3 -0
- package/dist/v2/pages/DeleteEntity/index.d.ts.map +1 -0
- package/dist/v2/pages/Settings/SettingsPage.scss.js +1 -1
- package/dist/v2/pages/Settings/SettingsTabs.scss.js +1 -1
- package/dist/v2/pages/Settings/components/SidebarCustomisation.js +2 -0
- package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +1 -1
- package/dist/v2/pages/Settings/components/SidebarNavItem.js +2 -0
- package/dist/v2/pages/Settings/components/SidebarNavItem.scss.js +1 -1
- package/dist/v2/pages/SettingsSubPage/SettingsSubPage.d.ts +1 -0
- package/dist/v2/pages/SettingsSubPage/SettingsSubPage.d.ts.map +1 -1
- package/dist/v2/pages/SettingsSubPage/SettingsSubPage.js +2 -2
- package/dist/v2/pages/SettingsSubPage/SettingsSubPage.scss.js +1 -1
- package/dist/v2/pages/auth/AuthLayout/AuthLayout.scss.js +1 -1
- package/dist/v2/shadcn/components/ui/switch.scss.js +1 -1
- package/dist/v2/styles/form/NewInput.scss.js +1 -1
- package/dist/v2/styles/tokens/_colors.scss +19 -0
- package/dist/v2/utils/colourPicker/colors.d.ts +8 -0
- package/dist/v2/utils/colourPicker/colors.d.ts.map +1 -0
- package/dist/v2/utils/timeFormat/formatTime.d.ts +14 -0
- package/dist/v2/utils/timeFormat/formatTime.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/index.ts +1 -0
- package/src/v2/components/Badge/Badge.scss +1 -2
- package/src/v2/components/Checkbox/Checkbox.scss +37 -57
- package/src/v2/components/Checkbox/Checkbox.tsx +6 -44
- package/src/v2/components/ColorPicker/ColorPicker.scss +96 -0
- package/src/v2/components/ColorPicker/ColorPicker.stories.tsx +68 -0
- package/src/v2/components/ColorPicker/ColorPicker.tsx +49 -0
- package/src/v2/components/ColorPicker/index.ts +1 -0
- package/src/v2/components/FeatureCard/FeatureCard.scss +65 -0
- package/src/v2/components/FeatureCard/FeatureCard.stories.tsx +42 -0
- package/src/v2/components/FeatureCard/FeatureCard.tsx +37 -0
- package/src/v2/components/FeatureCard/index.ts +2 -0
- package/src/v2/components/IconButton/IconButton.scss +1 -1
- package/src/v2/components/IconButton/IconButton.tsx +41 -2
- package/src/v2/components/PeriodCard/PeriodCard.tsx +76 -13
- package/src/v2/components/index.ts +6 -0
- package/src/v2/icons/index.tsx +29 -4
- package/src/v2/pages/DeleteEntity/DeleteEntityPage.scss +96 -0
- package/src/v2/pages/DeleteEntity/DeleteEntityPage.stories.tsx +83 -0
- package/src/v2/pages/DeleteEntity/DeleteEntityPage.tsx +120 -0
- package/src/v2/pages/DeleteEntity/index.ts +2 -0
- package/src/v2/pages/SettingsSubPage/SettingsSubPage.scss +4 -4
- package/src/v2/pages/SettingsSubPage/SettingsSubPage.tsx +3 -1
- package/src/v2/styles/tokens/_colors.scss +19 -0
- package/src/v2/utils/colourPicker/colors.ts +17 -0
- package/src/v2/utils/timeFormat/formatTime.ts +18 -0
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
width: 0;
|
|
29
29
|
|
|
30
30
|
&:checked ~ .checkbox__toggle {
|
|
31
|
-
background: var(--fill-selected,
|
|
32
|
-
border:
|
|
31
|
+
background: var(--fill-selected, var(--neutral-500));
|
|
32
|
+
border: none;
|
|
33
33
|
|
|
34
|
-
.
|
|
34
|
+
.checkbox__unchecked-group {
|
|
35
35
|
opacity: 0;
|
|
36
36
|
visibility: hidden;
|
|
37
37
|
}
|
|
@@ -43,29 +43,25 @@
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
&:focus ~ .checkbox__toggle {
|
|
46
|
-
|
|
46
|
+
outline: none;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
&:disabled ~ .checkbox__toggle {
|
|
50
|
-
background-color: var(--surface-status-disabled,
|
|
51
|
-
border-color: var(--border-primary,
|
|
50
|
+
background-color: var(--surface-status-disabled, var(--neutral-25));
|
|
51
|
+
border-color: var(--border-primary, var(--neutral-50));
|
|
52
52
|
cursor: not-allowed;
|
|
53
53
|
opacity: 0.6;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
// Only show X
|
|
57
|
+
// Only show Unchecked group (X) when not pristine and not checked
|
|
58
58
|
&:not(&--pristine) &__input:not(:checked) ~ &__toggle {
|
|
59
|
-
|
|
59
|
+
background: var(--grey-500); // Match image track color
|
|
60
|
+
border: none;
|
|
61
|
+
|
|
62
|
+
.checkbox__unchecked-group {
|
|
60
63
|
opacity: 1;
|
|
61
64
|
visibility: visible;
|
|
62
|
-
top: 50%;
|
|
63
|
-
position: absolute;
|
|
64
|
-
right: 4px;
|
|
65
|
-
transform: translateY(-50%);
|
|
66
|
-
display: flex;
|
|
67
|
-
align-items: center;
|
|
68
|
-
justify-content: center;
|
|
69
65
|
}
|
|
70
66
|
|
|
71
67
|
.checkbox__checked-group {
|
|
@@ -78,30 +74,18 @@
|
|
|
78
74
|
position: relative;
|
|
79
75
|
display: flex;
|
|
80
76
|
align-items: center;
|
|
81
|
-
justify-content: flex-end; // Positions X mark to the right
|
|
82
77
|
width: 58px;
|
|
83
|
-
height: 34px;
|
|
78
|
+
height: 34px;
|
|
84
79
|
min-width: 58px;
|
|
85
80
|
padding: 4px;
|
|
86
|
-
background: var(--surface-secondary,
|
|
87
|
-
border:
|
|
81
|
+
background: var(--surface-secondary, var(--neutral-25));
|
|
82
|
+
border: none;
|
|
88
83
|
border-radius: var(--padding-xl, 32px);
|
|
89
84
|
flex-shrink: 0;
|
|
85
|
+
transition: background-color 0.2s ease;
|
|
90
86
|
}
|
|
91
87
|
|
|
92
|
-
&
|
|
93
|
-
width: 24px;
|
|
94
|
-
height: 24px;
|
|
95
|
-
opacity: 0; // Hidden by default (blank state)
|
|
96
|
-
visibility: hidden;
|
|
97
|
-
|
|
98
|
-
svg {
|
|
99
|
-
width: 100%;
|
|
100
|
-
height: 100%;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
&__checked-group {
|
|
88
|
+
&__unchecked-group {
|
|
105
89
|
position: absolute;
|
|
106
90
|
left: 4px;
|
|
107
91
|
top: 50%;
|
|
@@ -113,37 +97,33 @@
|
|
|
113
97
|
display: flex;
|
|
114
98
|
align-items: center;
|
|
115
99
|
justify-content: center;
|
|
100
|
+
background: white;
|
|
101
|
+
border-radius: 50%;
|
|
116
102
|
}
|
|
117
103
|
|
|
118
|
-
&
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
height: 24px;
|
|
122
|
-
display: flex;
|
|
123
|
-
align-items: center;
|
|
124
|
-
justify-content: center;
|
|
125
|
-
|
|
126
|
-
svg {
|
|
127
|
-
width: 100%;
|
|
128
|
-
height: 100%;
|
|
129
|
-
}
|
|
104
|
+
&__icon-cross {
|
|
105
|
+
fill: var(--grey-500);
|
|
106
|
+
opacity: 0.5;
|
|
130
107
|
}
|
|
131
108
|
|
|
132
|
-
&
|
|
109
|
+
&__checked-group {
|
|
133
110
|
position: absolute;
|
|
111
|
+
right: 4px; // Checked position on the right
|
|
134
112
|
top: 50%;
|
|
135
|
-
|
|
136
|
-
transform: translate(-50%, -50%);
|
|
113
|
+
transform: translateY(-50%);
|
|
137
114
|
width: 24px;
|
|
138
115
|
height: 24px;
|
|
116
|
+
opacity: 0;
|
|
117
|
+
visibility: hidden;
|
|
139
118
|
display: flex;
|
|
140
119
|
align-items: center;
|
|
141
120
|
justify-content: center;
|
|
121
|
+
background: white;
|
|
122
|
+
border-radius: 50%;
|
|
123
|
+
}
|
|
142
124
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
height: 100%;
|
|
146
|
-
}
|
|
125
|
+
&__icon-tick {
|
|
126
|
+
fill: var(--neutral-500);
|
|
147
127
|
}
|
|
148
128
|
|
|
149
129
|
&__content {
|
|
@@ -177,19 +157,19 @@
|
|
|
177
157
|
font-family: var(--font-family-sans, 'Geist', sans-serif), serif;
|
|
178
158
|
font-size: var(--text-xs-size, 11px);
|
|
179
159
|
line-height: var(--text-xs-line, 14px);
|
|
180
|
-
color: var(--label-status-error,
|
|
160
|
+
color: var(--label-status-error, var(--red-500));
|
|
181
161
|
margin-left: 69px;
|
|
182
162
|
}
|
|
183
163
|
|
|
184
164
|
&__wrapper:hover &__input:not(:disabled) ~ &__toggle {
|
|
185
|
-
border-color: var(--border-primary-hover, #d1d3de);
|
|
165
|
+
// border-color: var(--border-primary-hover, #d1d3de);
|
|
186
166
|
}
|
|
187
167
|
|
|
188
168
|
&--pristine {
|
|
189
169
|
.checkbox__toggle {
|
|
190
|
-
background: var(--surface-secondary,
|
|
170
|
+
background: var(--surface-secondary, var(--neutral-25));
|
|
191
171
|
}
|
|
192
|
-
.
|
|
172
|
+
.checkbox__unchecked-group,
|
|
193
173
|
.checkbox__checked-group {
|
|
194
174
|
opacity: 0 !important;
|
|
195
175
|
visibility: hidden !important;
|
|
@@ -205,7 +185,7 @@
|
|
|
205
185
|
align-items: center;
|
|
206
186
|
gap: 8px;
|
|
207
187
|
border-radius: var(--padding-xl, 32px);
|
|
208
|
-
border: 1px solid var(--border-primary,
|
|
209
|
-
background: var(--surface-primary,
|
|
188
|
+
border: 1px solid var(--border-primary, var(--neutral-50));
|
|
189
|
+
background: var(--surface-primary, var(--neutral-white));
|
|
210
190
|
}
|
|
211
191
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { InputHTMLAttributes, forwardRef } from 'react'
|
|
2
|
+
import { IconTick, IconCross } from '../../icons'
|
|
2
3
|
import './Checkbox.scss'
|
|
3
4
|
|
|
4
5
|
export interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {
|
|
@@ -41,53 +42,14 @@ export const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(
|
|
|
41
42
|
{...props}
|
|
42
43
|
/>
|
|
43
44
|
<span className="checkbox__toggle">
|
|
44
|
-
{/* X mark - visible when unchecked, positioned to the
|
|
45
|
-
<span className="
|
|
46
|
-
<
|
|
47
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
48
|
-
width="24"
|
|
49
|
-
height="24"
|
|
50
|
-
viewBox="0 0 24 24"
|
|
51
|
-
fill="none"
|
|
52
|
-
>
|
|
53
|
-
<path
|
|
54
|
-
d="M0 12C0 5.37258 5.37258 0 12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12Z"
|
|
55
|
-
fill="#14215A"
|
|
56
|
-
/>
|
|
57
|
-
<path
|
|
58
|
-
d="M18.1426 8.59961L14.0762 12.375L18.1426 16.1504L16.1006 18.3496L11.8711 14.4219L7.64258 18.3496L5.60059 16.1504L9.66602 12.375L5.60059 8.59961L7.64258 6.40039L11.8711 10.3271L16.1006 6.40039L18.1426 8.59961Z"
|
|
59
|
-
fill="white"
|
|
60
|
-
/>
|
|
61
|
-
</svg>
|
|
45
|
+
{/* White circle + X mark - visible when unchecked, positioned to the left */}
|
|
46
|
+
<span className="checkbox__unchecked-group">
|
|
47
|
+
<IconCross size={16} className="checkbox__icon-cross" />
|
|
62
48
|
</span>
|
|
63
49
|
|
|
64
|
-
{/* White circle + Checkmark - visible when checked, positioned to the
|
|
50
|
+
{/* White circle + Checkmark - visible when checked, positioned to the right */}
|
|
65
51
|
<span className="checkbox__checked-group">
|
|
66
|
-
<
|
|
67
|
-
<svg
|
|
68
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
69
|
-
width="24"
|
|
70
|
-
height="24"
|
|
71
|
-
viewBox="0 0 24 24"
|
|
72
|
-
fill="none"
|
|
73
|
-
>
|
|
74
|
-
<circle cx="12" cy="12" r="12" fill="white" />
|
|
75
|
-
</svg>
|
|
76
|
-
</span>
|
|
77
|
-
<span className="checkbox__checkmark">
|
|
78
|
-
<svg
|
|
79
|
-
xmlns="http://www.w3.org/2000/svg"
|
|
80
|
-
width="24"
|
|
81
|
-
height="24"
|
|
82
|
-
viewBox="0 0 24 24"
|
|
83
|
-
fill="none"
|
|
84
|
-
>
|
|
85
|
-
<path
|
|
86
|
-
d="M19.1272 8.67725L10.8545 18.1013L5.71509 13.2058L7.78491 11.0334L10.6611 13.7734L16.8728 6.69824L19.1272 8.67725Z"
|
|
87
|
-
fill="#14215A"
|
|
88
|
-
/>
|
|
89
|
-
</svg>
|
|
90
|
-
</span>
|
|
52
|
+
<IconTick size={16} className="checkbox__icon-tick" />
|
|
91
53
|
</span>
|
|
92
54
|
</span>
|
|
93
55
|
{(label || description) && (
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
.color-picker-grid {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-wrap: wrap;
|
|
4
|
+
column-gap: 20px;
|
|
5
|
+
row-gap: 32px;
|
|
6
|
+
margin-top: 16px;
|
|
7
|
+
width: 100%;
|
|
8
|
+
border-radius: 8px;
|
|
9
|
+
border: 1px solid transparent;
|
|
10
|
+
transition: all 0.2s;
|
|
11
|
+
|
|
12
|
+
&--error {
|
|
13
|
+
border-color: #E0423A;
|
|
14
|
+
background-color: rgba(224, 66, 58, 0.05);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media (max-width: 480px) {
|
|
18
|
+
column-gap: 0;
|
|
19
|
+
row-gap: 16px;
|
|
20
|
+
justify-content: flex-start;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.color-picker-button {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: column;
|
|
27
|
+
align-items: center;
|
|
28
|
+
gap: 6px; // 1.5 * 4 = 6px
|
|
29
|
+
padding: 8px; // 2 * 4 = 8px
|
|
30
|
+
border-radius: 8px;
|
|
31
|
+
transition: background-color 0.2s;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
min-width: 72px;
|
|
34
|
+
background: transparent;
|
|
35
|
+
border: none;
|
|
36
|
+
outline: none;
|
|
37
|
+
|
|
38
|
+
@media (max-width: 480px) {
|
|
39
|
+
min-width: unset;
|
|
40
|
+
width: 25%;
|
|
41
|
+
padding: 4px;
|
|
42
|
+
|
|
43
|
+
.color-picker-outer-circle {
|
|
44
|
+
width: 48px;
|
|
45
|
+
height: 48px;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.color-picker-inner-circle {
|
|
49
|
+
width: 32px;
|
|
50
|
+
height: 32px;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.color-picker-name {
|
|
54
|
+
font-size: 10px;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&:hover {
|
|
59
|
+
background-color: var(--surface-primary-hover);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.color-picker-outer-circle {
|
|
64
|
+
position: relative;
|
|
65
|
+
width: 54px;
|
|
66
|
+
height: 54px;
|
|
67
|
+
border-radius: 50%;
|
|
68
|
+
display: flex;
|
|
69
|
+
align-items: center;
|
|
70
|
+
justify-content: center;
|
|
71
|
+
border: 1px solid var(--border-primary);
|
|
72
|
+
transition: border-color 0.2s;
|
|
73
|
+
|
|
74
|
+
&:hover {
|
|
75
|
+
border-color: var(--label-secondary);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
&--selected {
|
|
79
|
+
border-width: 2px;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.color-picker-inner-circle {
|
|
84
|
+
width: 38px;
|
|
85
|
+
height: 38px;
|
|
86
|
+
border-radius: 50%;
|
|
87
|
+
transition: all 0.2s ease-out;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.color-picker-name {
|
|
91
|
+
font-size: 12px; // text-xs
|
|
92
|
+
font-weight: 500; // font-medium
|
|
93
|
+
color: var(--label-secondary);
|
|
94
|
+
line-height: 1.25; // leading-tight
|
|
95
|
+
text-transform: capitalize;
|
|
96
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { ColorPicker } from './ColorPicker'
|
|
3
|
+
import * as React from 'react'
|
|
4
|
+
import { useState } from 'react'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof ColorPicker> = {
|
|
7
|
+
title: 'V2/Components/ColorPicker',
|
|
8
|
+
component: ColorPicker,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
11
|
+
},
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default meta
|
|
16
|
+
type Story = StoryObj<typeof ColorPicker>
|
|
17
|
+
|
|
18
|
+
const MOCK_COLORS = [
|
|
19
|
+
{ name: 'Red', hex: '#EF4444' },
|
|
20
|
+
{ name: 'Orange', hex: '#F97316' },
|
|
21
|
+
{ name: 'Amber', hex: '#F59E0B' },
|
|
22
|
+
{ name: 'Yellow', hex: '#EAB308' },
|
|
23
|
+
{ name: 'Lime', hex: '#84CC16' },
|
|
24
|
+
{ name: 'Green', hex: '#22C55E' },
|
|
25
|
+
{ name: 'Emerald', hex: '#10B981' },
|
|
26
|
+
{ name: 'Teal', hex: '#14B8A6' },
|
|
27
|
+
{ name: 'Cyan', hex: '#06B6D4' },
|
|
28
|
+
{ name: 'Sky', hex: '#0EA5E9' },
|
|
29
|
+
{ name: 'Blue', hex: '#3B82F6' },
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
export const Default: Story = {
|
|
33
|
+
args: {
|
|
34
|
+
colors: MOCK_COLORS,
|
|
35
|
+
selectedColor: '#EF4444',
|
|
36
|
+
onChange: (hex: string) => console.log('Selected color:', hex),
|
|
37
|
+
t: (key: string) => key,
|
|
38
|
+
},
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const Controlled: Story = {
|
|
42
|
+
render: (args) => {
|
|
43
|
+
const ControlledExample = () => {
|
|
44
|
+
const [selected, setSelected] = useState('#3B82F6')
|
|
45
|
+
return (
|
|
46
|
+
<ColorPicker
|
|
47
|
+
{...args}
|
|
48
|
+
selectedColor={selected}
|
|
49
|
+
onChange={setSelected}
|
|
50
|
+
t={(key: string) => key}
|
|
51
|
+
/>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
return <ControlledExample />
|
|
55
|
+
},
|
|
56
|
+
args: {
|
|
57
|
+
colors: MOCK_COLORS,
|
|
58
|
+
},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const NoSelection: Story = {
|
|
62
|
+
args: {
|
|
63
|
+
colors: MOCK_COLORS,
|
|
64
|
+
selectedColor: '',
|
|
65
|
+
onChange: (hex: string) => console.log('Selected color:', hex),
|
|
66
|
+
t: (key: string) => key,
|
|
67
|
+
},
|
|
68
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import './ColorPicker.scss'
|
|
3
|
+
|
|
4
|
+
export interface ColorOption {
|
|
5
|
+
name: string
|
|
6
|
+
hex: string
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface ColorPickerProps {
|
|
10
|
+
colors: ColorOption[]
|
|
11
|
+
selectedColor?: string
|
|
12
|
+
onChange: (hex: string) => void
|
|
13
|
+
t: (key: string) => string
|
|
14
|
+
error?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const ColorPicker: React.FC<ColorPickerProps> = ({
|
|
18
|
+
colors,
|
|
19
|
+
selectedColor,
|
|
20
|
+
onChange,
|
|
21
|
+
t,
|
|
22
|
+
error,
|
|
23
|
+
}) => {
|
|
24
|
+
return (
|
|
25
|
+
<div className={`color-picker-grid ${error ? 'color-picker-grid--error' : ''}`}>
|
|
26
|
+
{colors.map((color) => (
|
|
27
|
+
<button
|
|
28
|
+
key={color.name}
|
|
29
|
+
type="button"
|
|
30
|
+
className="color-picker-button"
|
|
31
|
+
onClick={() => onChange(color.hex)}
|
|
32
|
+
>
|
|
33
|
+
<div
|
|
34
|
+
className={`color-picker-outer-circle ${
|
|
35
|
+
selectedColor === color.hex ? 'color-picker-outer-circle--selected' : ''
|
|
36
|
+
}`}
|
|
37
|
+
style={selectedColor === color.hex ? { borderColor: color.hex, borderWidth: '2px' } : {}}
|
|
38
|
+
>
|
|
39
|
+
<div
|
|
40
|
+
className="color-picker-inner-circle"
|
|
41
|
+
style={{ backgroundColor: color.hex }}
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
<span className="color-picker-name">{t(color.name)}</span>
|
|
45
|
+
</button>
|
|
46
|
+
))}
|
|
47
|
+
</div>
|
|
48
|
+
)
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './ColorPicker'
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
@import '../../styles/tokens/colors';
|
|
2
|
+
@import '../../styles/tokens/sizes';
|
|
3
|
+
|
|
4
|
+
.feature-card {
|
|
5
|
+
font-family: var(--font-family-sans, 'Geist', sans-serif), serif;
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
justify-content: space-between;
|
|
9
|
+
gap: 20px;
|
|
10
|
+
padding: 12px;
|
|
11
|
+
background-color: var(--surface-secondary);
|
|
12
|
+
border: 1px solid var(--border-primary);
|
|
13
|
+
border-radius: 12px;
|
|
14
|
+
|
|
15
|
+
@media (min-width: 640px) {
|
|
16
|
+
flex-direction: row;
|
|
17
|
+
align-items: center;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&__content {
|
|
21
|
+
display: flex;
|
|
22
|
+
align-items: center;
|
|
23
|
+
gap: 20px;
|
|
24
|
+
flex: 1;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&__icon-wrapper {
|
|
28
|
+
display: flex;
|
|
29
|
+
align-items: center;
|
|
30
|
+
justify-content: center;
|
|
31
|
+
flex-shrink: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
&__text {
|
|
35
|
+
display: flex;
|
|
36
|
+
flex-direction: column;
|
|
37
|
+
flex: 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
&__title {
|
|
41
|
+
font-size: 16px;
|
|
42
|
+
line-height: 24px;
|
|
43
|
+
font-weight: 500;
|
|
44
|
+
color: var(--label-primary);
|
|
45
|
+
margin: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&__description {
|
|
49
|
+
font-size: 14px;
|
|
50
|
+
line-height: 20px;
|
|
51
|
+
color: var(--label-primary);
|
|
52
|
+
opacity: 0.8;
|
|
53
|
+
margin: 4px 0 0;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&__action {
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
width: 100%;
|
|
60
|
+
|
|
61
|
+
@media (min-width: 640px) {
|
|
62
|
+
width: auto;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import { FeatureCard } from './FeatureCard'
|
|
3
|
+
import { AnalyticsIcon } from '../../icons'
|
|
4
|
+
import * as React from 'react'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof FeatureCard> = {
|
|
7
|
+
title: 'V2/Components/FeatureCard',
|
|
8
|
+
component: FeatureCard,
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: 'centered',
|
|
11
|
+
},
|
|
12
|
+
tags: ['autodocs'],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default meta
|
|
16
|
+
type Story = StoryObj<typeof FeatureCard>
|
|
17
|
+
|
|
18
|
+
export const Default: Story = {
|
|
19
|
+
args: {
|
|
20
|
+
icon: <AnalyticsIcon />,
|
|
21
|
+
title: 'Dynamic Pricing',
|
|
22
|
+
description: 'When enabled, you will be able to set different prices for different times of the day.',
|
|
23
|
+
},
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const WithAction: Story = {
|
|
27
|
+
args: {
|
|
28
|
+
icon: <AnalyticsIcon />,
|
|
29
|
+
title: 'Variable Pricing',
|
|
30
|
+
description: 'Set different prices for different days of the week or periods.',
|
|
31
|
+
action: <div style={{ width: '40px', height: '24px', background: '#ccc', borderRadius: '12px' }} />,
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const CustomClassName: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
icon: <AnalyticsIcon />,
|
|
38
|
+
title: 'Custom Styled Card',
|
|
39
|
+
description: 'This card has a custom CSS class applied to it.',
|
|
40
|
+
className: 'custom-feature-card',
|
|
41
|
+
},
|
|
42
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
import './FeatureCard.scss'
|
|
3
|
+
|
|
4
|
+
export interface FeatureCardProps {
|
|
5
|
+
icon: React.ReactNode
|
|
6
|
+
title: string
|
|
7
|
+
description: string
|
|
8
|
+
action?: React.ReactNode
|
|
9
|
+
className?: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const FeatureCard: React.FC<FeatureCardProps> = ({
|
|
13
|
+
icon,
|
|
14
|
+
title,
|
|
15
|
+
description,
|
|
16
|
+
action,
|
|
17
|
+
className = '',
|
|
18
|
+
}) => {
|
|
19
|
+
return (
|
|
20
|
+
<div className={`feature-card ${className}`}>
|
|
21
|
+
<div className="feature-card__content">
|
|
22
|
+
<div className="feature-card__icon-wrapper">
|
|
23
|
+
{icon}
|
|
24
|
+
</div>
|
|
25
|
+
<div className="feature-card__text">
|
|
26
|
+
<h3 className="feature-card__title">{title}</h3>
|
|
27
|
+
<p className="feature-card__description">{description}</p>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
{action && (
|
|
31
|
+
<div className="feature-card__action">
|
|
32
|
+
{action}
|
|
33
|
+
</div>
|
|
34
|
+
)}
|
|
35
|
+
</div>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
@@ -6,12 +6,20 @@ export interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>
|
|
|
6
6
|
label?: string
|
|
7
7
|
icon?: 'back' | 'add' | 'delete' | ReactNode
|
|
8
8
|
variant?: 'default' | 'danger'
|
|
9
|
+
backgroundColor?: string
|
|
10
|
+
borderColor?: string
|
|
11
|
+
hoverBackgroundColor?: string
|
|
12
|
+
hoverBorderColor?: string
|
|
9
13
|
}
|
|
10
14
|
|
|
11
15
|
export function IconButton({
|
|
12
16
|
label,
|
|
13
17
|
icon = 'back',
|
|
14
18
|
variant = 'default',
|
|
19
|
+
backgroundColor,
|
|
20
|
+
borderColor,
|
|
21
|
+
hoverBackgroundColor,
|
|
22
|
+
hoverBorderColor,
|
|
15
23
|
className = '',
|
|
16
24
|
...props
|
|
17
25
|
}: IconButtonProps) {
|
|
@@ -22,6 +30,24 @@ export function IconButton({
|
|
|
22
30
|
className,
|
|
23
31
|
].filter(Boolean).join(' ')
|
|
24
32
|
|
|
33
|
+
const style: any = {
|
|
34
|
+
...(backgroundColor ? { backgroundColor } : {}),
|
|
35
|
+
...(borderColor ? { borderColor } : {}),
|
|
36
|
+
...(props.style || {}),
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const handleMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
40
|
+
if (hoverBackgroundColor) e.currentTarget.style.backgroundColor = hoverBackgroundColor
|
|
41
|
+
if (hoverBorderColor) e.currentTarget.style.borderColor = hoverBorderColor
|
|
42
|
+
if (props.onMouseEnter) props.onMouseEnter(e)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const handleMouseLeave = (e: React.MouseEvent<HTMLButtonElement>) => {
|
|
46
|
+
e.currentTarget.style.backgroundColor = backgroundColor || ''
|
|
47
|
+
e.currentTarget.style.borderColor = borderColor || ''
|
|
48
|
+
if (props.onMouseLeave) props.onMouseLeave(e)
|
|
49
|
+
}
|
|
50
|
+
|
|
25
51
|
const iconSize = isIconOnly ? 32 : 16
|
|
26
52
|
|
|
27
53
|
const renderIcon = () => {
|
|
@@ -33,14 +59,27 @@ export function IconButton({
|
|
|
33
59
|
|
|
34
60
|
if (isIconOnly) {
|
|
35
61
|
return (
|
|
36
|
-
<button
|
|
62
|
+
<button
|
|
63
|
+
type="button"
|
|
64
|
+
className={classes}
|
|
65
|
+
style={style}
|
|
66
|
+
onMouseEnter={handleMouseEnter}
|
|
67
|
+
onMouseLeave={handleMouseLeave}
|
|
68
|
+
{...props}
|
|
69
|
+
>
|
|
37
70
|
{renderIcon()}
|
|
38
71
|
</button>
|
|
39
72
|
)
|
|
40
73
|
}
|
|
41
74
|
|
|
42
75
|
return (
|
|
43
|
-
<button
|
|
76
|
+
<button
|
|
77
|
+
className={classes}
|
|
78
|
+
style={style}
|
|
79
|
+
onMouseEnter={handleMouseEnter}
|
|
80
|
+
onMouseLeave={handleMouseLeave}
|
|
81
|
+
{...props}
|
|
82
|
+
>
|
|
44
83
|
<span className="icon-button__icon">
|
|
45
84
|
{renderIcon()}
|
|
46
85
|
</span>
|