@instructure/ui-color-picker 8.25.1-snapshot-20

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 (201) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +46 -0
  3. package/es/ColorContrast/ColorContrastLocator.js +54 -0
  4. package/es/ColorContrast/index.js +174 -0
  5. package/es/ColorContrast/props.js +40 -0
  6. package/es/ColorContrast/styles.js +99 -0
  7. package/es/ColorContrast/theme.js +55 -0
  8. package/es/ColorIndicator/ColorIndicatorLocator.js +40 -0
  9. package/es/ColorIndicator/index.js +91 -0
  10. package/es/ColorIndicator/props.js +31 -0
  11. package/es/ColorIndicator/styles.js +70 -0
  12. package/es/ColorIndicator/theme.js +53 -0
  13. package/es/ColorMixer/ColorMixerLocator.js +27 -0
  14. package/es/ColorMixer/ColorPalette/index.js +258 -0
  15. package/es/ColorMixer/ColorPalette/props.js +37 -0
  16. package/es/ColorMixer/ColorPalette/styles.js +81 -0
  17. package/es/ColorMixer/ColorPalette/theme.js +48 -0
  18. package/es/ColorMixer/RGBAInput/index.js +148 -0
  19. package/es/ColorMixer/RGBAInput/props.js +39 -0
  20. package/es/ColorMixer/RGBAInput/styles.js +63 -0
  21. package/es/ColorMixer/RGBAInput/theme.js +43 -0
  22. package/es/ColorMixer/Slider/index.js +218 -0
  23. package/es/ColorMixer/Slider/props.js +38 -0
  24. package/es/ColorMixer/Slider/styles.js +95 -0
  25. package/es/ColorMixer/Slider/theme.js +53 -0
  26. package/es/ColorMixer/index.js +232 -0
  27. package/es/ColorMixer/props.js +40 -0
  28. package/es/ColorMixer/styles.js +49 -0
  29. package/es/ColorMixer/utils/shallowCompare.js +32 -0
  30. package/es/ColorPicker/ColorPickerLocator.js +137 -0
  31. package/es/ColorPicker/index.js +487 -0
  32. package/es/ColorPicker/props.js +47 -0
  33. package/es/ColorPicker/styles.js +119 -0
  34. package/es/ColorPicker/theme.js +76 -0
  35. package/es/ColorPreset/ColorPresetLocator.js +27 -0
  36. package/es/ColorPreset/index.js +268 -0
  37. package/es/ColorPreset/props.js +36 -0
  38. package/es/ColorPreset/styles.js +102 -0
  39. package/es/ColorPreset/theme.js +53 -0
  40. package/es/index.js +28 -0
  41. package/lib/ColorContrast/ColorContrastLocator.js +66 -0
  42. package/lib/ColorContrast/index.js +169 -0
  43. package/lib/ColorContrast/props.js +51 -0
  44. package/lib/ColorContrast/styles.js +107 -0
  45. package/lib/ColorContrast/theme.js +63 -0
  46. package/lib/ColorIndicator/ColorIndicatorLocator.js +51 -0
  47. package/lib/ColorIndicator/index.js +82 -0
  48. package/lib/ColorIndicator/props.js +42 -0
  49. package/lib/ColorIndicator/styles.js +78 -0
  50. package/lib/ColorIndicator/theme.js +63 -0
  51. package/lib/ColorMixer/ColorMixerLocator.js +37 -0
  52. package/lib/ColorMixer/ColorPalette/index.js +252 -0
  53. package/lib/ColorMixer/ColorPalette/props.js +48 -0
  54. package/lib/ColorMixer/ColorPalette/styles.js +90 -0
  55. package/lib/ColorMixer/ColorPalette/theme.js +57 -0
  56. package/lib/ColorMixer/RGBAInput/index.js +142 -0
  57. package/lib/ColorMixer/RGBAInput/props.js +50 -0
  58. package/lib/ColorMixer/RGBAInput/styles.js +71 -0
  59. package/lib/ColorMixer/RGBAInput/theme.js +51 -0
  60. package/lib/ColorMixer/Slider/index.js +211 -0
  61. package/lib/ColorMixer/Slider/props.js +49 -0
  62. package/lib/ColorMixer/Slider/styles.js +103 -0
  63. package/lib/ColorMixer/Slider/theme.js +62 -0
  64. package/lib/ColorMixer/index.js +226 -0
  65. package/lib/ColorMixer/props.js +51 -0
  66. package/lib/ColorMixer/styles.js +57 -0
  67. package/lib/ColorMixer/utils/shallowCompare.js +40 -0
  68. package/lib/ColorPicker/ColorPickerLocator.js +151 -0
  69. package/lib/ColorPicker/index.js +500 -0
  70. package/lib/ColorPicker/props.js +58 -0
  71. package/lib/ColorPicker/styles.js +127 -0
  72. package/lib/ColorPicker/theme.js +85 -0
  73. package/lib/ColorPreset/ColorPresetLocator.js +37 -0
  74. package/lib/ColorPreset/index.js +274 -0
  75. package/lib/ColorPreset/props.js +47 -0
  76. package/lib/ColorPreset/styles.js +110 -0
  77. package/lib/ColorPreset/theme.js +61 -0
  78. package/lib/index.js +45 -0
  79. package/lib/package.json +1 -0
  80. package/package.json +62 -0
  81. package/src/ColorContrast/ColorContrastLocator.ts +51 -0
  82. package/src/ColorContrast/README.md +111 -0
  83. package/src/ColorContrast/index.tsx +189 -0
  84. package/src/ColorContrast/props.ts +140 -0
  85. package/src/ColorContrast/styles.ts +102 -0
  86. package/src/ColorContrast/theme.ts +62 -0
  87. package/src/ColorIndicator/ColorIndicatorLocator.ts +41 -0
  88. package/src/ColorIndicator/README.md +76 -0
  89. package/src/ColorIndicator/index.tsx +89 -0
  90. package/src/ColorIndicator/props.ts +68 -0
  91. package/src/ColorIndicator/styles.ts +88 -0
  92. package/src/ColorIndicator/theme.ts +58 -0
  93. package/src/ColorMixer/ColorMixerLocator.ts +29 -0
  94. package/src/ColorMixer/ColorPalette/index.tsx +250 -0
  95. package/src/ColorMixer/ColorPalette/props.ts +87 -0
  96. package/src/ColorMixer/ColorPalette/styles.ts +94 -0
  97. package/src/ColorMixer/ColorPalette/theme.ts +52 -0
  98. package/src/ColorMixer/README.md +98 -0
  99. package/src/ColorMixer/RGBAInput/index.tsx +172 -0
  100. package/src/ColorMixer/RGBAInput/props.ts +93 -0
  101. package/src/ColorMixer/RGBAInput/styles.ts +69 -0
  102. package/src/ColorMixer/RGBAInput/theme.ts +48 -0
  103. package/src/ColorMixer/Slider/index.tsx +242 -0
  104. package/src/ColorMixer/Slider/props.ts +94 -0
  105. package/src/ColorMixer/Slider/styles.ts +114 -0
  106. package/src/ColorMixer/Slider/theme.ts +59 -0
  107. package/src/ColorMixer/index.tsx +221 -0
  108. package/src/ColorMixer/props.ts +169 -0
  109. package/src/ColorMixer/styles.ts +51 -0
  110. package/src/ColorMixer/utils/shallowCompare.ts +35 -0
  111. package/src/ColorPicker/ColorPickerLocator.ts +124 -0
  112. package/src/ColorPicker/README.md +420 -0
  113. package/src/ColorPicker/index.tsx +609 -0
  114. package/src/ColorPicker/props.ts +293 -0
  115. package/src/ColorPicker/styles.ts +131 -0
  116. package/src/ColorPicker/theme.ts +80 -0
  117. package/src/ColorPreset/ColorPresetLocator.ts +29 -0
  118. package/src/ColorPreset/README.md +121 -0
  119. package/src/ColorPreset/index.tsx +328 -0
  120. package/src/ColorPreset/props.ts +162 -0
  121. package/src/ColorPreset/styles.ts +107 -0
  122. package/src/ColorPreset/theme.ts +58 -0
  123. package/src/index.ts +34 -0
  124. package/tsconfig.build.json +36 -0
  125. package/tsconfig.build.tsbuildinfo +1 -0
  126. package/types/ColorContrast/ColorContrastLocator.d.ts +592 -0
  127. package/types/ColorContrast/ColorContrastLocator.d.ts.map +1 -0
  128. package/types/ColorContrast/index.d.ts +61 -0
  129. package/types/ColorContrast/index.d.ts.map +1 -0
  130. package/types/ColorContrast/props.d.ts +62 -0
  131. package/types/ColorContrast/props.d.ts.map +1 -0
  132. package/types/ColorContrast/styles.d.ts +76 -0
  133. package/types/ColorContrast/styles.d.ts.map +1 -0
  134. package/types/ColorContrast/theme.d.ts +10 -0
  135. package/types/ColorContrast/theme.d.ts.map +1 -0
  136. package/types/ColorIndicator/ColorIndicatorLocator.d.ts +577 -0
  137. package/types/ColorIndicator/ColorIndicatorLocator.d.ts.map +1 -0
  138. package/types/ColorIndicator/index.d.ts +35 -0
  139. package/types/ColorIndicator/index.d.ts.map +1 -0
  140. package/types/ColorIndicator/props.d.ts +25 -0
  141. package/types/ColorIndicator/props.d.ts.map +1 -0
  142. package/types/ColorIndicator/styles.d.ts +15 -0
  143. package/types/ColorIndicator/styles.d.ts.map +1 -0
  144. package/types/ColorIndicator/theme.d.ts +11 -0
  145. package/types/ColorIndicator/theme.d.ts.map +1 -0
  146. package/types/ColorMixer/ColorMixerLocator.d.ts +566 -0
  147. package/types/ColorMixer/ColorMixerLocator.d.ts.map +1 -0
  148. package/types/ColorMixer/ColorPalette/index.d.ts +70 -0
  149. package/types/ColorMixer/ColorPalette/index.d.ts.map +1 -0
  150. package/types/ColorMixer/ColorPalette/props.d.ts +29 -0
  151. package/types/ColorMixer/ColorPalette/props.d.ts.map +1 -0
  152. package/types/ColorMixer/ColorPalette/styles.d.ts +15 -0
  153. package/types/ColorMixer/ColorPalette/styles.d.ts.map +1 -0
  154. package/types/ColorMixer/ColorPalette/theme.d.ts +10 -0
  155. package/types/ColorMixer/ColorPalette/theme.d.ts.map +1 -0
  156. package/types/ColorMixer/RGBAInput/index.d.ts +51 -0
  157. package/types/ColorMixer/RGBAInput/index.d.ts.map +1 -0
  158. package/types/ColorMixer/RGBAInput/props.d.ts +28 -0
  159. package/types/ColorMixer/RGBAInput/props.d.ts.map +1 -0
  160. package/types/ColorMixer/RGBAInput/styles.d.ts +15 -0
  161. package/types/ColorMixer/RGBAInput/styles.d.ts.map +1 -0
  162. package/types/ColorMixer/RGBAInput/theme.d.ts +10 -0
  163. package/types/ColorMixer/RGBAInput/theme.d.ts.map +1 -0
  164. package/types/ColorMixer/Slider/index.d.ts +64 -0
  165. package/types/ColorMixer/Slider/index.d.ts.map +1 -0
  166. package/types/ColorMixer/Slider/props.d.ts +26 -0
  167. package/types/ColorMixer/Slider/props.d.ts.map +1 -0
  168. package/types/ColorMixer/Slider/styles.d.ts +15 -0
  169. package/types/ColorMixer/Slider/styles.d.ts.map +1 -0
  170. package/types/ColorMixer/Slider/theme.d.ts +10 -0
  171. package/types/ColorMixer/Slider/theme.d.ts.map +1 -0
  172. package/types/ColorMixer/index.d.ts +59 -0
  173. package/types/ColorMixer/index.d.ts.map +1 -0
  174. package/types/ColorMixer/props.d.ts +91 -0
  175. package/types/ColorMixer/props.d.ts.map +1 -0
  176. package/types/ColorMixer/styles.d.ts +14 -0
  177. package/types/ColorMixer/styles.d.ts.map +1 -0
  178. package/types/ColorMixer/utils/shallowCompare.d.ts +3 -0
  179. package/types/ColorMixer/utils/shallowCompare.d.ts.map +1 -0
  180. package/types/ColorPicker/ColorPickerLocator.d.ts +4113 -0
  181. package/types/ColorPicker/ColorPickerLocator.d.ts.map +1 -0
  182. package/types/ColorPicker/index.d.ts +158 -0
  183. package/types/ColorPicker/index.d.ts.map +1 -0
  184. package/types/ColorPicker/props.d.ts +166 -0
  185. package/types/ColorPicker/props.d.ts.map +1 -0
  186. package/types/ColorPicker/styles.d.ts +17 -0
  187. package/types/ColorPicker/styles.d.ts.map +1 -0
  188. package/types/ColorPicker/theme.d.ts +10 -0
  189. package/types/ColorPicker/theme.d.ts.map +1 -0
  190. package/types/ColorPreset/ColorPresetLocator.d.ts +566 -0
  191. package/types/ColorPreset/ColorPresetLocator.d.ts.map +1 -0
  192. package/types/ColorPreset/index.d.ts +100 -0
  193. package/types/ColorPreset/index.d.ts.map +1 -0
  194. package/types/ColorPreset/props.d.ts +87 -0
  195. package/types/ColorPreset/props.d.ts.map +1 -0
  196. package/types/ColorPreset/styles.d.ts +77 -0
  197. package/types/ColorPreset/styles.d.ts.map +1 -0
  198. package/types/ColorPreset/theme.d.ts +10 -0
  199. package/types/ColorPreset/theme.d.ts.map +1 -0
  200. package/types/index.d.ts +11 -0
  201. package/types/index.d.ts.map +1 -0
