@instructure/ui-checkbox 10.4.2-snapshot-10 → 10.4.2-snapshot-11

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 (52) hide show
  1. package/CHANGELOG.md +5 -2
  2. package/es/Checkbox/CheckboxFacade/props.js +2 -1
  3. package/es/Checkbox/CheckboxFacade/styles.js +3 -2
  4. package/es/Checkbox/CheckboxFacade/theme.js +2 -1
  5. package/es/Checkbox/ToggleFacade/props.js +2 -1
  6. package/es/Checkbox/ToggleFacade/styles.js +3 -2
  7. package/es/Checkbox/ToggleFacade/theme.js +2 -1
  8. package/es/Checkbox/index.js +43 -20
  9. package/es/Checkbox/props.js +2 -1
  10. package/es/Checkbox/styles.js +10 -1
  11. package/es/Checkbox/theme.js +44 -0
  12. package/lib/Checkbox/CheckboxFacade/props.js +2 -1
  13. package/lib/Checkbox/CheckboxFacade/styles.js +3 -2
  14. package/lib/Checkbox/CheckboxFacade/theme.js +2 -1
  15. package/lib/Checkbox/ToggleFacade/props.js +2 -1
  16. package/lib/Checkbox/ToggleFacade/styles.js +3 -2
  17. package/lib/Checkbox/ToggleFacade/theme.js +2 -1
  18. package/lib/Checkbox/index.js +43 -20
  19. package/lib/Checkbox/props.js +2 -1
  20. package/lib/Checkbox/styles.js +10 -1
  21. package/lib/Checkbox/theme.js +50 -0
  22. package/package.json +19 -19
  23. package/src/Checkbox/CheckboxFacade/props.ts +6 -1
  24. package/src/Checkbox/CheckboxFacade/styles.ts +2 -2
  25. package/src/Checkbox/CheckboxFacade/theme.ts +1 -0
  26. package/src/Checkbox/ToggleFacade/props.ts +6 -1
  27. package/src/Checkbox/ToggleFacade/styles.ts +2 -3
  28. package/src/Checkbox/ToggleFacade/theme.ts +1 -0
  29. package/src/Checkbox/index.tsx +37 -5
  30. package/src/Checkbox/props.ts +10 -2
  31. package/src/Checkbox/styles.ts +10 -1
  32. package/src/Checkbox/theme.ts +46 -0
  33. package/tsconfig.build.tsbuildinfo +1 -1
  34. package/types/Checkbox/CheckboxFacade/index.d.ts +2 -0
  35. package/types/Checkbox/CheckboxFacade/index.d.ts.map +1 -1
  36. package/types/Checkbox/CheckboxFacade/props.d.ts +4 -0
  37. package/types/Checkbox/CheckboxFacade/props.d.ts.map +1 -1
  38. package/types/Checkbox/CheckboxFacade/theme.d.ts.map +1 -1
  39. package/types/Checkbox/ToggleFacade/index.d.ts +2 -0
  40. package/types/Checkbox/ToggleFacade/index.d.ts.map +1 -1
  41. package/types/Checkbox/ToggleFacade/props.d.ts +4 -0
  42. package/types/Checkbox/ToggleFacade/props.d.ts.map +1 -1
  43. package/types/Checkbox/ToggleFacade/styles.d.ts.map +1 -1
  44. package/types/Checkbox/ToggleFacade/theme.d.ts.map +1 -1
  45. package/types/Checkbox/index.d.ts +4 -0
  46. package/types/Checkbox/index.d.ts.map +1 -1
  47. package/types/Checkbox/props.d.ts +2 -1
  48. package/types/Checkbox/props.d.ts.map +1 -1
  49. package/types/Checkbox/styles.d.ts +1 -1
  50. package/types/Checkbox/styles.d.ts.map +1 -1
  51. package/types/Checkbox/theme.d.ts +9 -0
  52. package/types/Checkbox/theme.d.ts.map +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instructure/ui-checkbox",
3
- "version": "10.4.2-snapshot-10",
3
+ "version": "10.4.2-snapshot-11",
4
4
  "description": " styled HTML input type='checkbox' component.",
5
5
  "author": "Instructure, Inc. Engineering and Product Design",
