@instructure/ui-checkbox 11.6.0 → 11.6.1-snapshot-129

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 (158) hide show
  1. package/CHANGELOG.md +44 -297
  2. package/es/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/index.js +1 -1
  3. package/es/Checkbox/{ToggleFacade → v1/ToggleFacade}/index.js +1 -1
  4. package/es/Checkbox/{index.js → v1/index.js} +3 -3
  5. package/es/Checkbox/v2/CheckboxFacade/index.js +104 -0
  6. package/es/Checkbox/v2/CheckboxFacade/props.js +26 -0
  7. package/es/Checkbox/v2/CheckboxFacade/styles.js +177 -0
  8. package/es/Checkbox/v2/ToggleFacade/index.js +116 -0
  9. package/es/Checkbox/v2/ToggleFacade/props.js +26 -0
  10. package/es/Checkbox/v2/ToggleFacade/styles.js +232 -0
  11. package/es/Checkbox/v2/index.js +289 -0
  12. package/es/Checkbox/v2/props.js +26 -0
  13. package/es/Checkbox/v2/styles.js +102 -0
  14. package/es/CheckboxGroup/{index.js → v1/index.js} +2 -2
  15. package/es/CheckboxGroup/v2/index.js +125 -0
  16. package/es/CheckboxGroup/v2/props.js +26 -0
  17. package/es/{index.js → exports/a.js} +2 -2
  18. package/es/exports/b.js +25 -0
  19. package/lib/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/index.js +2 -2
  20. package/lib/Checkbox/{ToggleFacade → v1/ToggleFacade}/index.js +3 -3
  21. package/lib/Checkbox/{index.js → v1/index.js} +5 -5
  22. package/lib/Checkbox/v2/CheckboxFacade/index.js +109 -0
  23. package/lib/Checkbox/v2/CheckboxFacade/props.js +31 -0
  24. package/lib/Checkbox/v2/CheckboxFacade/styles.js +183 -0
  25. package/lib/Checkbox/v2/ToggleFacade/index.js +121 -0
  26. package/lib/Checkbox/v2/ToggleFacade/props.js +31 -0
  27. package/lib/Checkbox/v2/ToggleFacade/styles.js +238 -0
  28. package/lib/Checkbox/v2/index.js +308 -0
  29. package/lib/Checkbox/v2/props.js +31 -0
  30. package/lib/Checkbox/v2/styles.js +108 -0
  31. package/lib/CheckboxGroup/{index.js → v1/index.js} +5 -5
  32. package/lib/CheckboxGroup/v2/index.js +133 -0
  33. package/lib/CheckboxGroup/v2/props.js +31 -0
  34. package/lib/{index.js → exports/a.js} +6 -6
  35. package/lib/exports/b.js +31 -0
  36. package/package.json +45 -23
  37. package/src/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/index.tsx +1 -1
  38. package/src/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/styles.ts +3 -1
  39. package/src/Checkbox/{ToggleFacade → v1/ToggleFacade}/index.tsx +1 -1
  40. package/src/Checkbox/{index.tsx → v1/index.tsx} +3 -3
  41. package/src/Checkbox/{props.ts → v1/props.ts} +1 -1
  42. package/src/Checkbox/{styles.ts → v1/styles.ts} +1 -1
  43. package/src/Checkbox/{theme.ts → v1/theme.ts} +1 -1
  44. package/src/Checkbox/v2/CheckboxFacade/index.tsx +113 -0
  45. package/src/Checkbox/v2/CheckboxFacade/props.ts +67 -0
  46. package/src/Checkbox/v2/CheckboxFacade/styles.ts +209 -0
  47. package/src/Checkbox/v2/README.md +193 -0
  48. package/src/Checkbox/v2/ToggleFacade/index.tsx +124 -0
  49. package/src/Checkbox/v2/ToggleFacade/props.ts +67 -0
  50. package/src/Checkbox/v2/ToggleFacade/styles.ts +301 -0
  51. package/src/Checkbox/v2/index.tsx +376 -0
  52. package/src/Checkbox/v2/props.ts +132 -0
  53. package/src/Checkbox/v2/styles.ts +118 -0
  54. package/src/CheckboxGroup/{index.tsx → v1/index.tsx} +2 -2
  55. package/src/CheckboxGroup/{props.ts → v1/props.ts} +3 -3
  56. package/src/CheckboxGroup/v2/README.md +111 -0
  57. package/src/CheckboxGroup/v2/index.tsx +157 -0
  58. package/src/CheckboxGroup/v2/props.ts +77 -0
  59. package/src/{index.ts → exports/a.ts} +6 -6
  60. package/src/exports/b.ts +30 -0
  61. package/tsconfig.build.tsbuildinfo +1 -1
  62. package/types/Checkbox/v1/CheckboxFacade/index.d.ts.map +1 -0
  63. package/types/Checkbox/v1/CheckboxFacade/props.d.ts.map +1 -0
  64. package/types/Checkbox/v1/CheckboxFacade/styles.d.ts.map +1 -0
  65. package/types/Checkbox/v1/CheckboxFacade/theme.d.ts.map +1 -0
  66. package/types/Checkbox/v1/ToggleFacade/index.d.ts.map +1 -0
  67. package/types/Checkbox/v1/ToggleFacade/props.d.ts.map +1 -0
  68. package/types/Checkbox/v1/ToggleFacade/styles.d.ts.map +1 -0
  69. package/types/Checkbox/v1/ToggleFacade/theme.d.ts.map +1 -0
  70. package/types/Checkbox/{index.d.ts → v1/index.d.ts} +1 -1
  71. package/types/Checkbox/v1/index.d.ts.map +1 -0
  72. package/types/Checkbox/{props.d.ts → v1/props.d.ts} +1 -1
  73. package/types/Checkbox/v1/props.d.ts.map +1 -0
  74. package/types/Checkbox/v1/styles.d.ts.map +1 -0
  75. package/types/Checkbox/v1/theme.d.ts.map +1 -0
  76. package/types/Checkbox/v2/CheckboxFacade/index.d.ts +39 -0
  77. package/types/Checkbox/v2/CheckboxFacade/index.d.ts.map +1 -0
  78. package/types/Checkbox/v2/CheckboxFacade/props.d.ts +27 -0
  79. package/types/Checkbox/v2/CheckboxFacade/props.d.ts.map +1 -0
  80. package/types/Checkbox/v2/CheckboxFacade/styles.d.ts +16 -0
  81. package/types/Checkbox/v2/CheckboxFacade/styles.d.ts.map +1 -0
  82. package/types/Checkbox/v2/ToggleFacade/index.d.ts +40 -0
  83. package/types/Checkbox/v2/ToggleFacade/index.d.ts.map +1 -0
  84. package/types/Checkbox/v2/ToggleFacade/props.d.ts +25 -0
  85. package/types/Checkbox/v2/ToggleFacade/props.d.ts.map +1 -0
  86. package/types/Checkbox/v2/ToggleFacade/styles.d.ts +16 -0
  87. package/types/Checkbox/v2/ToggleFacade/styles.d.ts.map +1 -0
  88. package/types/Checkbox/v2/index.d.ts +71 -0
  89. package/types/Checkbox/v2/index.d.ts.map +1 -0
  90. package/types/Checkbox/v2/props.d.ts +64 -0
  91. package/types/Checkbox/v2/props.d.ts.map +1 -0
  92. package/types/Checkbox/v2/styles.d.ts +16 -0
  93. package/types/Checkbox/v2/styles.d.ts.map +1 -0
  94. package/types/CheckboxGroup/{index.d.ts → v1/index.d.ts} +1 -1
  95. package/types/CheckboxGroup/v1/index.d.ts.map +1 -0
  96. package/types/CheckboxGroup/{props.d.ts → v1/props.d.ts} +3 -3
  97. package/types/CheckboxGroup/v1/props.d.ts.map +1 -0
  98. package/types/CheckboxGroup/v2/index.d.ts +42 -0
  99. package/types/CheckboxGroup/v2/index.d.ts.map +1 -0
  100. package/types/CheckboxGroup/v2/props.d.ts +30 -0
  101. package/types/CheckboxGroup/v2/props.d.ts.map +1 -0
  102. package/types/exports/a.d.ts +7 -0
  103. package/types/exports/a.d.ts.map +1 -0
  104. package/types/exports/b.d.ts +7 -0
  105. package/types/exports/b.d.ts.map +1 -0
  106. package/types/Checkbox/CheckboxFacade/index.d.ts.map +0 -1
  107. package/types/Checkbox/CheckboxFacade/props.d.ts.map +0 -1
  108. package/types/Checkbox/CheckboxFacade/styles.d.ts.map +0 -1
  109. package/types/Checkbox/CheckboxFacade/theme.d.ts.map +0 -1
  110. package/types/Checkbox/ToggleFacade/index.d.ts.map +0 -1
  111. package/types/Checkbox/ToggleFacade/props.d.ts.map +0 -1
  112. package/types/Checkbox/ToggleFacade/styles.d.ts.map +0 -1
  113. package/types/Checkbox/ToggleFacade/theme.d.ts.map +0 -1
  114. package/types/Checkbox/index.d.ts.map +0 -1
  115. package/types/Checkbox/props.d.ts.map +0 -1
  116. package/types/Checkbox/styles.d.ts.map +0 -1
  117. package/types/Checkbox/theme.d.ts.map +0 -1
  118. package/types/CheckboxGroup/index.d.ts.map +0 -1
  119. package/types/CheckboxGroup/props.d.ts.map +0 -1
  120. package/types/index.d.ts +0 -7
  121. package/types/index.d.ts.map +0 -1
  122. /package/es/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/props.js +0 -0
  123. /package/es/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/styles.js +0 -0
  124. /package/es/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/theme.js +0 -0
  125. /package/es/Checkbox/{ToggleFacade → v1/ToggleFacade}/props.js +0 -0
  126. /package/es/Checkbox/{ToggleFacade → v1/ToggleFacade}/styles.js +0 -0
  127. /package/es/Checkbox/{ToggleFacade → v1/ToggleFacade}/theme.js +0 -0
  128. /package/es/Checkbox/{props.js → v1/props.js} +0 -0
  129. /package/es/Checkbox/{styles.js → v1/styles.js} +0 -0
  130. /package/es/Checkbox/{theme.js → v1/theme.js} +0 -0
  131. /package/es/CheckboxGroup/{props.js → v1/props.js} +0 -0
  132. /package/lib/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/props.js +0 -0
  133. /package/lib/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/styles.js +0 -0
  134. /package/lib/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/theme.js +0 -0
  135. /package/lib/Checkbox/{ToggleFacade → v1/ToggleFacade}/props.js +0 -0
  136. /package/lib/Checkbox/{ToggleFacade → v1/ToggleFacade}/styles.js +0 -0
  137. /package/lib/Checkbox/{ToggleFacade → v1/ToggleFacade}/theme.js +0 -0
  138. /package/lib/Checkbox/{props.js → v1/props.js} +0 -0
  139. /package/lib/Checkbox/{styles.js → v1/styles.js} +0 -0
  140. /package/lib/Checkbox/{theme.js → v1/theme.js} +0 -0
  141. /package/lib/CheckboxGroup/{props.js → v1/props.js} +0 -0
  142. /package/src/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/props.ts +0 -0
  143. /package/src/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/theme.ts +0 -0
  144. /package/src/Checkbox/{README.md → v1/README.md} +0 -0
  145. /package/src/Checkbox/{ToggleFacade → v1/ToggleFacade}/props.ts +0 -0
  146. /package/src/Checkbox/{ToggleFacade → v1/ToggleFacade}/styles.ts +0 -0
  147. /package/src/Checkbox/{ToggleFacade → v1/ToggleFacade}/theme.ts +0 -0
  148. /package/src/CheckboxGroup/{README.md → v1/README.md} +0 -0
  149. /package/types/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/index.d.ts +0 -0
  150. /package/types/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/props.d.ts +0 -0
  151. /package/types/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/styles.d.ts +0 -0
  152. /package/types/Checkbox/{CheckboxFacade → v1/CheckboxFacade}/theme.d.ts +0 -0
  153. /package/types/Checkbox/{ToggleFacade → v1/ToggleFacade}/index.d.ts +0 -0
  154. /package/types/Checkbox/{ToggleFacade → v1/ToggleFacade}/props.d.ts +0 -0
  155. /package/types/Checkbox/{ToggleFacade → v1/ToggleFacade}/styles.d.ts +0 -0
  156. /package/types/Checkbox/{ToggleFacade → v1/ToggleFacade}/theme.d.ts +0 -0
  157. /package/types/Checkbox/{styles.d.ts → v1/styles.d.ts} +0 -0
  158. /package/types/Checkbox/{theme.d.ts → v1/theme.d.ts} +0 -0
