@stack-spot/portal-components 2.15.0 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/AnimatedHeight.d.ts +0 -1
  3. package/dist/components/AnimatedHeight.d.ts.map +1 -1
  4. package/dist/components/AsyncContent.d.ts.map +1 -1
  5. package/dist/components/BannerWarning.d.ts.map +1 -1
  6. package/dist/components/Breadcrumb/index.d.ts +0 -1
  7. package/dist/components/Breadcrumb/index.d.ts.map +1 -1
  8. package/dist/components/Breadcrumb/styled.d.ts +0 -1
  9. package/dist/components/Breadcrumb/styled.d.ts.map +1 -1
  10. package/dist/components/ButtonLoading.d.ts.map +1 -1
  11. package/dist/components/FadingOverflow.d.ts +0 -1
  12. package/dist/components/FadingOverflow.d.ts.map +1 -1
  13. package/dist/components/FileTreeView/index.d.ts.map +1 -1
  14. package/dist/components/InfiniteScroll.d.ts +1 -1
  15. package/dist/components/InfiniteScroll.d.ts.map +1 -1
  16. package/dist/components/LazyMarkdown/BlockquoteMd.d.ts.map +1 -1
  17. package/dist/components/LazyMarkdown/CodeViewer.d.ts.map +1 -1
  18. package/dist/components/LazyMarkdown/Markdown.d.ts.map +1 -1
  19. package/dist/components/LazyMarkdown/MarkdownButton.d.ts.map +1 -1
  20. package/dist/components/LazyMarkdown/Video.d.ts.map +1 -1
  21. package/dist/components/LazyMarkdown/index.d.ts.map +1 -1
  22. package/dist/components/Placeholder.d.ts +0 -1
  23. package/dist/components/Placeholder.d.ts.map +1 -1
  24. package/dist/components/ScrollView.d.ts +0 -1
  25. package/dist/components/ScrollView.d.ts.map +1 -1
  26. package/dist/components/Select/BadgeItem.d.ts +3 -0
  27. package/dist/components/Select/BadgeItem.d.ts.map +1 -0
  28. package/dist/components/Select/BadgeItem.js +5 -0
  29. package/dist/components/Select/BadgeItem.js.map +1 -0
  30. package/dist/components/Select/ClearInput.d.ts +3 -0
  31. package/dist/components/Select/ClearInput.d.ts.map +1 -0
  32. package/dist/components/Select/ClearInput.js +18 -0
  33. package/dist/components/Select/ClearInput.js.map +1 -0
  34. package/dist/components/Select/CloseItem.d.ts +3 -0
  35. package/dist/components/Select/CloseItem.d.ts.map +1 -0
  36. package/dist/components/Select/CloseItem.js +26 -0
  37. package/dist/components/Select/CloseItem.js.map +1 -0
  38. package/dist/components/Select/CreatableSelect.d.ts +15 -0
  39. package/dist/components/Select/CreatableSelect.d.ts.map +1 -0
  40. package/dist/components/Select/CreatableSelect.js +155 -0
  41. package/dist/components/Select/CreatableSelect.js.map +1 -0
  42. package/dist/components/Select/LabelItem.d.ts +3 -0
  43. package/dist/components/Select/LabelItem.d.ts.map +1 -0
  44. package/dist/components/Select/LabelItem.js +4 -0
  45. package/dist/components/Select/LabelItem.js.map +1 -0
  46. package/dist/components/Select/SelectSearch.d.ts +11 -0
  47. package/dist/components/Select/SelectSearch.d.ts.map +1 -0
  48. package/dist/components/Select/SelectSearch.js +114 -0
  49. package/dist/components/Select/SelectSearch.js.map +1 -0
  50. package/dist/components/Select/index.d.ts +4 -0
  51. package/dist/components/Select/index.d.ts.map +1 -0
  52. package/dist/components/Select/index.js +4 -0
  53. package/dist/components/Select/index.js.map +1 -0
  54. package/dist/components/Select/types.d.ts +7 -0
  55. package/dist/components/Select/types.d.ts.map +1 -0
  56. package/dist/components/Select/types.js +2 -0
  57. package/dist/components/Select/types.js.map +1 -0
  58. package/dist/components/SelectionList.d.ts.map +1 -1
  59. package/dist/components/StatusCircle.d.ts +0 -1
  60. package/dist/components/StatusCircle.d.ts.map +1 -1
  61. package/dist/components/TimelineSection.d.ts +0 -1
  62. package/dist/components/TimelineSection.d.ts.map +1 -1
  63. package/dist/components/error/ErrorFeedback.d.ts +0 -1
  64. package/dist/components/error/ErrorFeedback.d.ts.map +1 -1
  65. package/dist/components/error/NotFound.d.ts.map +1 -1
  66. package/dist/components/error/UnderMaintenance.d.ts.map +1 -1
  67. package/dist/components/form/SearchInput.d.ts.map +1 -1
  68. package/dist/components/form/Select/styled.d.ts +0 -1
  69. package/dist/components/form/Select/styled.d.ts.map +1 -1
  70. package/dist/components/notification/NotificationComponent.d.ts.map +1 -1
  71. package/dist/components/notification/NotificationItem.d.ts.map +1 -1
  72. package/dist/components/notification/NotificationItem.js +2 -1
  73. package/dist/components/notification/NotificationItem.js.map +1 -1
  74. package/dist/components/notification/NotificationList.d.ts +0 -1
  75. package/dist/components/notification/NotificationList.d.ts.map +1 -1
  76. package/dist/components/notification/NotificationPlaceholder.d.ts +0 -1
  77. package/dist/components/notification/NotificationPlaceholder.d.ts.map +1 -1
  78. package/dist/context/anchor.d.ts +0 -1
  79. package/dist/context/anchor.d.ts.map +1 -1
  80. package/dist/context/loading.d.ts.map +1 -1
  81. package/dist/context/notification/context.d.ts +0 -1
  82. package/dist/context/notification/context.d.ts.map +1 -1
  83. package/dist/hooks/keyboard.d.ts +0 -1
  84. package/dist/hooks/keyboard.d.ts.map +1 -1
  85. package/dist/hooks/text.d.ts +0 -1
  86. package/dist/hooks/text.d.ts.map +1 -1
  87. package/dist/hooks/use-effect-once.d.ts.map +1 -1
  88. package/dist/index.d.ts +1 -0
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +1 -0
  91. package/dist/index.js.map +1 -1
  92. package/dist/svg/AI.d.ts.map +1 -1
  93. package/dist/svg/CS.d.ts.map +1 -1
  94. package/dist/svg/EDP.d.ts.map +1 -1
  95. package/dist/svg/Forbidden.d.ts.map +1 -1
  96. package/dist/svg/GenericPlaceholder.d.ts.map +1 -1
  97. package/dist/svg/HUB.d.ts.map +1 -1
  98. package/dist/svg/Logo.d.ts.map +1 -1
  99. package/dist/svg/MiniLogo.d.ts.map +1 -1
  100. package/dist/svg/NotFound.d.ts.map +1 -1
  101. package/dist/svg/ServerError.d.ts.map +1 -1
  102. package/dist/svg/Unauthenticated.d.ts.map +1 -1
  103. package/package.json +2 -1
  104. package/src/components/Select/BadgeItem.tsx +8 -0
  105. package/src/components/Select/ClearInput.tsx +24 -0
  106. package/src/components/Select/CloseItem.tsx +38 -0
  107. package/src/components/Select/CreatableSelect.tsx +197 -0
  108. package/src/components/Select/LabelItem.tsx +8 -0
  109. package/src/components/Select/SelectSearch.tsx +141 -0
  110. package/src/components/Select/index.tsx +5 -0
  111. package/src/components/Select/types.ts +8 -0
  112. package/src/components/notification/NotificationItem.tsx +2 -1
  113. package/src/index.ts +1 -0
