@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.
Files changed (116) hide show
  1. package/dist/Maintenance/Maintenance.scss.js +1 -1
  2. package/dist/index.d.ts +1 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +3 -0
  5. package/dist/v2/components/AccountManagerCard/AccountManagerCard.scss.js +1 -1
  6. package/dist/v2/components/ActionMenu/ActionMenu.scss.js +1 -1
  7. package/dist/v2/components/Alert/Alert.scss.js +1 -1
  8. package/dist/v2/components/AvatarUpload/AvatarUpload.scss.js +1 -1
  9. package/dist/v2/components/Badge/Badge.scss.js +1 -1
  10. package/dist/v2/components/Button/Button.scss.js +1 -1
  11. package/dist/v2/components/Button/GhostButton.scss.js +1 -1
  12. package/dist/v2/components/Checkbox/Checkbox.d.ts.map +1 -1
  13. package/dist/v2/components/Checkbox/Checkbox.js +10 -50
  14. package/dist/v2/components/Checkbox/Checkbox.scss.js +1 -1
  15. package/dist/v2/components/ColorPicker/ColorPicker.d.ts +15 -0
  16. package/dist/v2/components/ColorPicker/ColorPicker.d.ts.map +1 -0
  17. package/dist/v2/components/ColorPicker/ColorPicker.js +40 -0
  18. package/dist/v2/components/ColorPicker/ColorPicker.scss.js +6 -0
  19. package/dist/v2/components/ColorPicker/index.d.ts +2 -0
  20. package/dist/v2/components/ColorPicker/index.d.ts.map +1 -0
  21. package/dist/v2/components/DataTable/DataTable.scss.js +1 -1
  22. package/dist/v2/components/EmptyState/EmptyState.scss.js +1 -1
  23. package/dist/v2/components/FeatureCard/FeatureCard.d.ts +11 -0
  24. package/dist/v2/components/FeatureCard/FeatureCard.d.ts.map +1 -0
  25. package/dist/v2/components/FeatureCard/FeatureCard.js +40 -0
  26. package/dist/v2/components/FeatureCard/FeatureCard.scss.js +6 -0
  27. package/dist/v2/components/FeatureCard/index.d.ts +3 -0
  28. package/dist/v2/components/FeatureCard/index.d.ts.map +1 -0
  29. package/dist/v2/components/FeatureToggle/FeatureToggle.scss.js +1 -1
  30. package/dist/v2/components/FormField/FormField.scss.js +1 -1
  31. package/dist/v2/components/IconButton/IconButton.d.ts +5 -1
  32. package/dist/v2/components/IconButton/IconButton.d.ts.map +1 -1
  33. package/dist/v2/components/IconButton/IconButton.js +28 -3
  34. package/dist/v2/components/IconButton/IconButton.scss.js +1 -1
  35. package/dist/v2/components/InfoGrid/InfoGrid.scss.js +1 -1
  36. package/dist/v2/components/Modal/DeleteModal.scss.js +1 -1
  37. package/dist/v2/components/NPSScore/NPSScore.scss.js +1 -1
  38. package/dist/v2/components/NewTabs/NewTabs.scss.js +1 -1
  39. package/dist/v2/components/NotificationBanner/NotificationBanner.scss.js +1 -1
  40. package/dist/v2/components/PeriodCard/PeriodCard.d.ts +18 -4
  41. package/dist/v2/components/PeriodCard/PeriodCard.d.ts.map +1 -1
  42. package/dist/v2/components/PeriodCard/PeriodCard.js +46 -6
  43. package/dist/v2/components/Select/Select.scss.js +1 -1
  44. package/dist/v2/components/StatusBadge/StatusBadge.scss.js +1 -1
  45. package/dist/v2/components/StepIndicator/StepIndicator.scss.js +1 -1
  46. package/dist/v2/components/TableControls/TableControls.scss.js +1 -1
  47. package/dist/v2/components/Tabs/Tabs.scss.js +1 -1
  48. package/dist/v2/components/Tooltip/Tooltip.scss.js +1 -1
  49. package/dist/v2/components/UserAvatar/UserAvatar.scss.js +1 -1
  50. package/dist/v2/components/UserPanel/UserPanel.scss.js +1 -1
  51. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +1 -1
  52. package/dist/v2/components/ZoneCard/ZoneCard.scss.js +1 -1
  53. package/dist/v2/components/index.d.ts +4 -0
  54. package/dist/v2/components/index.d.ts.map +1 -1
  55. package/dist/v2/dashboard-analytics/chart/Chart.scss.js +1 -1
  56. package/dist/v2/dashboard-analytics/metric-card/MetricCard.scss.js +1 -1
  57. package/dist/v2/dashboard-analytics/venue-card/VenueCard.scss.js +1 -1
  58. package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.scss.js +1 -1
  59. package/dist/v2/icons/index.d.ts +19 -2
  60. package/dist/v2/icons/index.d.ts.map +1 -1
  61. package/dist/v2/icons/index.js +21 -4
  62. package/dist/v2/navigation/DashboardLayout/AdminSidebar.scss.js +1 -1
  63. package/dist/v2/navigation/DashboardLayout/DashboardLayout.scss.js +1 -1
  64. package/dist/v2/navigation/DashboardLayout/ProviderSidebar.scss.js +1 -1
  65. package/dist/v2/navigation/DashboardLayout/TopNavigation.scss.js +1 -1
  66. package/dist/v2/pages/DeleteEntity/DeleteEntityPage.d.ts +29 -0
  67. package/dist/v2/pages/DeleteEntity/DeleteEntityPage.d.ts.map +1 -0
  68. package/dist/v2/pages/DeleteEntity/DeleteEntityPage.js +294 -0
  69. package/dist/v2/pages/DeleteEntity/DeleteEntityPage.scss.js +6 -0
  70. package/dist/v2/pages/DeleteEntity/index.d.ts +3 -0
  71. package/dist/v2/pages/DeleteEntity/index.d.ts.map +1 -0
  72. package/dist/v2/pages/Settings/SettingsPage.scss.js +1 -1
  73. package/dist/v2/pages/Settings/SettingsTabs.scss.js +1 -1
  74. package/dist/v2/pages/Settings/components/SidebarCustomisation.js +2 -0
  75. package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +1 -1
  76. package/dist/v2/pages/Settings/components/SidebarNavItem.js +2 -0
  77. package/dist/v2/pages/Settings/components/SidebarNavItem.scss.js +1 -1
  78. package/dist/v2/pages/SettingsSubPage/SettingsSubPage.d.ts +1 -0
  79. package/dist/v2/pages/SettingsSubPage/SettingsSubPage.d.ts.map +1 -1
  80. package/dist/v2/pages/SettingsSubPage/SettingsSubPage.js +2 -2
  81. package/dist/v2/pages/SettingsSubPage/SettingsSubPage.scss.js +1 -1
  82. package/dist/v2/pages/auth/AuthLayout/AuthLayout.scss.js +1 -1
  83. package/dist/v2/shadcn/components/ui/switch.scss.js +1 -1
  84. package/dist/v2/styles/form/NewInput.scss.js +1 -1
  85. package/dist/v2/styles/tokens/_colors.scss +19 -0
  86. package/dist/v2/utils/colourPicker/colors.d.ts +8 -0
  87. package/dist/v2/utils/colourPicker/colors.d.ts.map +1 -0
  88. package/dist/v2/utils/timeFormat/formatTime.d.ts +14 -0
  89. package/dist/v2/utils/timeFormat/formatTime.d.ts.map +1 -0
  90. package/package.json +3 -3
  91. package/src/index.ts +1 -0
  92. package/src/v2/components/Badge/Badge.scss +1 -2
  93. package/src/v2/components/Checkbox/Checkbox.scss +37 -57
  94. package/src/v2/components/Checkbox/Checkbox.tsx +6 -44
  95. package/src/v2/components/ColorPicker/ColorPicker.scss +96 -0
  96. package/src/v2/components/ColorPicker/ColorPicker.stories.tsx +68 -0
  97. package/src/v2/components/ColorPicker/ColorPicker.tsx +49 -0
  98. package/src/v2/components/ColorPicker/index.ts +1 -0
  99. package/src/v2/components/FeatureCard/FeatureCard.scss +65 -0
  100. package/src/v2/components/FeatureCard/FeatureCard.stories.tsx +42 -0
  101. package/src/v2/components/FeatureCard/FeatureCard.tsx +37 -0
  102. package/src/v2/components/FeatureCard/index.ts +2 -0
  103. package/src/v2/components/IconButton/IconButton.scss +1 -1
  104. package/src/v2/components/IconButton/IconButton.tsx +41 -2
  105. package/src/v2/components/PeriodCard/PeriodCard.tsx +76 -13
  106. package/src/v2/components/index.ts +6 -0
  107. package/src/v2/icons/index.tsx +29 -4
  108. package/src/v2/pages/DeleteEntity/DeleteEntityPage.scss +96 -0
  109. package/src/v2/pages/DeleteEntity/DeleteEntityPage.stories.tsx +83 -0
  110. package/src/v2/pages/DeleteEntity/DeleteEntityPage.tsx +120 -0
  111. package/src/v2/pages/DeleteEntity/index.ts +2 -0
  112. package/src/v2/pages/SettingsSubPage/SettingsSubPage.scss +4 -4
  113. package/src/v2/pages/SettingsSubPage/SettingsSubPage.tsx +3 -1
  114. package/src/v2/styles/tokens/_colors.scss +19 -0
  115. package/src/v2/utils/colourPicker/colors.ts +17 -0
  116. 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, #14215A);
