@licklist/design 0.78.32 → 0.78.34

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 (138) hide show
  1. package/dist/Maintenance/MaintenancePage.js +1 -0
  2. package/dist/index.js +8 -1
  3. package/dist/v2/components/ActionMenu/ActionMenu.d.ts +14 -0
  4. package/dist/v2/components/ActionMenu/ActionMenu.d.ts.map +1 -0
  5. package/dist/v2/components/ActionMenu/ActionMenu.js +159 -0
  6. package/dist/v2/components/ActionMenu/ActionMenu.scss.js +6 -0
  7. package/dist/v2/components/ActionMenu/index.d.ts +2 -0
  8. package/dist/v2/components/ActionMenu/index.d.ts.map +1 -0
  9. package/dist/v2/components/Alert/Alert.d.ts.map +1 -1
  10. package/dist/v2/components/Alert/Alert.js +48 -1
  11. package/dist/v2/components/Alert/Alert.scss.js +1 -1
  12. package/dist/v2/components/Badge/Badge.d.ts +10 -0
  13. package/dist/v2/components/Badge/Badge.d.ts.map +1 -0
  14. package/dist/v2/components/Badge/Badge.js +19 -0
  15. package/dist/v2/components/Badge/Badge.scss.js +6 -0
  16. package/dist/v2/components/Badge/index.d.ts +2 -0
  17. package/dist/v2/components/Badge/index.d.ts.map +1 -0
  18. package/dist/v2/components/Button/Button.d.ts +3 -2
  19. package/dist/v2/components/Button/Button.d.ts.map +1 -1
  20. package/dist/v2/components/Button/Button.js +13 -6
  21. package/dist/v2/components/Button/Button.scss.js +1 -1
  22. package/dist/v2/components/Button/GhostButton.scss.js +1 -1
  23. package/dist/v2/components/Button/index.d.ts +2 -0
  24. package/dist/v2/components/Button/index.d.ts.map +1 -1
  25. package/dist/v2/components/Checkbox/Checkbox.scss.js +1 -1
  26. package/dist/v2/components/FormField/FormField.d.ts.map +1 -1
  27. package/dist/v2/components/FormField/FormField.scss.js +1 -1
  28. package/dist/v2/components/Modal/DeleteModal.d.ts +15 -0
  29. package/dist/v2/components/Modal/DeleteModal.d.ts.map +1 -0
  30. package/dist/v2/components/Modal/DeleteModal.js +151 -0
  31. package/dist/v2/components/Modal/DeleteModal.scss.js +6 -0
  32. package/dist/v2/components/Modal/index.d.ts +3 -0
  33. package/dist/v2/components/Modal/index.d.ts.map +1 -0
  34. package/dist/v2/components/NPSScore/NPSScore.d.ts +3 -1
  35. package/dist/v2/components/NPSScore/NPSScore.d.ts.map +1 -1
  36. package/dist/v2/components/NPSScore/NPSScore.js +11 -27
  37. package/dist/v2/components/NPSScore/NPSScore.scss.js +1 -1
  38. package/dist/v2/components/NewInput/NewInput.d.ts +2 -0
  39. package/dist/v2/components/NewInput/NewInput.d.ts.map +1 -1
  40. package/dist/v2/components/NewInput/NewInput.js +37 -12
  41. package/dist/v2/components/NewPageHeader/NewPageHeader.d.ts +4 -1
  42. package/dist/v2/components/NewPageHeader/NewPageHeader.d.ts.map +1 -1
  43. package/dist/v2/components/NewPageHeader/NewPageHeader.js +18 -11
  44. package/dist/v2/components/NewPageHeader/NewPageHeader.scss.js +1 -1
  45. package/dist/v2/components/NewTable/NewTable.d.ts +21 -0
  46. package/dist/v2/components/NewTable/NewTable.d.ts.map +1 -0
  47. package/dist/v2/components/NewTable/NewTable.js +63 -0
  48. package/dist/v2/components/NewTable/NewTable.scss.js +6 -0
  49. package/dist/v2/components/NewTable/index.d.ts +2 -0
  50. package/dist/v2/components/NewTable/index.d.ts.map +1 -0
  51. package/dist/v2/components/Pagination/Pagination.d.ts +13 -0
  52. package/dist/v2/components/Pagination/Pagination.d.ts.map +1 -0
  53. package/dist/v2/components/Pagination/Pagination.js +76 -0
  54. package/dist/v2/components/Pagination/Pagination.scss.js +6 -0
  55. package/dist/v2/components/Pagination/index.d.ts +2 -0
  56. package/dist/v2/components/Pagination/index.d.ts.map +1 -0
  57. package/dist/v2/components/QuickFilter/QuickFilter.d.ts +14 -0
  58. package/dist/v2/components/QuickFilter/QuickFilter.d.ts.map +1 -0
  59. package/dist/v2/components/QuickFilter/QuickFilter.js +70 -0
  60. package/dist/v2/components/QuickFilter/QuickFilter.scss.js +6 -0
  61. package/dist/v2/components/QuickFilter/index.d.ts +2 -0
  62. package/dist/v2/components/QuickFilter/index.d.ts.map +1 -0
  63. package/dist/v2/components/SectionHeader/SectionHeader.d.ts.map +1 -1
  64. package/dist/v2/components/Select/Select.d.ts +7 -4
  65. package/dist/v2/components/Select/Select.d.ts.map +1 -1
  66. package/dist/v2/components/Select/Select.js +53 -24
  67. package/dist/v2/components/Select/Select.scss.js +1 -1
  68. package/dist/v2/components/TableSortIcon/TableSortIcon.d.ts +9 -0
  69. package/dist/v2/components/TableSortIcon/TableSortIcon.d.ts.map +1 -0
  70. package/dist/v2/components/TableSortIcon/TableSortIcon.js +14 -0
  71. package/dist/v2/components/TableSortIcon/index.d.ts +2 -0
  72. package/dist/v2/components/TableSortIcon/index.d.ts.map +1 -0
  73. package/dist/v2/components/WYSIWYGEditor/Icons.js +2 -2
  74. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +1 -1
  75. package/dist/v2/components/index.d.ts +17 -4
  76. package/dist/v2/components/index.d.ts.map +1 -1
  77. package/dist/v2/icons/index.d.ts +46 -0
  78. package/dist/v2/icons/index.d.ts.map +1 -1
  79. package/dist/v2/icons/index.js +358 -4
  80. package/dist/v2/navigation/DashboardLayout/ProviderSidebar.d.ts.map +1 -1
  81. package/dist/v2/navigation/DashboardLayout/ProviderSidebar.js +4 -8
  82. package/dist/v2/pages/Settings/SettingsPage.scss.js +1 -1
  83. package/dist/v2/pages/Settings/SettingsTabs.scss.js +1 -1
  84. package/dist/v2/pages/Settings/components/SidebarCustomisation.js +9 -3
  85. package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +1 -1
  86. package/dist/v2/pages/Settings/components/SidebarNavItem.js +9 -3
  87. package/dist/v2/pages/Settings/components/SidebarNavItem.scss.js +1 -1
  88. package/dist/v2/styles/form/NewInput.scss.js +1 -1
  89. package/package.json +3 -3
  90. package/src/v2/components/ActionMenu/ActionMenu.scss +106 -0
  91. package/src/v2/components/ActionMenu/ActionMenu.tsx +115 -0
  92. package/src/v2/components/ActionMenu/index.ts +1 -0
  93. package/src/v2/components/Alert/Alert.scss +8 -19
  94. package/src/v2/components/Alert/Alert.tsx +24 -1
  95. package/src/v2/components/Badge/Badge.scss +82 -0
  96. package/src/v2/components/Badge/Badge.tsx +25 -0
  97. package/src/v2/components/Badge/index.ts +1 -0
  98. package/src/v2/components/Button/Button.tsx +18 -4
  99. package/src/v2/components/Button/GhostButton.scss +11 -1
  100. package/src/v2/components/Button/index.ts +2 -0
  101. package/src/v2/components/Customer/CustomerDetail.scss +319 -0
  102. package/src/v2/components/Customer/CustomersList.scss +815 -0
  103. package/src/v2/components/FormField/FormField.tsx +19 -21
  104. package/src/v2/components/Modal/DeleteModal.scss +254 -0
  105. package/src/v2/components/Modal/DeleteModal.tsx +102 -0
  106. package/src/v2/components/Modal/index.ts +3 -0
  107. package/src/v2/components/NPSScore/NPSScore.scss +40 -59
  108. package/src/v2/components/NPSScore/NPSScore.tsx +15 -16
  109. package/src/v2/components/NewInput/NewInput.stories.tsx +3 -18
  110. package/src/v2/components/NewInput/NewInput.tsx +35 -12
  111. package/src/v2/components/NewPageHeader/NewPageHeader.scss +17 -8
  112. package/src/v2/components/NewPageHeader/NewPageHeader.tsx +17 -10
  113. package/src/v2/components/NewTable/NewTable.scss +126 -0
  114. package/src/v2/components/NewTable/NewTable.tsx +92 -0
  115. package/src/v2/components/NewTable/index.ts +1 -0
  116. package/src/v2/components/Pagination/Pagination.scss +142 -0
  117. package/src/v2/components/Pagination/Pagination.tsx +80 -0
  118. package/src/v2/components/Pagination/index.ts +1 -0
  119. package/src/v2/components/QuickFilter/QuickFilter.scss +67 -0
  120. package/src/v2/components/QuickFilter/QuickFilter.tsx +51 -0
  121. package/src/v2/components/QuickFilter/index.ts +1 -0
  122. package/src/v2/components/SectionHeader/SectionHeader.tsx +5 -7
  123. package/src/v2/components/Select/Select.scss +61 -24
  124. package/src/v2/components/Select/Select.stories.tsx +77 -1
  125. package/src/v2/components/Select/Select.tsx +63 -34
  126. package/src/v2/components/TableSortIcon/TableSortIcon.tsx +20 -0
  127. package/src/v2/components/TableSortIcon/index.ts +1 -0
  128. package/src/v2/components/WYSIWYGEditor/Icons.tsx +2 -2
  129. package/src/v2/components/index.ts +44 -5
  130. package/src/v2/icons/index.tsx +123 -3
  131. package/src/v2/navigation/DashboardLayout/ProviderSidebar.tsx +3 -1
  132. package/src/v2/navigation/config.tsx +1 -1
  133. package/src/v2/pages/Settings/components/SidebarCustomisation.tsx +1 -1
  134. package/src/v2/styles/common.scss +7 -0
  135. package/src/v2/styles/components/Button.scss +34 -2
  136. package/src/v2/styles/form/NewInput.scss +45 -21
  137. package/src/v2/styles/index.scss +1 -0
  138. package/src/v2/styles/tokens/_colors.scss +6 -0