@@ -0,0 +1,197 @@
1
+ import { theme } from '@stack-spot/portal-theme'
2
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
3
+ import { FC, useEffect, useState } from 'react'
4
+ import { CSSObjectWithLabel } from 'react-select'
5
+ import Creatable from 'react-select/creatable'
6
+ import { BadgeItem } from './BadgeItem'
7
+ import { ClearInput } from './ClearInput'
8
+ import { CloseItem } from './CloseItem'
9
+ import { LabelItem } from './LabelItem'
10
+ import { CreatableSelectOptionType, CreatableValueType } from './types'
11
+
12
+ export interface CreatableSelectProps {
13
+ id?: string,
14
+ name?: string,
15
+ disabled?: boolean,
16
+ isLoading?: boolean,
17
+ isMulti?: boolean,
18
+ options?: CreatableSelectOptionType[],
19
+ className?: string,
20
+ value?: string | string[],
21
+ onChange?: (newValue: CreatableValueType) => void,
22
+ }
23
+
24
+ export const CreatableSelect: FC<CreatableSelectProps> = ({ disabled, options, value, isMulti, onChange, id, ...props }) => {
25
+ const t = useTranslate(dictionary)
26
+ const [inputOptions, setInputOptions] = useState(options || [])
27
+ const prepareValue = () => {
28
+ let startValue: CreatableValueType | undefined = undefined
29
+ if (value) {
30
+ if (isMulti) {
31
+ const typedValue = value as string[] || []
32
+ startValue = [...typedValue].map((v) => ({ label: v, value: v }))
33
+ } else {
34
+ const typedValue = value as string
35
+ startValue = { label: typedValue, value: typedValue }
36
+ }
37
+ }
38
+ return startValue
39
+ }
40
+
41
+ const [inputValue, setInputValue] = useState<CreatableValueType | undefined>(prepareValue())
42
+
43
+ useEffect(() => {
44
+ const newValue = prepareValue()
45
+ inputValue !== newValue && setInputValue(newValue)
46
+ }, [value])
47
+
48
+
49
+ const handleCreate = (newValue: string) => {
50
+ const newOption = { label: newValue, value: newValue }
51
+ setInputOptions((prev) => [...prev, newOption])
52
+ if (isMulti) {
53
+ setInputValue((prev) => {
54
+ const previousValue = Array.isArray(prev) ? prev : []
55
+ const newInputValue = [...(previousValue as CreatableSelectOptionType[]), newOption]
56
+ setTimeout(() => {
57
+ onChange && onChange(newInputValue)
58
+ }, 100)
59
+ return newInputValue
60
+ })
61
+ } else {
62
+ setInputValue(newOption)
63
+ onChange && onChange(newOption)
64
+ }
65
+ }
66
+
67
+ const handleChange = (newValue: CreatableValueType) => {
68
+ setInputValue(newValue)
69
+ onChange && onChange(newValue)
70
+ }
71
+
72
+ return (
73
+ <Creatable
74
+ placeholder={t.typeYourOption}
75
+ {...props}
76
+ inputId={id}
77
+ isClearable={true}
78
+ isDisabled={disabled}
79
+ value={inputValue}
80
+ options={inputOptions}
81
+ isMulti={isMulti}
82
+ onChange={handleChange}
83
+ onCreateOption={handleCreate}
84
+ components={{ MultiValueContainer: BadgeItem, MultiValueLabel: LabelItem, MultiValueRemove: CloseItem, ClearIndicator: ClearInput }}
85
+ noOptionsMessage={() => (t.typeYourOption)}
86
+ formatCreateLabel={(value) => (value)}
87
+ tabSelectsValue={false}
88
+ styles={{
89
+ control: (base, state) => ({
90
+ ...base,
91
+ minHeight: '2.5rem',
92
+ height: 'auto',
93
+ backgroundColor: theme.color.light[300],
94
+ border: `0.063rem solid ${theme.color.light[600]}`,
95
+ borderRadius: '0.25rem',
96
+ fontSize: '0.875rem',
97
+ fontStyle: 'normal',
98
+ fontFeatureSettings: '\'clig\' off, \'liga\' off',
99
+ display: 'flex',
100
+ alignItems: 'center',
101
+ outlineColor: theme.color.light[700],
102
+
103
+ '&:hover': {
104
+ border: `0.063rem solid ${theme.color.light[600]}`,
105
+ },
106
+
107
+ ...(state.isFocused || state.menuIsOpen ? {
108
+ borderColor: `${theme.color.primary[500]} !important`,
109
+ outline: `0.063rem solid ${theme.color.primary[500]} !important`,
110
+ } : {}),
111
+ } as CSSObjectWithLabel),
112
+ input: () => ({
113
+ color: theme.color.light.contrastText,
114
+ }),
115
+ placeholder: () => ({
116
+ display: 'none',
117
+ }),
118
+ dropdownIndicator: () => ({
119
+ display: 'none',
120
+ }),
121
+ indicatorSeparator: () => ({
122
+ display: 'none',
123
+ }),
124
+ singleValue: (base) => ({
125
+ ...base,
126
+ color: theme.color.light.contrastText,
127
+ } as CSSObjectWithLabel),
128
+ menu: (base) => ({
129
+ ...base,
130
+ backgroundColor: theme.color.light[500],
131
+ border: `0.063rem solid ${theme.color.light[400]}`,
132
+ borderRadius: '0.5rem',
133
+ boxShadow: `0 0 0 0.125rem ${theme.color.gray[600]}`,
134
+ color: theme.color.light.contrastText,
135
+ } as CSSObjectWithLabel),
136
+ multiValue: (base) => ({
137
+ ...base,
138
+ backgroundColor: 'inherit',
139
+ display: 'flex',
140
+ alignItems: 'center',
141
+ justifyItems: 'center',
142
+ }),
143
+ multiValueRemove: (base) => ({
144
+ ...base,
145
+ cursor: 'pointer',
146
+ backgroundColor: 'inherit',
147
+ paddingRight: 0,
148
+ ':hover': {
149
+ backgroundColor: 'inherit',
150
+ color: 'inherit',
151
+ },
152
+ }),
153
+ option: (styles, { isDisabled, isFocused, isSelected }) => ({
154
+ ...styles,
155
+ backgroundColor: isDisabled
156
+ ? undefined
157
+ : isSelected
158
+ ? theme.color.light[700]
159
+ : isFocused
160
+ ? theme.color.light[600]
161
+ : undefined,
162
+
163
+ color: isSelected ? theme.color.light[300] : theme.color.light.contrastText,
164
+
165
+ cursor: isDisabled ? 'not-allowed' : 'default',
166
+
167
+ ':active': {
168
+ ...styles[':active'],
169
+ backgroundColor: !isDisabled
170
+ ? isSelected
171
+ ? theme.color.light.contrastText
172
+ : theme.color.light[600]
173
+ : undefined,
174
+ },
175
+
176
+ ':hover': {
177
+ ...styles[':hover'],
178
+ backgroundColor: !isDisabled
179
+ ? isSelected
180
+ ? theme.color.light[700]
181
+ : theme.color.light[600]
182
+ : undefined,
183
+ },
184
+ } as CSSObjectWithLabel),
185
+ }}
186
+ />
187
+ )
188
+ }
189
+
190
+ const dictionary = {
191
+ en: {
192
+ typeYourOption: 'Type your option',
193
+ },
194
+ pt: {
195
+ typeYourOption: 'Insira a sua opção',
196
+ },
197
+ } satisfies Dictionary
@@ -0,0 +1,8 @@
1
+ import { Box, Text } from '@citric/core'
2
+ import { MultiValueGenericProps } from 'react-select'
3
+
4
+ export const LabelItem = (props: MultiValueGenericProps<any>) => (
5
+ <Box>
6
+ <Text>{props.data.label}</Text>
7
+ </Box>
8
+ )
@@ -0,0 +1,141 @@
1
+ import { theme } from '@stack-spot/portal-theme'
2
+ import { Dictionary, useTranslate } from '@stack-spot/portal-translate'
3
+ import { RefCallback } from 'react'
4
+ import Select, { components, CSSObjectWithLabel, Props as SelectProps } from 'react-select'
5
+ import { BadgeItem } from './BadgeItem'
6
+ import { ClearInput } from './ClearInput'
7
+ import { CloseItem } from './CloseItem'
8
+ import { LabelItem } from './LabelItem'
9
+
10
+ export interface SelectSearchProps extends Partial<SelectProps> {
11
+ options: any[],
12
+ components?: Partial<typeof components>,
13
+ disabled?: boolean,
14
+ onChange?: (newValue?: any) => void,
15
+ ref?: RefCallback<any>,
16
+ }
17
+
18
+ export const SelectSearch = ({
19
+ options,
20
+ components: customComponents = {},
21
+ onChange,
22
+ styles: customStyles = {},
23
+ disabled,
24
+ ref,
25
+ ...props
26
+ }: SelectSearchProps) => {
27
+ const t = useTranslate(dictionary)
28
+ return (
29
+ <Select
30
+ options={options}
31
+ onChange={onChange}
32
+ isDisabled={disabled}
33
+ ref={ref}
34
+ noOptionsMessage={() => t.noOptions}
35
+ {...props}
36
+ styles={{
37
+ ...customStyles,
38
+ control: (base, state) => ({
39
+ ...base,
40
+ height: '2.5rem',
41
+ display: 'flex',
42
+ alignItems: 'center',
43
+ padding: '0px',
44
+ color: theme.color.light.contrastText,
45
+ backgroundColor: theme.color.light[300],
46
+ border: `1px solid ${theme.color.light[600]}`,
47
+ outlineColor: theme.color.light[700],
48
+ '&:hover': {
49
+ border: `0.063rem solid ${theme.color.light[600]}`,
50
+ },
51
+ fontSize: '0.875rem',
52
+ lineHeight: '1.714',
53
+ fontFamily: 'Roboto, sans-serif',
54
+ ...(state.isFocused || state.menuIsOpen
55
+ ? {
56
+ borderColor: `${theme.color.primary[500]} !important`,
57
+ outline: `0.063rem solid ${theme.color.primary[500]} !important`,
58
+ }
59
+ : {}),
60
+ ...(state.isDisabled
61
+ ? {
62
+ backgroundColor: theme.color.light[500],
63
+ borderColor: theme.color.light[600],
64
+ cursor: 'not-allowed',
65
+ }
66
+ : {}),
67
+ ...customStyles?.control?.(base, state),
68
+ } as CSSObjectWithLabel),
69
+ input: (base, state) => ({
70
+ ...base,
71
+ color: theme.color.light.contrastText,
72
+ ...customStyles?.input?.(base, state),
73
+ }),
74
+ menu: (base, state) => ({
75
+ ...base,
76
+ marginTop: '0.25rem',
77
+ position: 'relative',
78
+ ...customStyles?.menu?.(base, state),
79
+ }),
80
+ option: (base, state) => ({
81
+ ...base,
82
+ display: 'flex',
83
+ alignItems: 'center',
84
+ backgroundColor: theme.color.light[300],
85
+ cursor: 'pointer',
86
+ '&:hover': {
87
+ backgroundColor: theme.color.light[500],
88
+ },
89
+ border: '1px solid transparent',
90
+ ...(state.isFocused
91
+ ? {
92
+ borderColor: `${theme.color.light.contrastText} !important`,
93
+ }
94
+ : {}),
95
+ ...customStyles?.option?.(base, state),
96
+ }),
97
+ menuList: (base, state) => ({
98
+ ...base,
99
+ padding: 0,
100
+ '&::-webkit-scrollbar': {
101
+ width: '0.125rem',
102
+ height: '.5rem',
103
+ backgroundColor: 'transparent',
104
+ },
105
+ '&::-webkit-scrollbar-track': {
106
+ background: `${theme.color.light[300]}`,
107
+ borderRadius: '2px',
108
+ },
109
+ '&::-webkit-scrollbar-thumb': {
110
+ background: `${theme.color.primary[500]}`,
111
+ borderRadius: '2px',
112
+ },
113
+ '&::-webkit-scrollbar-thumb:hover': {
114
+ background: `${theme.color.light[700]}`,
115
+ borderRadius: '2px',
116
+ },
117
+ '&::-webkit-scrollbar-corner': {
118
+ backgroundColor: 'transparent',
119
+ },
120
+ ...customStyles?.menuList?.(base, state),
121
+ }),
122
+ }}
123
+ components={{
124
+ ...components,
125
+ MultiValueContainer: BadgeItem,
126
+ MultiValueLabel: LabelItem,
127
+ MultiValueRemove: CloseItem,
128
+ ClearIndicator: ClearInput,
129
+ ...customComponents,
130
+ }}
131
+ />
132
+ )}
133
+
134
+ const dictionary = {
135
+ en: {
136
+ noOptions: 'No options',
137
+ },
138
+ pt: {
139
+ noOptions: 'Sem opções',
140
+ },
141
+ } satisfies Dictionary
@@ -0,0 +1,5 @@
1
+ import { CreatableSelect } from './CreatableSelect'
2
+ import { SelectSearch, SelectSearchProps } from './SelectSearch'
3
+
4
+ export { CreatableSelect, SelectSearch, SelectSearchProps }
5
+
@@ -0,0 +1,8 @@
1
+ import { MultiValue, SingleValue } from 'react-select'
2
+
3
+ export type CreatableValueType = SingleValue<CreatableSelectOptionType> | MultiValue<CreatableSelectOptionType>
4
+
5
+ export interface CreatableSelectOptionType {
6
+ label: string,
7
+ value: string,
8
+ }
@@ -280,7 +280,8 @@ export const NotificationItem = ({ notification, isSummary, ...props }: Notifica
280
280
  }
281
281
 
282
282
  function handleTextMark(text: string) {
283
- return text.replace(/[^\p{L}\p{N}\s\p{Emoji_Presentation}:!'()]/gu, '')
283
+ // eslint-disable-next-line no-useless-escape
284
+ return text.replace(/[^\p{L}\p{N}\s\p{Emoji_Presentation}:!'()\/]/gu, '')
284
285
  }
285
286
 
286
287
  const dictionary = {
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ export { AsyncContent } from './components/AsyncContent'
2
2
  export { BannerWarning } from './components/BannerWarning'
3
3
  export { ButtonLoading } from './components/ButtonLoading'
4
4
  export { ChatBot } from './components/ChatBot'
5
+ export * from './components/Select'
5
6
  export { useDateFormatter } from './hooks/date'
6
7
  export { useKeyboardControls } from './hooks/keyboard'
7
8
  export { useManualRender } from './hooks/manual-render'