32
- border: 1px solid var(--border-primary, #E8E9EF);
31
+ background: var(--fill-selected, var(--neutral-500));
32
+ border: none;
33
33
 
34
- .checkbox__xmark {
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
- box-shadow: 0 0 0 2px rgba(20, 33, 90, 0.2);
46
+ outline: none;
47
47
  }
48
48
 
49
49
  &:disabled ~ .checkbox__toggle {
50
- background-color: var(--surface-status-disabled, #f8f8fa);
51
- border-color: var(--border-primary, #e8e9ef);
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 mark when not pristine and not checked
57
+ // Only show Unchecked group (X) when not pristine and not checked
58
58
  &:not(&--pristine) &__input:not(:checked) ~ &__toggle {
59
- .checkbox__xmark {
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; // Set explicit height to help with vertical centering
78
+ height: 34px;
84
79
  min-width: 58px;
85
80
  padding: 4px;
86
- background: var(--surface-secondary, #F8F8FA);
87
- border: 1px solid var(--border-primary, #E8E9EF);
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
- &__xmark {
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
- &__circle {
119
- position: relative;
120
- width: 24px;
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
- &__checkmark {
109
+ &__checked-group {
133
110
  position: absolute;
111
+ right: 4px; // Checked position on the right
134
112
  top: 50%;
135
- left: 50%;
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
- svg {
144
- width: 100%;
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, #ef4444);
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, #F8F8FA);
170
+ background: var(--surface-secondary, var(--neutral-25));
191
171
  }
192
- .checkbox__xmark,
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, #E8E9EF);
209
- background: var(--surface-primary, #FFF);
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 right */}
45
- <span className="checkbox__xmark">
46
- <svg
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 left */}
50
+ {/* White circle + Checkmark - visible when checked, positioned to the right */}
65
51
  <span className="checkbox__checked-group">
66
- <span className="checkbox__circle">
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
+ }
@@ -0,0 +1,2 @@
1
+ export { FeatureCard } from './FeatureCard'
2
+ export type { FeatureCardProps } from './FeatureCard'
@@ -76,6 +76,6 @@
76
76
  color: var(--label-danger, #cc3c35);
77
77
 
78
78
  &:hover {
79
- background: var(--surface-primary, #fff);
79
+ background: var(--surface-danger-soft-hover, color-mix(in srgb, var(--surface-danger-soft) 85%, black));
80
80
  }
81
81
  }
@@ -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 type="button" className={classes} {...props}>
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 className={classes} {...props}>
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>