@@ -180,3 +180,209 @@ type: example
180180 < / div>
181181< / InstUISettingsProvider>
182182` ` `
183+
184+ ### Branding (user customizable theming)
185+
186+ The ` canvas` theme has specific theme variables that are meant as a basis to provide end users a customizability of this theme, e.g. a university can use their own colors throughout the UI. This is used by [Canvas's theme editor](https://community.canvaslms.com/t5/Admin-Guide/How-do-I-create-a-theme-for-an-account-using-the-Theme-Editor/ta-p/242).
187+
188+ > ` canvas- high- contrast` does not have this functionality, so a11y color contrast requirements (e.g. [WCAG](https://webaim.org/articles/contrast/)) are always met
189+
190+ ` ` ` ts
191+ -- -
192+ type: example
193+ -- -
194+ const Example = () => {
195+ // global stuff
196+ const [icBrandPrimary , setIcBrandPrimary ] = useState (canvas[' ic-brand-primary' ])
197+ const [icBrandFontColorDark , setIcBrandFontColorDark ] = useState (canvas[' ic-brand-font-color-dark' ])
198+ // Link
199+ const [icLinkColor , setIcLinkColor ] = useState (canvas[' ic-link-color' ])
200+ const [icLinkDecoration , setIcLinkDecoration ] = useState (canvas[' ic-link-decoration' ])
201+ // Button
202+ const [icBrandButtonPrimaryBgd , setIcBrandButtonPrimaryBgd ] = useState (canvas[' ic-brand-button--primary-bgd' ])
203+ const [icBrandButtonPrimaryText , setIcBrandButtonPrimaryText ] = useState (canvas[' ic-brand-button--primary-text' ])
204+ const [icBrandButtonSecondaryBgd , setIcBrandButtonSecondaryBgd ] = useState (canvas[' ic-brand-button--secondary-bgd' ])
205+ const [icBrandButtonSecondaryText , setIcBrandButtonSecondaryText ] = useState (canvas[' ic-brand-button--secondary-text' ])
206+ // SideNavBar
207+ const [icBrandGlobalNavBgd , setIcBrandGlobalNavBgd ] = useState (canvas[' ic-brand-global-nav-bgd' ])
208+ const [icGlobalNavLinkHover , setIcGlobalNavLinkHover ] = useState (canvas[' ic-global-nav-link-hover' ])
209+ const [icBrandGlobalNavIcIconSvgFill , setIcBrandGlobalNavIcIconSvgFill ] = useState (canvas[' ic-brand-global-nav-ic-icon-svg-fill' ])
210+ const [icBrandGlobalNavIcIconSvgFillActive , setIcBrandGlobalNavIcIconSvgFillActive ] = useState (canvas[' ic-brand-global-nav-ic-icon-svg-fill--active' ])
211+ const [icBrandGlobalNavMenuItemTextColor , setIcBrandGlobalNavMenuItemTextColor ] = useState (canvas[' ic-brand-global-nav-menu-item__text-color' ])
212+ const [icBrandGlobalNavMenuItemTextColorActive , setIcBrandGlobalNavMenuItemTextColorActive ] = useState (canvas[' ic-brand-global-nav-menu-item__text-color--active' ])
213+
214+ return (
215+ < div>
216+ < h3> Common variables< / h3>
217+ < Flex gap= " small large" >
218+ < Flex .Item size= " 50%" >
219+ < TextInput renderLabel= " ic-brand-primary" value= {icBrandPrimary} onChange= {(e , v ) => setIcBrandPrimary (v)}
220+ messages= {[{text: ' used for border/background/shadow/focus colors in many places' ,type: ' hint' }]} / >
221+ < / Flex .Item >
222+ < Flex .Item size= " 50%" >
223+ < TextInput renderLabel= " ic-brand-font-color-dark" value= {icBrandFontColorDark} onChange= {(e , v ) => setIcBrandFontColorDark (v)}
224+ messages= {[{text: ' used in lots of places for text color' ,type: ' hint' }]} / >
225+ < / Flex .Item >
226+ < / Flex>
227+
228+ < h3>< code> Button< / code> branding< / h3>
229+ < Flex gap= " small large" >
230+ < Flex .Item size= " 50%" >
231+ < TextInput renderLabel= " ic-brand-button--primary-bgd" value= {icBrandButtonPrimaryBgd} onChange= {(e , v ) => setIcBrandButtonPrimaryBgd (v)}
232+ messages= {[{text: " Used by 'primary' color buttons for background" ,type: ' hint' }]} / >
233+ < br/ >
234+ < TextInput renderLabel= " ic-brand-button--primary-text" value= {icBrandButtonPrimaryText} onChange= {(e , v ) => setIcBrandButtonPrimaryText (v)}
235+ messages= {[{text: " Used by 'primary' color buttons for text color" ,type: ' hint' }]} / >
236+ < / Flex .Item >
237+ < Flex .Item size= " 50%" >
238+ < TextInput renderLabel= " ic-brand-button--secondary-bgd" value= {icBrandButtonSecondaryBgd} onChange= {(e , v ) => setIcBrandButtonSecondaryBgd (v)}
239+ messages= {[{text: ' Unused in InstUI' ,type: ' hint' }]} / >
240+ < br/ >
241+ < TextInput renderLabel= " ic-brand-button--secondary-text" value= {icBrandButtonSecondaryText} onChange= {(e , v ) => setIcBrandButtonSecondaryText (v)}
242+ messages= {[{text: ' Unused in InstUI' ,type: ' hint' }]}/ >
243+ < / Flex .Item >
244+ < / Flex>
245+ < div style= {{display: ' flex' , gap: ' 2rem' , marginTop: ' 3rem' , flexDirection: ' column' }}>
246+ < InstUISettingsProvider theme= {{... canvas, ... {
247+ ' ic-brand-primary' : icBrandPrimary,
248+ ' ic-brand-font-color-dark' : icBrandFontColorDark,
249+ ' ic-link-color' : icLinkColor,
250+ ' ic-link-decoration' : icLinkDecoration,
251+ ' ic-brand-button--primary-bgd' : icBrandButtonPrimaryBgd,
252+ ' ic-brand-button--primary-text' : icBrandButtonPrimaryText,
253+ ' ic-brand-button--secondary-bgd' : icBrandButtonSecondaryBgd,
254+ ' ic-brand-button--secondary-text' : icBrandButtonSecondaryText,
255+ ' ic-brand-global-nav-bgd' : icBrandGlobalNavBgd,
256+ ' ic-global-nav-link-hover' : icGlobalNavLinkHover,
257+ ' ic-brand-global-nav-ic-icon-svg-fill' : icBrandGlobalNavIcIconSvgFill,
258+ ' ic-brand-global-nav-ic-icon-svg-fill--active' : icBrandGlobalNavIcIconSvgFillActive,
259+ ' ic-brand-global-nav-menu-item__text-color' : icBrandGlobalNavMenuItemTextColor,
260+ ' ic-brand-global-nav-menu-item__text-color--active' : icBrandGlobalNavMenuItemTextColorActive
261+ }}}>
262+ < hr style= {{width: ' 100%' }}/ >
263+ < Flex gap= " small large" >
264+ < Flex .Item size= " 50%" >
265+ < Button color= " primary" > I ' m a ' primary' color button</Button>
266+ <TextInput renderLabel="TextInput" placeholder="ic-brand-primary sets focus color"/>
267+ </Flex.Item>
268+ <Flex.Item size="50%">
269+ <Button color="secondary">I' m a ' secondary' color button< / Button>
270+ < TextArea label= " TextArea" placeholder= " ic-brand-primary sets focus color" / >
271+ < / Flex .Item >
272+ < / Flex>
273+
274+ < Tabs>
275+ < Tabs .Panel id= " tabA" renderTitle= " Tab A" isSelected= {true }>< / Tabs .Panel >
276+ < Tabs .Panel id= " tabB" renderTitle= " Disabled Tab" isDisabled>< / Tabs .Panel >
277+ < Tabs .Panel id= " tabC" renderTitle= " Tab C" >< / Tabs .Panel >
278+ < Tabs .Panel id= " tabD" renderTitle= " Tab D" >< / Tabs .Panel >
279+ < / Tabs>
280+
281+ < hr style= {{width: ' 100%' }}/ >
282+ < h3> Link colors used by < code> Link< / code> and < code> Billboard< / code> : < / h3>
283+ < Flex gap= " small large" >
284+ < Flex .Item size= " 50%" >
285+ < TextInput renderLabel= " ic-link-color" value= {icLinkColor} onChange= {(e , v ) => setIcLinkColor (v)}
286+ messages= {[{text: ' Used for non-inverse Link and clickable Billboard' ,type: ' hint' }]} / >
287+ < / Flex .Item >
288+ < Flex .Item size= " 50%" >
289+ < TextInput renderLabel= " ic-link-decoration" value= {icLinkDecoration} onChange= {(e , v ) => setIcLinkDecoration (v)}
290+ messages= {[{text: ' Unused in InstUI' ,type: ' hint' }]}/ >
291+ < / Flex .Item >
292+ < / Flex>
293+ < hr style= {{width: ' 100%' }}/ >
294+ < Flex gap= " small large" >
295+ < Flex .Item size= " 50%" >
296+ < Link href= " https://instructure.github.io/instructure-ui/" > normal link< / Link>
297+ < / Flex .Item >
298+ < Flex .Item size= " 50%" >
299+ < View background= " primary-inverse" as= " div" >
300+ < Link color= " link-inverse" href= " https://instructure.github.io/instructure-ui/" > inverse link< / Link>
301+ < / View>
302+ < / Flex .Item >
303+ < / Flex>
304+ < Flex gap= " small large" >
305+ < Flex .Item size= " 50%" >
306+ < Billboard
307+ margin= " small"
308+ message= " Billboard with link"
309+ href= " http://instructure.com"
310+ hero= {(size ) => < IconGradebookLine size= {size} / > }
311+ / >
312+ < / Flex .Item >
313+ < Flex .Item size= " 50%" >
314+ < Billboard
315+ margin= " small"
316+ message= " Billboard without link"
317+ hero= {(size ) => < IconGradebookLine size= {size} / > }
318+ / >
319+ < / Flex .Item >
320+ < / Flex>
321+
322+ < hr style= {{width: ' 100%' }}/ >
323+ < h3>< code> SideNavBar< / code> branding< / h3>
324+ < Flex gap= " small large" >
325+ < Flex .Item size= " 50%" >
326+ < TextInput renderLabel= " ic-brand-global-nav-bgd" value= {icBrandGlobalNavBgd} onChange= {(e , v ) => setIcBrandGlobalNavBgd (v)}/ >
327+ < TextInput renderLabel= " ic-global-nav-link-hover" value= {icGlobalNavLinkHover} onChange= {(e , v ) => setIcGlobalNavLinkHover (v)}/ >
328+ < TextInput renderLabel= " ic-brand-global-nav-ic-icon-svg-fill" value= {icBrandGlobalNavIcIconSvgFill} onChange= {(e , v ) => setIcBrandGlobalNavIcIconSvgFill (v)}/ >
329+ < / Flex .Item >
330+ < Flex .Item size= " 50%" >
331+ < TextInput renderLabel= " ic-brand-global-nav-menu-item__text-color" value= {icBrandGlobalNavMenuItemTextColor} onChange= {(e , v ) => setIcBrandGlobalNavMenuItemTextColor (v)}/ >
332+ < TextInput renderLabel= " ic-brand-global-nav-menu-item__text-color--active" value= {icBrandGlobalNavMenuItemTextColorActive} onChange= {(e , v ) => setIcBrandGlobalNavMenuItemTextColorActive (v)}/ >
333+ < TextInput renderLabel= " ic-brand-global-nav-ic-icon-svg-fill--active" value= {icBrandGlobalNavIcIconSvgFillActive} onChange= {(e , v ) => setIcBrandGlobalNavIcIconSvgFillActive (v)}/ >
334+ < / Flex .Item >
335+ < / Flex>
336+ < hr style= {{width: ' 100%' }}/ >
337+ < SideNavBar
338+ label= " Main navigation"
339+ toggleLabel= {{
340+ expandedLabel: ' Minimize SideNavBar' ,
341+ minimizedLabel: ' Expand SideNavBar'
342+ }}
343+ >
344+ < SideNavBar .Item
345+ icon= {< IconUserLine / > }
346+ label= {< ScreenReaderContent> Home< / ScreenReaderContent> }
347+ href= " #"
348+ / >
349+ < SideNavBar .Item
350+ icon= {< Avatar name= " Ziggy Marley" size= " x-small" src= {avatarSquare} showBorder= " always" / > }
351+ label= " Account"
352+ onClick= {() => { this .loadSubNav (' account' ) }}
353+ / >
354+ < SideNavBar .Item
355+ icon= {< IconAdminLine / > }
356+ label= " Admin"
357+ href= " #"
358+ / >
359+ < SideNavBar .Item selected
360+ icon= {< IconDashboardLine / > }
361+ label= " Dashboard"
362+ href= " #"
363+ / >
364+ < SideNavBar .Item
365+ icon= {< Badge count= {99 }
366+ formatOutput= {function (formattedCount ) {
367+ return (
368+ < AccessibleContent alt= {` You have ${ formattedCount} unread messages.` }>
369+ {formattedCount}
370+ < / AccessibleContent>
371+ )
372+ }}
373+ >< IconInboxLine / >< / Badge> }
374+ label= " Inbox"
375+ href= " #"
376+ / >
377+ < SideNavBar .Item icon= {< IconUserLine / > }
378+ label= " Supercalifragilistic"
379+ href= " #" / >
380+ < / SideNavBar>
381+ < / InstUISettingsProvider>
382+ < / div>
383+ < / div>
384+ )
385+ }
386+
387+ render (< Example/ > )
388+ ` ` `
0 commit comments