@@ -0,0 +1,80 @@
1
+ import React from 'react'
2
+ import './Pagination.scss'
3
+ import { ArrowLeftIcon, ArrowRightIcon } from '../../icons'
4
+
5
+ export interface PaginationProps {
6
+ currentPage: number
7
+ totalPages: number
8
+ totalItems: number
9
+ itemsPerPage: number
10
+ onPageChange: (page: number) => void
11
+ t: (key: string, options?: any) => string
12
+ entityName?: string
13
+ }
14
+
15
+ export const Pagination: React.FC<PaginationProps> = ({
16
+ currentPage,
17
+ totalPages,
18
+ totalItems,
19
+ itemsPerPage,
20
+ onPageChange,
21
+ t,
22
+ entityName = 'items'
23
+ }) => {
24
+ const startItem = (currentPage - 1) * itemsPerPage + 1
25
+ const endItem = Math.min(currentPage * itemsPerPage, totalItems)
26
+ const isFirstPage = currentPage <= 1
27
+ const isLastPage = currentPage >= totalPages
28
+
29
+ const handlePrev = (e: React.MouseEvent<HTMLButtonElement>) => {
30
+ e.preventDefault()
31
+ if (!isFirstPage) {
32
+ onPageChange(currentPage - 1)
33
+ }
34
+ }
35
+
36
+ const handleNext = (e: React.MouseEvent<HTMLButtonElement>) => {
37
+ e.preventDefault()
38
+ if (!isLastPage) {
39
+ onPageChange(currentPage + 1)
40
+ }
41
+ }
42
+
43
+ return (
44
+ <div className="v2-pagination">
45
+ <div className="v2-pagination__controls">
46
+ <button
47
+ type="button"
48
+ className="v2-pagination__button"
49
+ onClick={handlePrev}
50
+ disabled={isFirstPage}
51
+ aria-label={t('App:previous', { defaultValue: 'Previous' })}
52
+ >
53
+ <ArrowLeftIcon />
54
+ </button>
55
+ <button
56
+ type="button"
57
+ className="v2-pagination__button"
58
+ onClick={handleNext}
59
+ disabled={isLastPage}
60
+ aria-label={t('App:next', { defaultValue: 'Next' })}
61
+ >
62
+ <ArrowRightIcon />
63
+ </button>
64
+ </div>
65
+ <div className="v2-pagination__info">
66
+ <div className="v2-pagination__page-number">
67
+ {t('App:page', { from: currentPage })}
68
+ </div>
69
+ <div className="v2-pagination__showing">
70
+ {t('App:paginationText', {
71
+ type: entityName,
72
+ from: startItem,
73
+ to: endItem,
74
+ total: totalItems
75
+ })}
76
+ </div>
77
+ </div>
78
+ </div>
79
+ )
80
+ }
@@ -0,0 +1 @@
1
+ export * from './Pagination'
@@ -0,0 +1,67 @@
1
+ .quick-filter {
2
+ display: flex;
3
+ align-items: center;
4
+ gap: 12px;
5
+
6
+ &__label {
7
+ font-size: var(--text-small-size, 13px);
8
+ font-weight: 500;
9
+ color: var(--label-secondary, #9399B3);
10
+ white-space: nowrap;
11
+ }
12
+
13
+ &__options {
14
+ display: flex;
15
+ flex-wrap: wrap;
16
+ gap: 8px;
17
+
18
+ .ghost-button {
19
+ border-radius: 100px;
20
+ }
21
+ }
22
+ }
23
+
24
+ // Mobile styles
25
+ @media (max-width: 768px) {
26
+ .quick-filter {
27
+ display: flex;
28
+ flex-direction: row;
29
+ align-items: flex-start;
30
+ gap: 12px;
31
+ width: 100%;
32
+
33
+ &__label {
34
+ font-size: 12px;
35
+ }
36
+
37
+ &__options {
38
+ flex: 1;
39
+ display: flex;
40
+ flex-wrap: wrap;
41
+ gap: 6px;
42
+ padding: 0;
43
+ margin: 0;
44
+ min-width: 0;
45
+
46
+ .ghost-button {
47
+ flex-shrink: 0;
48
+ border-radius: 100px;
49
+ }
50
+ }
51
+ }
52
+ }
53
+
54
+ @media (max-width: 480px) {
55
+ .quick-filter {
56
+ gap: 8px;
57
+
58
+ &__label {
59
+ font-size: 11px;
60
+ }
61
+
62
+ &__options {
63
+ gap: 4px;
64
+ }
65
+ }
66
+ }
67
+
@@ -0,0 +1,51 @@
1
+ import React from 'react'
2
+ import { GhostButton } from '../Button'
3
+ import './QuickFilter.scss'
4
+
5
+ export interface QuickFilterOption {
6
+ label: string
7
+ value: string
8
+ }
9
+
10
+ export interface QuickFilterProps {
11
+ options: QuickFilterOption[]
12
+ selectedValues: string[]
13
+ onChange: (selectedValues: string[]) => void
14
+ label?: string
15
+ }
16
+
17
+ export const QuickFilter: React.FC<QuickFilterProps> = ({
18
+ options,
19
+ selectedValues = [],
20
+ onChange,
21
+ label,
22
+ }) => {
23
+ const toggleOption = (value: string) => {
24
+ if (selectedValues?.includes(value)) {
25
+ onChange(selectedValues.filter((v) => v !== value))
26
+ } else {
27
+ onChange([...selectedValues, value])
28
+ }
29
+ }
30
+
31
+ return (
32
+ <div className="quick-filter">
33
+ {label && <span className="quick-filter__label">{label}</span>}
34
+ <div className="quick-filter__options">
35
+ {options.map((option) => (
36
+ <GhostButton
37
+ key={option.value}
38
+ type="button"
39
+ size="sm"
40
+ className={
41
+ selectedValues?.includes(option.value) ? 'active' : ''
42
+ }
43
+ onClick={() => toggleOption(option.value)}
44
+ >
45
+ {option.label}
46
+ </GhostButton>
47
+ ))}
48
+ </div>
49
+ </div>
50
+ )
51
+ }
@@ -0,0 +1 @@
1
+ export * from './QuickFilter'
@@ -6,10 +6,8 @@ export interface SectionHeaderProps {
6
6
  className?: string;
7
7
  }
8
8
 
9
- export const SectionHeader: React.FC<SectionHeaderProps> = ({ title, className = '' }) => {
10
- return (
11
- <span className={`section-header ${className}`}>
12
- {title}
13
- </span>
14
- );
15
- };
9
+ export const SectionHeader: React.FC<SectionHeaderProps> = ({ title, className = '' }) => (
10
+ <span className={`section-header ${className}`}>
11
+ {title}
12
+ </span>
13
+ );
@@ -1,20 +1,41 @@
1
1
  @import '../../design-system/typography/Typography.scss';
2
2
 
3
+ .select-wrapper {
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: var(--spacing-sm, 8px);
7
+ width: 100%;
8
+ }
9
+
10
+ .select-label {
11
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
12
+ font-size: 15px;
13
+ font-style: normal;
14
+ font-weight: 600;
15
+ line-height: 20px;
16
+ color: var(--label-primary, #121E52);
17
+ display: block;
18
+ }
19
+
20
+ .select-label-optional {
21
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
22
+ font-size: 15px;
23
+ font-weight: 600;
24
+ line-height: 20px;
25
+ color: var(--label-primary, #121E52);
26
+ }
27
+
28
+
3
29
  .select-container {
4
30
  position: relative;
5
- display: inline-block;
6
- width: auto;
7
- max-width: 152px;
8
-
9
- @media (min-width: 768px) {
10
- max-width: 448px;
11
- }
31
+ display: block;
32
+ width: 100%;
12
33
  }
13
34
 
14
35
  .select {
15
36
  @include typography('heading.h5');
16
37
  display: block;
17
- width: auto;
38
+ width: 100%;
18
39
  height: 40px;
19
40
  padding: 8px var(--padding-reg, 16px);
20
41
  padding-right: 40px;
@@ -28,13 +49,12 @@
28
49
  border-radius: var(--radius-md, 4px);
29
50
  transition: all 0.2s ease-in-out;
30
51
  &:hover:not(:disabled) {
31
- border-color: var(--disabled-regular);
52
+ border-color: var(--border-primary);
32
53
  }
33
54
 
34
55
  &:focus {
35
56
  outline: none;
36
- border-color: var(--highlight-dark);
37
- box-shadow: 0 0 0 3px var(--surface-highlight-soft);
57
+ border-color: var(--border-selected, #6200EE);
38
58
  }
39
59
 
40
60
  // Variants
@@ -49,7 +69,7 @@
49
69
 
50
70
  &--focus {
51
71
  background-color: var(--surface-secondary);
52
- border-color: var(--border-selected);
72
+ border-color: var(--border-selected, #6200EE);
53
73
  }
54
74
 
55
75
  &--secondary {
@@ -148,26 +168,14 @@
148
168
  }
149
169
 
150
170
  .select {
151
- &:focus {
152
- outline: none;
153
- border-color: var(--highlight-dark);
154
- box-shadow: 0 0 0 3px var(--surface-highlight-soft);
155
- transform: translateY(-1px);
156
- }
157
-
158
171
  &:active {
159
172
  transform: translateY(0px);
160
- box-shadow: 0 0 0 2px var(--surface-highlight-soft);
161
173
  }
162
174
 
163
175
  &.select--transitioning {
164
176
  opacity: 0.8;
165
177
  transform: scale(0.98);
166
178
  border-color: var(--cyan-700);
167
-
168
- &:focus {
169
- transform: scale(0.98) translateY(-1px);
170
- }
171
179
  }
172
180
  }
173
181
 
@@ -186,3 +194,32 @@
186
194
  .select--filter-active {
187
195
  animation: filterPulse 0.6s ease-out;
188
196
  }
197
+
198
+ .select-helper-text {
199
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
200
+ font-size: var(--text-regular-size, 15px);
201
+ font-style: normal;
202
+ font-weight: 400;
203
+ line-height: var(--text-regular-line, 20px);
204
+ margin-top: 2px;
205
+ color: var(--label-secondary, #626A90);
206
+ min-width: max-content;
207
+ white-space: nowrap;
208
+
209
+ @media (max-width: 768px) {
210
+ min-width: unset;
211
+ white-space: normal;
212
+ word-wrap: break-word;
213
+ }
214
+ }
215
+
216
+ .select-error-text {
217
+ font-family: var(--font-family-sans, 'Geist', sans-serif);
218
+ font-size: var(--text-sm-size, 13px);
219
+ font-style: normal;
220
+ font-weight: 400;
221
+ line-height: var(--text-sm-line, 18px);
222
+ color: var(--status-error, #D32F2F);
223
+ margin-top: 2px;
224
+ }
225
+
@@ -161,4 +161,80 @@ export const AllVariants: Story = {
161
161
  </div>
162
162
  </div>
163
163
  ),
164
- }
164
+ }
165
+
166
+ export const WithLabel: Story = {
167
+ args: {
168
+ label: 'Select an option',
169
+ variant: 'default',
170
+ size: 'md',
171
+ },
172
+ render: (args) => (
173
+ <div style={{ width: '300px' }}>
174
+ <Select {...args}>
175
+ <option value="">Select</option>
176
+ <option value="option1">Option 1</option>
177
+ <option value="option2">Option 2</option>
178
+ <option value="option3">Option 3</option>
179
+ </Select>
180
+ </div>
181
+ ),
182
+ }
183
+
184
+ export const WithLabelAndOptional: Story = {
185
+ args: {
186
+ label: 'Gender',
187
+ optional: true,
188
+ variant: 'default',
189
+ size: 'md',
190
+ },
191
+ render: (args) => (
192
+ <div style={{ width: '300px' }}>
193
+ <Select {...args}>
194
+ <option value="">Select gender</option>
195
+ <option value="female">Female</option>
196
+ <option value="male">Male</option>
197
+ <option value="prefer_not_to_say">Prefer not to say</option>
198
+ </Select>
199
+ </div>
200
+ ),
201
+ }
202
+
203
+ export const WithError: Story = {
204
+ args: {
205
+ label: 'Country',
206
+ error: 'Please select a country',
207
+ variant: 'default',
208
+ size: 'md',
209
+ },
210
+ render: (args) => (
211
+ <div style={{ width: '300px' }}>
212
+ <Select {...args}>
213
+ <option value="">Select country</option>
214
+ <option value="us">United States</option>
215
+ <option value="uk">United Kingdom</option>
216
+ <option value="ca">Canada</option>
217
+ </Select>
218
+ </div>
219
+ ),
220
+ }
221
+
222
+ export const WithHelperText: Story = {
223
+ args: {
224
+ label: 'Timezone',
225
+ helperText: 'Choose your preferred timezone',
226
+ variant: 'default',
227
+ size: 'md',
228
+ },
229
+ render: (args) => (
230
+ <div style={{ width: '300px' }}>
231
+ <Select {...args}>
232
+ <option value="">Select timezone</option>
233
+ <option value="utc">UTC</option>
234
+ <option value="est">EST</option>
235
+ <option value="pst">PST</option>
236
+ </Select>
237
+ </div>
238
+ ),
239
+ }
240
+
@@ -1,56 +1,85 @@
1
- import React, { HTMLAttributes } from 'react'
1
+ import { SelectHTMLAttributes } from 'react'
2
2
  import './Select.scss'
3
3
 
4
- export interface SelectProps extends HTMLAttributes<HTMLSelectElement> {
4
+ export interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> {
5
5
  variant?: 'default' | 'hover'| 'focus' | 'error' | 'disabled'
6
6
  size?: 'sm' | 'md' | 'lg'
7
- disabled?: boolean
7
+ label?: string
8
+ optional?: boolean
9
+ error?: string
10
+ helperText?: string
8
11
  }
9
12
 
10
- export function Select({
11
- variant = 'default',
12
- size = 'md',
13
- disabled = false,
13
+ export function Select({
14
+ variant = 'default',
15
+ size = 'md',
16
+ disabled = false,
14
17
  className = '',
18
+ label,
19
+ optional,
20
+ error,
21
+ helperText,
15
22
  children,
16
- ...props
23
+ ...props
17
24
  }: SelectProps) {
25
+ const isError = !!error
18
26
  const classes = [
19
27
  'select',
20
28
  `select--${variant}`,
21
29
  `select--${size}`,
22
30
  disabled ? 'select--disabled' : '',
31
+ isError ? 'select--error' : '',
23
32
  className
24
33
  ].filter(Boolean).join(' ')
25
34
 
26
35
  return (
27
- <div className="select-container">
28
- <select
29
- className={classes}
30
- disabled={disabled}
31
- {...props}
32
- >
33
- {children}
34
- </select>
35
- <svg
36
- className="select-arrow"
37
- xmlns="http://www.w3.org/2000/svg"
38
- width="11"
39
- height="6"
40
- viewBox="0 0 11 6"
41
- fill="none"
42
- aria-hidden="true"
43
- >
44
- <path
45
- d="M1 1L5.5 5L10 1"
46
- stroke="#626A90"
47
- strokeWidth="2"
48
- strokeLinecap="round"
49
- strokeLinejoin="round"
50
- />
51
- </svg>
36
+ <div className="select-wrapper">
37
+ {(label || optional) && (
38
+ <label className="select-label">
39
+ {label} {optional && <span className="select-label-optional">(Optional)</span>}
40
+ </label>
41
+ )}
42
+
43
+ <div className="select-container">
44
+ <select
45
+ className={classes}
46
+ disabled={disabled}
47
+ {...props}
48
+ >
49
+ {children}
50
+ </select>
51
+ <svg
52
+ className="select-arrow"
53
+ xmlns="http://www.w3.org/2000/svg"
54
+ width="11"
55
+ height="6"
56
+ viewBox="0 0 11 6"
57
+ fill="none"
58
+ aria-hidden="true"
59
+ >
60
+ <path
61
+ d="M1 1L5.5 5L10 1"
62
+ stroke="#626A90"
63
+ strokeWidth="2"
64
+ strokeLinecap="round"
65
+ strokeLinejoin="round"
66
+ />
67
+ </svg>
68
+ </div>
69
+
70
+ {helperText && (
71
+ <p className="select-helper-text">
72
+ {helperText}
73
+ </p>
74
+ )}
75
+
76
+ {error && error !== ' ' && (
77
+ <p className="select-error-text">
78
+ {error}
79
+ </p>
80
+ )}
52
81
  </div>
53
82
  )
54
83
  }
55
84
 
56
- export default Select
85
+ export default Select
@@ -0,0 +1,20 @@
1
+ import React from 'react'
2
+ import { ArrowUpIcon, ArrowDownIcon } from '../../icons'
3
+
4
+ export type SortDirection = 'asc' | 'desc' | null
5
+
6
+ export interface TableSortIconProps {
7
+ active?: boolean
8
+ direction: SortDirection
9
+ className?: string
10
+ }
11
+
12
+ export const TableSortIcon: React.FC<TableSortIconProps> = ({ active = false, direction, className = '' }) => {
13
+ if (!active || !direction) return null
14
+
15
+ return (
16
+ <span className={className}>
17
+ {direction === 'asc' ? <ArrowUpIcon /> : <ArrowDownIcon />}
18
+ </span>
19
+ )
20
+ }
@@ -0,0 +1 @@
1
+ export * from './TableSortIcon'
@@ -62,8 +62,8 @@ export const QuoteAltIcon = () => (
62
62
  export const DividerIcon = () => (
63
63
  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
64
64
  <rect x="5.25" y="11.25" width="13.5" height="1.5" fill="#626A90"/>
65
- <circle cx="21.75" cy="12" r="0.75" fill="#626A90" fill-opacity="0.5"/>
66
- <circle cx="2.25" cy="12" r="0.75" fill="#626A90" fill-opacity="0.5"/>
65
+ <circle cx="21.75" cy="12" r="0.75" fill="#626A90" fillOpacity="0.5"/>
66
+ <circle cx="2.25" cy="12" r="0.75" fill="#626A90" fillOpacity="0.5"/>
67
67
  </svg>
68
68
  );
69
69
 
@@ -1,3 +1,22 @@
1
+ export { Badge } from './Badge'
2
+ export type { BadgeProps } from './Badge'
3
+
4
+ export { QuickFilter } from './QuickFilter'
5
+ export type { QuickFilterProps, QuickFilterOption } from './QuickFilter'
6
+
7
+ export { NewTable } from './NewTable'
8
+ export type { NewTableProps, NewTableColumn } from './NewTable'
9
+
10
+ export { TableSortIcon } from './TableSortIcon'
11
+ export type { TableSortIconProps } from './TableSortIcon'
12
+
13
+
14
+ export { ActionMenu } from './ActionMenu'
15
+ export type { ActionMenuProps, ActionMenuItem } from './ActionMenu'
16
+
17
+ export { DeleteModal } from './Modal'
18
+ export type { DeleteModalProps } from './Modal'
19
+
1
20
  // Form Components
2
21
  export { FormField } from './FormField'
3
22
  export type { FormFieldProps } from './FormField'
@@ -18,11 +37,8 @@ export { SectionHeader } from './SectionHeader'
18
37
  export type { SectionHeaderProps } from './SectionHeader'
19
38
 
20
39
  // Existing Components
21
- export { Button, ButtonText } from './Button'
22
- export type { ButtonProps, ButtonTextProps } from './Button'
23
-
24
- export { GhostButton } from './Button/GhostButton'
25
- export type { GhostButtonProps } from './Button/GhostButton'
40
+ export { Button, ButtonText, GhostButton } from './Button'
41
+ export type { ButtonProps, ButtonTextProps, GhostButtonProps } from './Button'
26
42
 
27
43
  export { Select } from './Select'
28
44
 
@@ -34,7 +50,30 @@ export { UserPanel } from './UserPanel'
34
50
 
35
51
  export { EntityHeader } from './EntityHeader'
36
52
 
53
+
37
54
  export { Alert } from './Alert'
38
55
 
39
56
  export { NPSScore } from './NPSScore'
40
57
 
58
+ export { Pagination } from './Pagination'
59
+ export type { PaginationProps } from './Pagination'
60
+
61
+ // Icons
62
+ export {
63
+ InfoIcon,
64
+ ArrowUpIcon,
65
+ ArrowDownIcon,
66
+ EditIcon,
67
+ ArrowLeftIcon,
68
+ ArrowRightIcon,
69
+ SearchIcon,
70
+ RefreshIcon,
71
+ SendIcon,
72
+ ExternalLinkIcon,
73
+ ExportIcon,
74
+ ClearIcon,
75
+ CloseIcon,
76
+ EllipsisIcon,
77
+ CircleIcon
78
+ } from '../icons'
79
+