@@ -0,0 +1,209 @@
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 { NewComponentTypes, SharedTokens } from '@instructure/ui-themes'
26
+ import { calcFocusOutlineStyles } from '@instructure/emotion'
27
+ import type { CheckboxFacadeProps, CheckboxFacadeStyle } from './props'
28
+
29
+ /**
30
+ * ---
31
+ * private: true
32
+ * ---
33
+ * Generates the style object from the theme and provided additional information
34
+ * @param {Object} componentTheme The theme variable object.
35
+ * @param {Object} props the props of the component, the style is applied to
36
+ * @param {Object} sharedTokens Shared theme token object
37
+ * @param {Object} state the state of the component, the style is applied to
38
+ * @return {Object} The final style object, which will be used in the component
39
+ */
40
+ const generateStyle = (
41
+ componentTheme: NewComponentTypes['Checkbox'],
42
+ props: CheckboxFacadeProps,
43
+ sharedTokens: SharedTokens
44
+ ): CheckboxFacadeStyle => {
45
+ const {
46
+ size,
47
+ checked,
48
+ disabled,
49
+ readOnly,
50
+ focused,
51
+ hovered,
52
+ indeterminate,
53
+ invalid
54
+ } = props
55
+
56
+ const isChecked = checked || indeterminate
57
+
58
+ const sizeVariants = {
59
+ small: {
60
+ label: { fontSize: componentTheme.fontSizeSm },
61
+ facade: {
62
+ fontSize: componentTheme.fontSizeSm,
63
+ width: componentTheme.controlSizeSm,
64
+ height: componentTheme.controlSizeSm,
65
+ margin: `${componentTheme.controlVerticalMargin} ${componentTheme.gap} 0 0`
66
+ }
67
+ },
68
+ medium: {
69
+ label: { fontSize: componentTheme.fontSizeMd },
70
+ facade: {
71
+ fontSize: componentTheme.fontSizeMd,
72
+ width: componentTheme.controlSizeMd,
73
+ height: componentTheme.controlSizeMd
74
+ }
75
+ },
76
+ large: {
77
+ label: { fontSize: componentTheme.fontSizeLg },
78
+ facade: {
79
+ fontSize: componentTheme.fontSizeLg,
80
+ width: componentTheme.controlSizeLg,
81
+ height: componentTheme.controlSizeLg
82
+ }
83
+ }
84
+ }
85
+ const sizeVariant =
86
+ sizeVariants[size as keyof typeof sizeVariants] ?? sizeVariants.medium
87
+
88
+ const getLabelColor = () => {
89
+ if (disabled) {
90
+ return componentTheme.labelDisabledColor
91
+ }
92
+
93
+ if (readOnly) {
94
+ return componentTheme.labelReadonlyColor
95
+ }
96
+
97
+ // DEFAULT state
98
+ return hovered
99
+ ? componentTheme.labelHoverColor
100
+ : componentTheme.labelBaseColor
101
+ }
102
+
103
+ const getFacadeStyles = () => {
104
+ const baseStyles = {
105
+ position: 'relative',
106
+ display: 'flex',
107
+ alignItems: 'center',
108
+ justifyContent: 'center',
109
+ boxSizing: 'border-box',
110
+ flexShrink: 0,
111
+ transition: 'all 0.2s',
112
+ borderRadius: componentTheme.borderRadius,
113
+ marginInlineEnd: componentTheme.gap,
114
+ marginInlineStart: '0',
115
+ ...sizeVariant.facade
116
+ }
117
+
118
+ if (disabled) {
119
+ return {
120
+ ...baseStyles,
121
+ background: componentTheme.backgroundDisabledColor,
122
+ border: `${componentTheme.borderWidth} solid ${componentTheme.borderDisabledColor}`
123
+ }
124
+ }
125
+
126
+ if (readOnly) {
127
+ return {
128
+ ...baseStyles,
129
+ background: componentTheme.backgroundReadonlyColor,
130
+ border: `${componentTheme.borderWidth} solid ${componentTheme.borderReadonlyColor}`,
131
+ pointerEvents: 'none'
132
+ }
133
+ }
134
+
135
+ if (invalid) {
136
+ return {
137
+ ...baseStyles,
138
+ ...(isChecked && {
139
+ background: componentTheme.backgroundCheckedColor,
140
+ border: `${componentTheme.borderWidth} solid ${
141
+ hovered
142
+ ? componentTheme.errorBorderHoverColor
143
+ : componentTheme.errorBorderColor
144
+ }`
145
+ }),
146
+ ...(!isChecked && {
147
+ background: hovered
148
+ ? componentTheme.backgroundHoverColor
149
+ : componentTheme.backgroundColor,
150
+ border: `${componentTheme.borderWidth} solid ${
151
+ hovered
152
+ ? componentTheme.errorBorderHoverColor
153
+ : componentTheme.errorBorderColor
154
+ }`
155
+ })
156
+ }
157
+ }
158
+
159
+ if (isChecked) {
160
+ return {
161
+ ...baseStyles,
162
+ background: componentTheme.backgroundCheckedColor,
163
+ border: `${componentTheme.borderWidth} solid ${componentTheme.borderCheckedColor}`
164
+ }
165
+ }
166
+
167
+ // DEFAULT (unchecked) state
168
+ return {
169
+ ...baseStyles,
170
+ background: hovered
171
+ ? componentTheme.backgroundHoverColor
172
+ : componentTheme.backgroundColor,
173
+ border: `${componentTheme.borderWidth} solid ${
174
+ hovered ? componentTheme.borderHoverColor : componentTheme.borderColor
175
+ }`
176
+ }
177
+ }
178
+
179
+ return {
180
+ checkboxFacade: {
181
+ label: 'checkboxFacade',
182
+ display: 'flex',
183
+ alignItems: 'flex-start',
184
+ cursor: disabled ? 'not-allowed' : readOnly ? 'default' : 'pointer'
185
+ },
186
+ facade: {
187
+ label: 'checkboxFacade__facade',
188
+ ...getFacadeStyles(),
189
+ ...(sharedTokens?.focusOutline
190
+ ? calcFocusOutlineStyles(sharedTokens.focusOutline, {
191
+ withFocusOutline: focused
192
+ })
193
+ : {})
194
+ },
195
+ label: {
196
+ label: 'checkboxFacade__label',
197
+ flex: '1 1 auto',
198
+ alignSelf: 'center',
199
+ minWidth: '0.0625rem',
200
+ color: getLabelColor(),
201
+ fontFamily: componentTheme.fontFamily,
202
+ fontWeight: componentTheme.fontWeight,
203
+ lineHeight: componentTheme.lineHeight,
204
+ ...sizeVariant.label
205
+ }
206
+ }
207
+ }
208
+
209
+ export default generateStyle
@@ -0,0 +1,193 @@
1
+ ---
2
+ describes: Checkbox
3
+ ---
4
+
5
+ By default, the Checkbox component is a custom styled HTML checkbox. To default the checkbox to checked,
6
+ set the `defaultChecked` prop.
7
+
8
+ Adjust the size of the checkbox and label text via the `size` prop. The default size is
9
+ `medium`.
10
+
11
+ ```js
12
+ ---
13
+ type: example
14
+ ---
15
+ <Checkbox label={lorem.sentence()} value="medium" defaultChecked />
16
+ ```
17
+
18
+ The default Checkbox in its disabled state:
19
+
20
+ ```js
21
+ ---
22
+ type: example
23
+ ---
24
+ <CheckboxGroup
25
+ defaultValue={['medium']}
26
+ name="example"
27
+ description={<ScreenReaderContent>Checkbox examples</ScreenReaderContent>}
28
+ >
29
+ <Checkbox label={lorem.sentence()} value="medium" disabled />
30
+ <Checkbox label={lorem.sentence()} value="small" disabled />
31
+ </CheckboxGroup>
32
+ ```
33
+
34
+ The `indeterminate` property triggers a visual state that handles
35
+ situations where "child" Checkboxes are neither all checked nor all
36
+ unchecked. Note the use of `aria-labelledby` to make the relationship
37
+ between the parent and child Checkboxes clear to screenreader users.
38
+
39
+ _Note: the `toggle` variant does not support the `indeterminate`
40
+ property._
41
+
42
+ ```js
43
+ ---
44
+ type: example
45
+ ---
46
+ const Example = () => {
47
+ const [value, setValue] = useState(['his111', 'eng203'])
48
+
49
+ const updateValue = (valueToUpdate) => {
50
+ const index = value.indexOf(valueToUpdate)
51
+ console.log(index)
52
+ if (index === -1) {
53
+ setValue([...value, valueToUpdate])
54
+ } else {
55
+ setValue([...value.slice(0, index), ...value.slice(index + 1)])
56
+ }
57
+ }
58
+
59
+ return (
60
+ <FormFieldGroup
61
+ description={
62
+ <ScreenReaderContent>
63
+ <span id="groupLabel">Courses to edit</span>
64
+ </ScreenReaderContent>
65
+ }
66
+ rowSpacing="small"
67
+ >
68
+ <Checkbox
69
+ aria-labelledby="groupLabel selectAllLabel"
70
+ label={<span id="selectAllLabel">Select all courses</span>}
71
+ value="all"
72
+ onChange={() =>
73
+ setValue(value.length === 3 ? [] : ['eng203', 'sci101', 'his111'])
74
+ }
75
+ checked={value.length === 3}
76
+ indeterminate={value.length > 0 && value.length < 3}
77
+ />
78
+ <View as="div" padding="0 0 0 medium">
79
+ <Checkbox
80
+ aria-labelledby="groupLabel eng203Label"
81
+ label={<span id="eng203Label">English 203</span>}
82
+ value="eng203"
83
+ name="courses"
84
+ onChange={(event) => {
85
+ updateValue(event.target.value)
86
+ }}
87
+ checked={value.indexOf('eng203') !== -1}
88
+ />
89
+ </View>
90
+ <View as="div" padding="0 0 0 medium">
91
+ <Checkbox
92
+ aria-labelledby="groupLabel sci101Label"
93
+ label={<span id="sci101Label">Science 101</span>}
94
+ value="sci101"
95
+ name="courses"
96
+ onChange={(event) => {
97
+ updateValue(event.target.value)
98
+ }}
99
+ checked={value.indexOf('sci101') !== -1}
100
+ />
101
+ </View>
102
+ <View as="div" padding="0 0 0 medium">
103
+ <Checkbox
104
+ aria-labelledby="groupLabel hist101Label"
105
+ label={<span id="hist101Label">History 111</span>}
106
+ value="his111"
107
+ name="courses"
108
+ onChange={(event) => {
109
+ updateValue(event.target.value)
110
+ }}
111
+ checked={value.indexOf('his111') !== -1}
112
+ />
113
+ </View>
114
+ </FormFieldGroup>
115
+ )
116
+ }
117
+
118
+ render(<Example />)
119
+ ```
120
+
121
+ Setting the `variant` prop to `toggle` turns the checkbox into a toggle switch. For **toggle only** the size prop affects the size of the label and not the actual size of the switch.
122
+
123
+ ```js
124
+ ---
125
+ type: example
126
+ ---
127
+ <FormFieldGroup description={<ScreenReaderContent>Checkbox examples</ScreenReaderContent>}>
128
+ <Checkbox label="Small size" value="small" variant="toggle" size="small" defaultChecked />
129
+ <Checkbox label="Medium size" value="medium" variant="toggle" />
130
+ <Checkbox label="Large size" value="large" variant="toggle" size="large" defaultChecked />
131
+ </FormFieldGroup>
132
+ ```
133
+
134
+ To change the label placement for the toggle variety, use the labelPlacement prop. The default
135
+ placement is 'end'.
136
+
137
+ _Note: the `simple` variant does not support the `labelPlacement`
138
+ property._
139
+
140
+ ```js
141
+ ---
142
+ type: example
143
+ ---
144
+ <FormFieldGroup description={<ScreenReaderContent>Toggle label examples</ScreenReaderContent>}>
145
+ <Checkbox label="Top" variant="toggle" labelPlacement="top" defaultChecked />
146
+ <Checkbox label="Start" variant="toggle" labelPlacement="start" />
147
+ <Checkbox label="End" variant="toggle" labelPlacement="end" defaultChecked />
148
+ </FormFieldGroup>
149
+ ```
150
+
151
+ You might want to hide the label text when using the toggle switch variant. Do that by wrapping
152
+ the text in the [ScreenReaderContent](ScreenReaderContent) component.
153
+
154
+ ```js
155
+ ---
156
+ type: example
157
+ ---
158
+ <Checkbox
159
+ label={<ScreenReaderContent>Screenreader-accessible label</ScreenReaderContent>}
160
+ value="accessible"
161
+ variant="toggle"
162
+ />
163
+ ```
164
+
165
+ ### Guidelines
166
+
167
+ ```js
168
+ ---
169
+ type: embed
170
+ ---
171
+ <Guidelines>
172
+ <Figure recommendation="yes" title="Do">
173
+ <Figure.Item>Align to the left side of the label</Figure.Item>
174
+ <Figure.Item>Use when multiple selections are allowed</Figure.Item>
175
+ <Figure.Item>Use to save space from toggles</Figure.Item>
176
+ <Figure.Item>Stack vertically if there is more than two options to select</Figure.Item>
177
+ </Figure>
178
+ <Figure recommendation="no" title="Don't">
179
+ <Figure.Item>Run more than two checkboxes horizontally</Figure.Item>
180
+ </Figure>
181
+ </Guidelines>
182
+ ```
183
+
184
+ ```js
185
+ ---
186
+ type: embed
187
+ ---
188
+ <Guidelines>
189
+ <Figure recommendation="a11y" title="Accessibility">
190
+ <Figure.Item>Do not add business logic to `onMouseOver` or `onMouseOut` events. These events are not triggered by keyboard navigation</Figure.Item>
191
+ </Figure>
192
+ </Guidelines>
193
+ ```
@@ -0,0 +1,124 @@
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 { Component } from 'react'
26
+
27
+ import {
28
+ CheckInstUIIcon,
29
+ XInstUIIcon,
30
+ renderIconWithProps
31
+ } from '@instructure/ui-icons'
32
+
33
+ import { withStyle } from '@instructure/emotion'
34
+
35
+ import generateStyle from './styles'
36
+
37
+ import { allowedProps } from './props'
38
+ import type { ToggleFacadeProps } from './props'
39
+
40
+ /**
41
+ ---
42
+ parent: Checkbox
43
+ ---
44
+ **/
45
+ @withStyle(generateStyle, 'Toggle')
46
+ class ToggleFacade extends Component<ToggleFacadeProps> {
47
+ static readonly componentId = 'ToggleFacade'
48
+
49
+ static allowedProps = allowedProps
50
+ static defaultProps = {
51
+ checked: false,
52
+ focused: false,
53
+ hovered: false,
54
+ size: 'medium',
55
+ disabled: false,
56
+ readOnly: false,
57
+ labelPlacement: 'end'
58
+ }
59
+
60
+ ref: Element | null = null
61
+
62
+ handleRef = (el: Element | null) => {
63
+ this.ref = el
64
+ }
65
+
66
+ componentDidMount() {
67
+ this.props.makeStyles?.()
68
+ }
69
+
70
+ componentDidUpdate() {
71
+ this.props.makeStyles?.()
72
+ }
73
+
74
+ renderIcon() {
75
+ const { disabled, readOnly, checked } = this.props
76
+
77
+ const getIconColor = () => {
78
+ if (disabled) {
79
+ return 'disabledBaseColor'
80
+ }
81
+ if (readOnly) {
82
+ return 'mutedColor'
83
+ }
84
+ if (checked) {
85
+ return 'successColor'
86
+ }
87
+ return 'baseColor'
88
+ }
89
+
90
+ const iconColor = getIconColor()
91
+
92
+ if (checked) {
93
+ return renderIconWithProps(CheckInstUIIcon, 'xs', iconColor)
94
+ } else {
95
+ return renderIconWithProps(XInstUIIcon, 'xs', iconColor)
96
+ }
97
+ }
98
+
99
+ renderLabel() {
100
+ const { children, styles } = this.props
101
+
102
+ return <span css={styles?.label}>{children}</span>
103
+ }
104
+
105
+ render() {
106
+ const { labelPlacement, styles } = this.props
107
+
108
+ return (
109
+ <span css={styles?.toggleFacade} ref={this.handleRef}>
110
+ {(labelPlacement === 'top' || labelPlacement === 'start') &&
111
+ this.renderLabel()}
112
+ <span css={styles?.facade} aria-hidden="true">
113
+ <span css={styles?.icon}>
114
+ <span css={styles?.iconToggle}>{this.renderIcon()}</span>
115
+ </span>
116
+ </span>
117
+ {labelPlacement === 'end' && this.renderLabel()}
118
+ </span>
119
+ )
120
+ }
121
+ }
122
+
123
+ export default ToggleFacade
124
+ export { ToggleFacade }
@@ -0,0 +1,67 @@
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 React from 'react'
26
+ import type { ToggleFacadeTheme } from '@instructure/shared-types'
27
+ import type { WithStyleProps, ComponentStyle } from '@instructure/emotion'
28
+
29
+ type ToggleFacadeOwnProps = {
30
+ children: React.ReactNode
31
+ checked?: boolean
32
+ disabled?: boolean
33
+ readOnly?: boolean
34
+ focused?: boolean
35
+ hovered?: boolean
36
+ size?: 'small' | 'medium' | 'large'
37
+ labelPlacement?: 'top' | 'start' | 'end'
38
+ /**
39
+ * Indicate if the parent component (`Checkbox`) is invalid to set the style accordingly.
40
+ */
41
+ invalid?: boolean
42
+ }
43
+
44
+ type PropKeys = keyof ToggleFacadeOwnProps
45
+
46
+ type AllowedPropKeys = Readonly<Array<PropKeys>>
47
+
48
+ type ToggleFacadeProps = ToggleFacadeOwnProps &
49
+ WithStyleProps<ToggleFacadeTheme, ToggleFacadeStyle>
50
+
51
+ type ToggleFacadeStyle = ComponentStyle<
52
+ 'toggleFacade' | 'facade' | 'icon' | 'iconToggle' | 'label'
53
+ >
54
+ const allowedProps: AllowedPropKeys = [
55
+ 'children',
56
+ 'checked',
57
+ 'disabled',
58
+ 'readOnly',
59
+ 'focused',
60
+ 'hovered',
61
+ 'size',
62
+ 'labelPlacement',
63
+ 'invalid'
64
+ ]
65
+
66
+ export type { ToggleFacadeProps, ToggleFacadeStyle }
67
+ export { allowedProps }