6
6
  "module": "./es/index.js",
@@ -24,28 +24,28 @@
24
24
  "license": "MIT",
25
25
  "dependencies": {
26
26
  "@babel/runtime": "^7.25.6",
27
- "@instructure/console": "10.4.2-snapshot-10",
28
- "@instructure/emotion": "10.4.2-snapshot-10",
29
- "@instructure/shared-types": "10.4.2-snapshot-10",
30
- "@instructure/ui-dom-utils": "10.4.2-snapshot-10",
31
- "@instructure/ui-form-field": "10.4.2-snapshot-10",
32
- "@instructure/ui-icons": "10.4.2-snapshot-10",
33
- "@instructure/ui-prop-types": "10.4.2-snapshot-10",
34
- "@instructure/ui-react-utils": "10.4.2-snapshot-10",
35
- "@instructure/ui-svg-images": "10.4.2-snapshot-10",
36
- "@instructure/ui-testable": "10.4.2-snapshot-10",
37
- "@instructure/ui-utils": "10.4.2-snapshot-10",
38
- "@instructure/ui-view": "10.4.2-snapshot-10",
39
- "@instructure/uid": "10.4.2-snapshot-10",
27
+ "@instructure/console": "10.4.2-snapshot-11",
28
+ "@instructure/emotion": "10.4.2-snapshot-11",
29
+ "@instructure/shared-types": "10.4.2-snapshot-11",
30
+ "@instructure/ui-dom-utils": "10.4.2-snapshot-11",
31
+ "@instructure/ui-form-field": "10.4.2-snapshot-11",
32
+ "@instructure/ui-icons": "10.4.2-snapshot-11",
33
+ "@instructure/ui-prop-types": "10.4.2-snapshot-11",
34
+ "@instructure/ui-react-utils": "10.4.2-snapshot-11",
35
+ "@instructure/ui-svg-images": "10.4.2-snapshot-11",
36
+ "@instructure/ui-testable": "10.4.2-snapshot-11",
37
+ "@instructure/ui-utils": "10.4.2-snapshot-11",
38
+ "@instructure/ui-view": "10.4.2-snapshot-11",
39
+ "@instructure/uid": "10.4.2-snapshot-11",
40
40
  "keycode": "^2",
41
41
  "prop-types": "^15.8.1"
42
42
  },