@@ -0,0 +1,328 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ /** @jsx jsx */
26
+ import { Component, SyntheticEvent } from 'react'
27
+
28
+ import { withStyle, jsx } from '@instructure/emotion'
29
+ import { passthroughProps } from '@instructure/ui-react-utils'
30
+ import { testable } from '@instructure/ui-testable'
31
+ import { colorToHex8, colorToRGB } from '@instructure/ui-color-utils'
32
+
33
+ import { IconButton, Button } from '@instructure/ui-buttons'
34
+ import { View } from '@instructure/ui-view'
35
+ import { Tooltip } from '@instructure/ui-tooltip'
36
+ import { Popover } from '@instructure/ui-popover'
37
+ import { Text } from '@instructure/ui-text'
38
+ import { Drilldown } from '@instructure/ui-drilldown'
39
+ import type { DrilldownOnSelectArgs } from '@instructure/ui-drilldown'
40
+ import { IconAddLine, IconCheckDarkSolid } from '@instructure/ui-icons'
41
+
42
+ import { ColorIndicator } from '../ColorIndicator'
43
+ import { ColorMixer } from '../ColorMixer'
44
+ import { ColorContrast } from '../ColorContrast'
45
+
46
+ import generateStyle from './styles'
47
+ import generateComponentTheme from './theme'
48
+
49
+ import type { ColorPresetProps, ColorPresetState } from './props'
50
+ import { propTypes, allowedProps } from './props'
51
+
52
+ /**
53
+ ---
54
+ category: components
55
+ ---
56
+ @tsProps
57
+ **/
58
+ @withStyle(generateStyle, generateComponentTheme)
59
+ @testable()
60
+ class ColorPreset extends Component<ColorPresetProps, ColorPresetState> {
61
+ static propTypes = propTypes
62
+ static allowedProps = allowedProps
63
+ static readonly componentId = 'ColorPreset'
64
+
65
+ static defaultProps = {
66
+ disabled: false
67
+ }
68
+
69
+ constructor(props: ColorPresetProps) {
70
+ super(props)
71
+ this.state = {
72
+ openEditor: false,
73
+ openAddNew: false,
74
+ newColor: { r: 51, g: 99, b: 42, a: 1 }
75
+ }
76
+ }
77
+
78
+ ref: HTMLDivElement | null = null
79
+
80
+ handleRef = (el: HTMLDivElement | null) => {
81
+ const { elementRef } = this.props
82
+
83
+ this.ref = el
84
+
85
+ if (typeof elementRef === 'function') {
86
+ elementRef(el)
87
+ }
88
+ }
89
+
90
+ componentDidMount() {
91
+ this.props.makeStyles?.()
92
+ }
93
+
94
+ componentDidUpdate() {
95
+ this.props.makeStyles?.()
96
+ }
97
+
98
+ onMenuItemSelected =
99
+ (color: string) =>
100
+ (_e: SyntheticEvent<Element, Event>, args: DrilldownOnSelectArgs) => {
101
+ if (args.value === 'select') {
102
+ this.props.onSelect(color)
103
+ }
104
+ if (args.value === 'remove') {
105
+ this.props?.colorMixerSettings?.onPresetChange(
106
+ this.props.colors.filter((clr) => clr !== color)
107
+ )
108
+ }
109
+ }
110
+
111
+ renderAddNewPresetButton = () => (
112
+ <Popover
113
+ renderTrigger={
114
+ <div css={this.props?.styles?.addNewPresetButton}>
115
+ <IconButton
116
+ disabled={this.props.disabled}
117
+ screenReaderLabel={
118
+ this.props.colorMixerSettings!.addNewPresetButtonScreenReaderLabel
119
+ }
120
+ >
121
+ <IconAddLine />
122
+ </IconButton>
123
+ </div>
124
+ }
125
+ isShowingContent={this.state.openAddNew}
126
+ onShowContent={() => {
127
+ if (this.props.disabled) return
128
+ this.setState({ openAddNew: true })
129
+ }}
130
+ onHideContent={() => {
131
+ this.setState({ openAddNew: false })
132
+ }}
133
+ on="click"
134
+ screenReaderLabel={this.props.popoverScreenReaderLabel}
135
+ shouldContainFocus
136
+ shouldReturnFocus
137
+ shouldCloseOnDocumentClick
138
+ offsetY={16}
139
+ mountNode={() => document.getElementById('main')}
140
+ >
141
+ <div css={this.props.styles?.popoverContent}>
142
+ <ColorMixer
143
+ value={colorToHex8(this.state.newColor)}
144
+ onChange={(newColor: string) =>
145
+ this.setState({ newColor: colorToRGB(newColor) })
146
+ }
147
+ withAlpha={this.props?.colorMixerSettings?.colorMixer?.withAlpha}
148
+ rgbRedInputScreenReaderLabel={
149
+ this.props.colorMixerSettings!.colorMixer
150
+ .rgbRedInputScreenReaderLabel
151
+ }
152
+ rgbGreenInputScreenReaderLabel={
153
+ this.props.colorMixerSettings!.colorMixer
154
+ .rgbGreenInputScreenReaderLabel
155
+ }
156
+ rgbBlueInputScreenReaderLabel={
157
+ this.props.colorMixerSettings!.colorMixer
158
+ .rgbBlueInputScreenReaderLabel
159
+ }
160
+ rgbAlphaInputScreenReaderLabel={
161
+ this.props.colorMixerSettings!.colorMixer
162
+ .rgbAlphaInputScreenReaderLabel
163
+ }
164
+ colorSliderNavigationExplanationScreenReaderLabel={
165
+ this.props.colorMixerSettings!.colorMixer
166
+ .colorSliderNavigationExplanationScreenReaderLabel
167
+ }
168
+ alphaSliderNavigationExplanationScreenReaderLabel={
169
+ this.props.colorMixerSettings!.colorMixer
170
+ .alphaSliderNavigationExplanationScreenReaderLabel
171
+ }
172
+ colorPaletteNavigationExplanationScreenReaderLabel={
173
+ this.props.colorMixerSettings!.colorMixer
174
+ .colorPaletteNavigationExplanationScreenReaderLabel
175
+ }
176
+ />
177
+ {this.props?.colorMixerSettings?.colorContrast && (
178
+ <div css={this.props.styles?.popoverContrastBlock}>
179
+ <ColorContrast
180
+ firstColor={
181
+ this.props.colorMixerSettings.colorContrast.firstColor
182
+ }
183
+ secondColor={colorToHex8(this.state.newColor)}
184
+ label={this.props.colorMixerSettings.colorContrast.label}
185
+ successLabel={
186
+ this.props.colorMixerSettings.colorContrast.successLabel
187
+ }
188
+ failureLabel={
189
+ this.props.colorMixerSettings.colorContrast.failureLabel
190
+ }
191
+ normalTextLabel={
192
+ this.props.colorMixerSettings.colorContrast.normalTextLabel
193
+ }
194
+ largeTextLabel={
195
+ this.props.colorMixerSettings.colorContrast.largeTextLabel
196
+ }
197
+ graphicsTextLabel={
198
+ this.props.colorMixerSettings.colorContrast.graphicsTextLabel
199
+ }
200
+ firstColorLabel={
201
+ this.props.colorMixerSettings.colorContrast.firstColorLabel
202
+ }
203
+ secondColorLabel={
204
+ this.props.colorMixerSettings.colorContrast.secondColorLabel
205
+ }
206
+ />
207
+ </div>
208
+ )}
209
+ </div>
210
+ <div css={this.props.styles?.popoverFooter}>
211
+ <Button
212
+ onClick={() => {
213
+ this.props?.colorMixerSettings?.onPresetChange([
214
+ colorToHex8(this.state.newColor),
215
+ ...this.props.colors
216
+ ])
217
+ this.setState({ openAddNew: false })
218
+ }}
219
+ color="primary"
220
+ margin="0 xx-small 0 xx-small"
221
+ >
222
+ Add
223
+ </Button>
224
+ <Button
225
+ onClick={() => this.setState({ openAddNew: false })}
226
+ color="secondary"
227
+ margin="0 xx-small 0 xx-small"
228
+ >
229
+ Close
230
+ </Button>
231
+ </div>
232
+ </Popover>
233
+ )
234
+ renderColorIndicator = (color: string, selectOnClick?: boolean) => (
235
+ <Tooltip renderTip={<div>{color}</div>}>
236
+ <View
237
+ disabled={this.props.disabled}
238
+ position="relative"
239
+ width="2.375rem"
240
+ height="2.375rem"
241
+ background="transparent"
242
+ margin="xx-small"
243
+ display="inline-block"
244
+ borderRadius="medium"
245
+ borderWidth="0"
246
+ padding="0"
247
+ as="button"
248
+ {...(selectOnClick
249
+ ? { onClick: () => this.props.onSelect(color) }
250
+ : {})}
251
+ {...(this.props.selected === color ? { 'aria-label': 'selected' } : {})}
252
+ role="presentation"
253
+ >
254
+ <div>
255
+ <ColorIndicator color={color} shape="rectangle" />
256
+ {this.props.selected === color && (
257
+ <div css={this.props?.styles?.selectedIndicator}>
258
+ <IconCheckDarkSolid
259
+ themeOverride={{ sizeXSmall: '0.8rem' }}
260
+ size="x-small"
261
+ />
262
+ </div>
263
+ )}
264
+ </div>
265
+ </View>
266
+ </Tooltip>
267
+ )
268
+ renderSettingsMenu = (color: string, index: number) => (
269
+ <Drilldown
270
+ onSelect={this.onMenuItemSelected(color)}
271
+ trigger={this.renderColorIndicator(color)}
272
+ key={`color-preset-color-${index}`}
273
+ rootPageId="root"
274
+ width="10rem"
275
+ offsetY="15rem"
276
+ >
277
+ <Drilldown.Page withoutHeaderSeparator id="root" renderTitle={color}>
278
+ <Drilldown.Option value="select" id="select">
279
+ Select
280
+ </Drilldown.Option>
281
+ <Drilldown.Option value="remove" id="remove">
282
+ Remove
283
+ </Drilldown.Option>
284
+ </Drilldown.Page>
285
+ </Drilldown>
286
+ )
287
+
288
+ render() {
289
+ const {
290
+ disabled,
291
+ onSelect,
292
+ selected,
293
+ styles,
294
+ label,
295
+ colorMixerSettings,
296
+ colors,
297
+ elementRef,
298
+ ...props
299
+ } = this.props
300
+ return (
301
+ <div
302
+ {...passthroughProps(props)}
303
+ ref={this.handleRef}
304
+ css={styles?.colorPreset}
305
+ >
306
+ {label && (
307
+ <div css={styles?.label}>
308
+ <Text weight="bold">{label}</Text>
309
+ </div>
310
+ )}
311
+ {typeof colorMixerSettings?.onPresetChange === 'function' &&
312
+ this.renderAddNewPresetButton()}
313
+ {colors.map((color, index) =>
314
+ typeof colorMixerSettings?.onPresetChange === 'function' ? (
315
+ this.renderSettingsMenu(color, index)
316
+ ) : (
317
+ <div key={`color-preset-color-${index}`}>
318
+ {this.renderColorIndicator(color, true)}
319
+ </div>
320
+ )
321
+ )}
322
+ </div>
323
+ )
324
+ }
325
+ }
326
+
327
+ export { ColorPreset }
328
+ export default ColorPreset
@@ -0,0 +1,162 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import PropTypes from 'prop-types'
26
+
27
+ import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
28
+ import type {
29
+ OtherHTMLAttributes,
30
+ PropValidators,
31
+ ColorPresetTheme
32
+ } from '@instructure/shared-types'
33
+ import type { RGBAType } from '../ColorMixer/props'
34
+
35
+ type ContrastStrength = 'min' | 'mid' | 'max'
36
+ type MessageType = Array<{
37
+ type: 'success' | 'hint' | 'error' | 'screenreader-only'
38
+ text: string
39
+ }>
40
+
41
+ type ColorPresetOwnProps = {
42
+ /**
43
+ * Array of HEX strings which are the preset colors. Supports 8 character HEX (with alpha)
44
+ */
45
+ colors: Array<string>
46
+ /**
47
+ * Makes the component uninteractable
48
+ */
49
+ disabled?: boolean
50
+ /**
51
+ * Provides a reference to the component's underlying html element.
52
+ */
53
+ elementRef?: (element: Element | null) => void
54
+ /**
55
+ * Label text of the component
56
+ */
57
+ label?: string
58
+
59
+ /**
60
+ * If set, a `plus` button will appear for the preset. Those components whose corresponding keys aren't provided (`colorMixer` or `colorContrast`)
61
+ * will not be rendered.
62
+ * The `onPresetChange` function gets called when a color gets added or removed from the preset list.
63
+ * It will be called with the new list of colors
64
+ */
65
+ colorMixerSettings?: {
66
+ /**
67
+ * screenReaderLabel for the add new preset button
68
+ */
69
+ addNewPresetButtonScreenReaderLabel: string
70
+ maxHeight: string
71
+ onPresetChange: (colors: ColorPresetOwnProps['colors']) => void
72
+ colorMixer: {
73
+ withAlpha: boolean
74
+ rgbRedInputScreenReaderLabel: string
75
+ rgbGreenInputScreenReaderLabel: string
76
+ rgbBlueInputScreenReaderLabel: string
77
+ rgbAlphaInputScreenReaderLabel: string
78
+ colorSliderNavigationExplanationScreenReaderLabel: string
79
+ alphaSliderNavigationExplanationScreenReaderLabel: string
80
+ colorPaletteNavigationExplanationScreenReaderLabel: string
81
+ }
82
+ colorContrast?: {
83
+ firstColor: string
84
+ label: string
85
+ successLabel: string
86
+ failureLabel: string
87
+ normalTextLabel: string
88
+ largeTextLabel: string
89
+ graphicsTextLabel: string
90
+ firstColorLabel: string
91
+ secondColorLabel: string
92
+ }
93
+ }
94
+ /**
95
+ * The function gets called when a color gets selected
96
+ */
97
+ onSelect: (selected: string) => void
98
+ /**
99
+ * Sets the ScreenReaderLabel for the popover
100
+ */
101
+ popoverScreenReaderLabel?: string
102
+ /**
103
+ * The currently selected HEX string
104
+ */
105
+ selected: string | null
106
+ }
107
+
108
+ type ColorPresetState = {
109
+ openEditor: boolean | string
110
+ openAddNew: boolean
111
+ newColor: RGBAType
112
+ }
113
+
114
+ type PropKeys = keyof ColorPresetOwnProps
115
+
116
+ type AllowedPropKeys = Readonly<Array<PropKeys>>
117
+
118
+ type ColorPresetProps = ColorPresetOwnProps &
119
+ WithStyleProps<ColorPresetTheme, ColorPresetStyle> &
120
+ OtherHTMLAttributes<ColorPresetOwnProps>
121
+
122
+ type ColorPresetStyle = ComponentStyle<
123
+ | 'colorPreset'
124
+ | 'addNewPresetButton'
125
+ | 'selectedIndicator'
126
+ | 'popoverContent'
127
+ | 'popoverDivider'
128
+ | 'popoverFooter'
129
+ | 'label'
130
+ | 'popoverContrastBlock'
131
+ >
132
+
133
+ const propTypes: PropValidators<PropKeys> = {
134
+ colors: PropTypes.array.isRequired,
135
+ disabled: PropTypes.bool,
136
+ elementRef: PropTypes.func,
137
+ label: PropTypes.string,
138
+ colorMixerSettings: PropTypes.object,
139
+ onSelect: PropTypes.func.isRequired,
140
+ popoverScreenReaderLabel: PropTypes.string,
141
+ selected: PropTypes.string.isRequired
142
+ }
143
+
144
+ const allowedProps: AllowedPropKeys = [
145
+ 'colors',
146
+ 'disabled',
147
+ 'elementRef',
148
+ 'label',
149
+ 'colorMixerSettings',
150
+ 'onSelect',
151
+ 'popoverScreenReaderLabel',
152
+ 'selected'
153
+ ]
154
+
155
+ export type {
156
+ ColorPresetProps,
157
+ ColorPresetStyle,
158
+ ColorPresetState,
159
+ ContrastStrength,
160
+ MessageType
161
+ }
162
+ export { propTypes, allowedProps }
@@ -0,0 +1,107 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import type { ColorPresetTheme } from '@instructure/shared-types'
26
+ import type { ColorPresetProps } from './props'
27
+ /**
28
+ * ---
29
+ * private: true
30
+ * ---
31
+ * Generates the style object from the theme and provided additional information
32
+ * @param {Object} componentTheme The theme variable object.
33
+ * @param {Object} props the props of the component, the style is applied to
34
+ * @param {Object} state the state of the component, the style is applied to
35
+ * @return {Object} The final style object, which will be used in the component
36
+ */
37
+ const generateStyle = (
38
+ componentTheme: ColorPresetTheme,
39
+ props: ColorPresetProps
40
+ ) => {
41
+ const { colorMixerSettings } = props
42
+ return {
43
+ colorPreset: {
44
+ label: 'colorPreset',
45
+ display: 'flex',
46
+ flexWrap: 'wrap',
47
+ width: '17rem'
48
+ },
49
+ addNewPresetButton: {
50
+ label: 'colorPreset__addNewPresetButton',
51
+ width: '2.375rem',
52
+ height: '2.375rem',
53
+ margin: componentTheme.xxSmallSpacing
54
+ },
55
+ selectedIndicator: {
56
+ label: 'colorPreset__selectedIndicator',
57
+ width: '1.25rem',
58
+ height: '1.25rem',
59
+ borderStyle: 'solid',
60
+ borderColor: componentTheme.selectedIndicatorBorderColor,
61
+ borderWidth: componentTheme.smallBorder,
62
+ borderRadius: '1.25rem',
63
+ boxSizing: 'border-box',
64
+ position: 'relative',
65
+ insetInlineStart: '1.5rem',
66
+ bottom: '2.75rem',
67
+ backgroundColor: componentTheme.selectedIndicatorBackgroundColor,
68
+ display: 'flex',
69
+ alignItems: 'center',
70
+ justifyContent: 'center'
71
+ },
72
+ popoverContent: {
73
+ label: 'colorPreset__popoverContent',
74
+ padding: componentTheme.smallSpacing,
75
+ maxHeight: colorMixerSettings?.maxHeight || '100vh',
76
+ overflow: 'scroll'
77
+ },
78
+ popoverDivider: {
79
+ label: 'colorPreset__popoverDivider',
80
+ borderTop: 'solid',
81
+ borderWidth: componentTheme.smallBorder,
82
+ borderColor: componentTheme.popoverDividerColor,
83
+ margin: `${componentTheme.smallSpacing} 0 ${componentTheme.smallSpacing} 0`
84
+ },
85
+ popoverContrastBlock: {
86
+ label: 'colorPreset__popoverContrastBlock',
87
+ borderTop: 'solid',
88
+ borderWidth: componentTheme.smallBorder,
89
+ borderColor: componentTheme.popoverDividerColor,
90
+ margin: `${componentTheme.smallSpacing} 0 ${componentTheme.smallSpacing} 0`
91
+ },
92
+ popoverFooter: {
93
+ label: 'colorPreset__popoverFooter',
94
+ backgroundColor: componentTheme.popoverFooterColor,
95
+ display: 'flex',
96
+ flexDirection: 'row-reverse',
97
+ padding: componentTheme.smallSpacing
98
+ },
99
+ label: {
100
+ label: 'colorPreset__label',
101
+ width: '100%',
102
+ margin: componentTheme.xxSmallSpacing
103
+ }
104
+ }
105
+ }
106
+
107
+ export default generateStyle
@@ -0,0 +1,58 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import type { Theme } from '@instructure/ui-themes'
26
+ import { ColorPresetTheme } from '@instructure/shared-types'
27
+
28
+ /**
29
+ * Generates the theme object for the component from the theme and provided additional information
30
+ * @param {Object} theme The actual theme object.
31
+ * @return {Object} The final theme object with the overrides and component variables
32
+ */
33
+ const generateComponentTheme = (theme: Theme): ColorPresetTheme => {
34
+ const { colors, borders, spacing } = theme
35
+
36
+ const componentVariables = {
37
+ xxSmallSpacing: spacing?.xxSmall,
38
+ smallSpacing: spacing?.small,
39
+ selectedIndicatorBackgroundColor: colors.white,
40
+ selectedIndicatorBorderColor: colors.licorice,
41
+ popoverDividerColor: colors?.tiara,
42
+ smallBorder: borders?.widthSmall,
43
+ popoverFooterColor: colors?.porcelain,
44
+ checkerboardBackgroundImage: `linear-gradient(45deg, ${colors.tiara} 25%, transparent 25%),
45
+ linear-gradient(-45deg, ${colors.tiara} 25%, transparent 25%),
46
+ linear-gradient(45deg, transparent 75%, ${colors.tiara} 75%),
47
+ linear-gradient(-45deg, transparent 75%, ${colors.tiara} 75%)`,
48
+ checkerboardBackgroundSize: '.5rem .5rem',
49
+ checkerboardBackgroundPosition:
50
+ '0 0, 0 .25rem, .25rem -0.25rem, -0.25rem 0px'
51
+ }
52
+
53
+ return {
54
+ ...componentVariables
55
+ }
56
+ }
57
+
58
+ export default generateComponentTheme
package/src/index.ts ADDED
@@ -0,0 +1,34 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+ export { ColorPicker } from './ColorPicker'
25
+ export { ColorMixer } from './ColorMixer'
26
+ export { ColorPreset } from './ColorPreset'
27
+ export { ColorContrast } from './ColorContrast'
28
+ export { ColorIndicator } from './ColorIndicator'
29
+
30
+ export type { ColorPickerProps } from './ColorPicker/props'
31
+ export type { ColorMixerProps } from './ColorMixer/props'
32
+ export type { ColorPresetProps } from './ColorPreset/props'
33
+ export type { ColorContrastProps } from './ColorContrast/props'
34
+ export type { ColorIndicatorProps } from './ColorIndicator/props'