43
43
  "devDependencies": {
44
- "@instructure/ui-axe-check": "10.4.2-snapshot-10",
45
- "@instructure/ui-babel-preset": "10.4.2-snapshot-10",
46
- "@instructure/ui-color-utils": "10.4.2-snapshot-10",
47
- "@instructure/ui-test-utils": "10.4.2-snapshot-10",
48
- "@instructure/ui-themes": "10.4.2-snapshot-10",
44
+ "@instructure/ui-axe-check": "10.4.2-snapshot-11",
45
+ "@instructure/ui-babel-preset": "10.4.2-snapshot-11",
46
+ "@instructure/ui-color-utils": "10.4.2-snapshot-11",
47
+ "@instructure/ui-test-utils": "10.4.2-snapshot-11",
48
+ "@instructure/ui-themes": "10.4.2-snapshot-11",
49
49
  "@testing-library/jest-dom": "^6.4.6",
50
50
  "@testing-library/react": "^16.0.1",
51
51
  "@testing-library/user-event": "^14.5.2",
@@ -40,6 +40,10 @@ type CheckboxFacadeOwnProps = {
40
40
  * Visual state showing that child checkboxes are a combination of checked and unchecked
41
41
  */
42
42
  indeterminate?: boolean
43
+ /**
44
+ * Indicate if the parent component (`Checkbox`) is invalid to set the style accordingly.
45
+ */
46
+ invalid?: boolean
43
47
  }
44
48
 
45
49
  type PropKeys = keyof CheckboxFacadeOwnProps
@@ -57,7 +61,8 @@ const propTypes: PropValidators<PropKeys> = {
57
61
  focused: PropTypes.bool,
58
62
  hovered: PropTypes.bool,
59
63
  size: PropTypes.oneOf(['small', 'medium', 'large']),
60
- indeterminate: PropTypes.bool
64
+ indeterminate: PropTypes.bool,
65
+ invalid: PropTypes.bool
61
66
  }
62
67
 
63
68
  const allowedProps: AllowedPropKeys = [
@@ -39,7 +39,7 @@ const generateStyle = (
39
39
  componentTheme: CheckboxFacadeTheme,
40
40
  props: CheckboxFacadeProps
41
41
  ): CheckboxFacadeStyle => {
42
- const { size, checked, focused, hovered, indeterminate } = props
42
+ const { size, checked, focused, hovered, indeterminate, invalid } = props
43
43
 
44
44
  const isChecked = checked || indeterminate
45
45
 
@@ -87,7 +87,7 @@ const generateStyle = (
87
87
  boxSizing: 'border-box',
88
88
  flexShrink: 0,
89
89
  transition: 'all 0.2s',
90
- border: `${componentTheme.borderWidth} solid ${componentTheme.borderColor}`,
90
+ border: `${componentTheme.borderWidth} solid ${invalid ? componentTheme.errorBorderColor : componentTheme.borderColor}`,
91
91
  borderRadius: componentTheme.borderRadius,
92
92
  marginInlineEnd: componentTheme.marginRight,
93
93
  marginInlineStart: '0',
@@ -48,6 +48,7 @@ const generateComponentTheme = (theme: Theme): CheckboxFacadeTheme => {
48
48
  color: colors?.contrasts?.white1010,
49
49
  borderWidth: borders?.widthSmall,
50
50
  borderColor: colors?.contrasts?.grey1214,
51
+ errorBorderColor: colors?.ui?.textError,
51
52
  borderRadius: borders?.radiusMedium,
52
53
  background: colors?.contrasts?.white1010,
53
54
  marginRight: spacing?.xSmall,
@@ -39,6 +39,10 @@ type ToggleFacadeOwnProps = {
39
39
  focused?: boolean
40
40
  size?: 'small' | 'medium' | 'large'
41
41
  labelPlacement?: 'top' | 'start' | 'end'
42
+ /**
43
+ * Indicate if the parent component (`Checkbox`) is invalid to set the style accordingly.
44
+ */
45
+ invalid?: boolean
42
46
  }
43
47
 
44
48
  type PropKeys = keyof ToggleFacadeOwnProps
@@ -59,7 +63,8 @@ const propTypes: PropValidators<PropKeys> = {
59
63
  readOnly: PropTypes.bool,
60
64
  focused: PropTypes.bool,
61
65
  size: PropTypes.oneOf(['small', 'medium', 'large']),
62
- labelPlacement: PropTypes.oneOf(['top', 'start', 'end'])
66
+ labelPlacement: PropTypes.oneOf(['top', 'start', 'end']),
67
+ invalid: PropTypes.bool
63
68
  }
64
69
 
65
70
  const allowedProps: AllowedPropKeys = [
@@ -39,7 +39,7 @@ const generateStyle = (
39
39
  componentTheme: ToggleFacadeTheme,
40
40
  props: ToggleFacadeProps
41
41
  ): ToggleFacadeStyle => {
42
- const { size, checked, focused, labelPlacement } = props
42
+ const { size, checked, focused, labelPlacement, invalid } = props
43
43
 
44
44
  const labelPlacementVariants = {
45
45
  start: {
@@ -81,7 +81,6 @@ const generateStyle = (
81
81
  alignItems: 'center',
82
82
  ...(labelPlacement === 'top' && { display: 'block' })
83
83
  },
84
-
85
84
  facade: {
86
85
  label: 'toggleFacade__facade',
87
86
  background: componentTheme.background,
@@ -92,7 +91,7 @@ const generateStyle = (
92
91
  position: 'relative',
93
92
  borderRadius: '3rem',
94
93
  verticalAlign: 'middle',
95
- boxShadow: `inset 0 0 0 ${componentTheme.borderWidth} ${componentTheme.borderColor}`,
94
+ boxShadow: `inset 0 0 0 ${componentTheme.borderWidth} ${(invalid && !checked) ? componentTheme.errorBorderColor : componentTheme.borderColor}`,
96
95
  height: componentTheme.toggleSize,
97
96
  width: `calc(${componentTheme.toggleSize} * 1.5)`,
98
97
  ...labelPlacementVariants[labelPlacement!].facade,
@@ -54,6 +54,7 @@ const generateComponentTheme = (theme: Theme): ToggleFacadeTheme => {
54
54
 
55
55
  const componentVariables: ToggleFacadeTheme = {
56
56
  color: colors?.contrasts?.white1010,
57
+ errorBorderColor: colors?.ui?.textError,
57
58
  background: colors?.contrasts?.grey1111,
58
59
  borderColor: colors?.contrasts?.grey1214,
59
60
  borderWidth: borders?.widthSmall,
@@ -40,6 +40,7 @@ import { CheckboxFacade } from './CheckboxFacade'
40
40
  import { ToggleFacade } from './ToggleFacade'
41
41
 
42
42
  import generateStyle from './styles'
43
+ import generateComponentTheme from './theme'
43
44
 
44
45
  import { propTypes, allowedProps } from './props'
45
46
  import type { CheckboxProps, CheckboxState } from './props'
@@ -57,7 +58,7 @@ tags: toggle, switch
57
58
  **/
58
59
 
59
60
  @withDeterministicId()
60
- @withStyle(generateStyle, null)
61
+ @withStyle(generateStyle, generateComponentTheme)
61
62
  @testable()
62
63
  class Checkbox extends Component<CheckboxProps, CheckboxState> {
63
64
  static readonly componentId = 'Checkbox'
@@ -181,6 +182,16 @@ class Checkbox extends Component<CheckboxProps, CheckboxState> {
181
182
  return isActiveElement(this._input)
182
183
  }
183
184
 
185
+ get isNewError() {
186
+ return !!this.props.messages?.find((m) => m.type === 'newError')
187
+ }
188
+
189
+ get invalid() {
190
+ return !!this.props.messages?.find(
191
+ (m) => m.type === 'newError' || m.type === 'error'
192
+ )
193
+ }
194
+
184
195
  focus() {
185
196
  this._input && this._input.focus()
186
197
  }
@@ -194,7 +205,9 @@ class Checkbox extends Component<CheckboxProps, CheckboxState> {
194
205
  readOnly,
195
206
  indeterminate,
196
207
  labelPlacement,
197
- themeOverride
208
+ themeOverride,
209
+ isRequired,
210
+ styles
198
211
  } = this.props
199
212
 
200
213
  const { hovered, focused } = this.state
@@ -214,8 +227,12 @@ class Checkbox extends Component<CheckboxProps, CheckboxState> {
214
227
  readOnly={readOnly}
215
228
  labelPlacement={labelPlacement}
216
229
  themeOverride={themeOverride as Partial<ToggleFacadeTheme>}
230
+ invalid={this.invalid}
217
231
  >
218
232
  {label}
233
+ {isRequired && (
234
+ <span css={this.invalid ? styles?.requiredInvalid : {}}> *</span>
235
+ )}
219
236
  </ToggleFacade>
220
237
  )
221
238
  } else {
@@ -227,18 +244,31 @@ class Checkbox extends Component<CheckboxProps, CheckboxState> {
227
244
  checked={this.checked}
228
245
  indeterminate={indeterminate}
229
246
  themeOverride={themeOverride as Partial<CheckboxFacadeTheme>}
247
+ invalid={this.invalid}
230
248
  >
231
249
  {label}
250
+ {isRequired && (
251
+ <span css={this.invalid ? styles?.requiredInvalid : {}}> *</span>
252
+ )}
232
253
  </CheckboxFacade>
233
254
  )
234
255
  }
235
256
  }
236
257
 
237
258
  renderMessages() {
238
- const { messages } = this.props
259
+ const { messages, styles, variant } = this.props
239
260
 
240
261
  return messages && messages.length > 0 ? (
241
- <View display="block" margin="small 0 0">
262
+ <View
263
+ display="block"
264
+ margin="small 0 0"
265
+ css={
266
+ this.isNewError &&
267
+ (variant === 'toggle'
268
+ ? styles?.indentedToggleError
269
+ : styles?.indentedError)
270
+ }
271
+ >
242
272
  <FormFieldMessages messages={messages} />
243
273
  </View>
244
274
  ) : null
@@ -256,7 +286,8 @@ class Checkbox extends Component<CheckboxProps, CheckboxState> {
256
286
  onMouseOut,
257
287
  indeterminate,
258
288
  variant,
259
- styles
289
+ styles,
290
+ isRequired
260
291
  } = this.props
261
292
 
262
293
  const props = omitProps(this.props, Checkbox.allowedProps)
@@ -284,6 +315,7 @@ class Checkbox extends Component<CheckboxProps, CheckboxState> {
284
315
  ref={(c) => {
285
316
  this._input = c
286
317
  }}
318
+ required={isRequired}
287
319
  disabled={disabled || readOnly}
288
320
  aria-checked={indeterminate ? 'mixed' : undefined}
289
321
  css={styles?.input}
@@ -79,6 +79,7 @@ type CheckboxOwnProps = {
79
79
  variant?: 'simple' | 'toggle'
80
80
  inline?: boolean
81
81
  labelPlacement?: 'top' | 'start' | 'end'
82
+ isRequired?: boolean
82
83
  }
83
84
 
84
85
  type PropKeys = keyof CheckboxOwnProps
@@ -91,7 +92,13 @@ type CheckboxProps = CheckboxOwnProps &
91
92
  WithDeterministicIdProps
92
93
 
93
94
  type CheckboxStyle = ComponentStyle<
94
- 'checkbox' | 'input' | 'control' | 'container'
95
+ | 'checkbox'
96
+ | 'input'
97
+ | 'control'
98
+ | 'container'
99
+ | 'requiredInvalid'
100
+ | 'indentedError'
101
+ | 'indentedToggleError'
95
102
  >
96
103
 
97
104
  const propTypes: PropValidators<PropKeys> = {
@@ -113,7 +120,8 @@ const propTypes: PropValidators<PropKeys> = {
113
120
  size: PropTypes.oneOf(['small', 'medium', 'large']),
114
121
  variant: PropTypes.oneOf(['simple', 'toggle']),
115
122
  inline: PropTypes.bool,
116
- labelPlacement: PropTypes.oneOf(['top', 'start', 'end'])
123
+ labelPlacement: PropTypes.oneOf(['top', 'start', 'end']),
124
+ isRequired: PropTypes.bool
117
125
  }
118
126
 
119
127
  const allowedProps: AllowedPropKeys = [
@@ -36,12 +36,21 @@ import type { ComponentTheme } from '@instructure/shared-types'
36
36
  * @return {Object} The final style object, which will be used in the component
37
37
  */
38
38
  const generateStyle = (
39
- _componentTheme: ComponentTheme,
39
+ componentTheme: ComponentTheme,
40
40
  props: CheckboxProps
41
41
  ): CheckboxStyle => {
42
42
  const { inline, disabled } = props
43
43
 
44
44
  return {
45
+ requiredInvalid: {
46
+ color: componentTheme.requiredInvalidColor
47
+ },
48
+ indentedError: {
49
+ paddingLeft: componentTheme.checkErrorInsetWidth
50
+ },
51
+ indentedToggleError: {
52
+ paddingLeft: componentTheme.toggleErrorInsetWidth,
53
+ },
45
54
  checkbox: {
46
55
  label: 'checkbox',
47
56
  position: 'relative',
@@ -0,0 +1,46 @@
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
+
27
+ /**
28
+ * Generates the theme object for the component from the theme and provided additional information
29
+ * @param {Object} theme The actual theme object.
30
+ * @return {Object} The final theme object with the overrides and component variables
31
+ */
32
+ const generateComponentTheme = (theme: Theme): any => {
33
+ const { colors, forms, spacing } = theme
34
+
35
+ const componentVariables: any = {
36
+ requiredInvalidColor: colors?.contrasts?.red5782,
37
+ toggleErrorInsetWidth: `calc(${forms?.inputHeightSmall}*1.5 + ${spacing?.small})`,
38
+ checkErrorInsetWidth: `calc(1.25em + ${spacing?.xSmall})`,
39
+ }
40
+
41
+ return {
42
+ ...componentVariables
43
+ }
44
+ }
45
+
46
+ export default generateComponentTheme