fontcustom_canvas 0.1.0 → 0.1.2
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.
- checksums.yaml +4 -4
- data/README.md +7 -4
- data/fontcustom_canvas-0.1.0.gem +0 -0
- data/fontcustom_canvas-0.1.1.gem +0 -0
- data/fontcustom_canvas.gemspec +1 -0
- data/lib/fontcustom_canvas.rb +5 -5
- data/lib/fontcustom_canvas/version.rb +1 -1
- data/public/_ic-typography.scss +629 -0
- data/public/_ic_app_header.scss +463 -0
- data/public/_variables.scss +298 -0
- data/public/brandable_css.rb +374 -0
- data/public/brandable_variables.json +233 -0
- data/public/theme_editor/Fonts.js +92 -0
- data/public/theme_editor/PropTypes.js +130 -0
- data/public/theme_editor/ThemeEditorAccordion.js +131 -0
- data/public/theme_editor/ThemeEditorFontFamilyRow.js +147 -0
- data/public/theme_editor/ThemeEditorFontSizeRow.js +152 -0
- data/public/theme_editor/ThemeEditorFontWeightRow.js +176 -0
- metadata +30 -3
@@ -0,0 +1,131 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) 2015 - present Instructure, Inc.
|
3
|
+
*
|
4
|
+
* This file is part of Canvas.
|
5
|
+
*
|
6
|
+
* Canvas is free software: you can redistribute it and/or modify it under
|
7
|
+
* the terms of the GNU Affero General Public License as published by the Free
|
8
|
+
* Software Foundation, version 3 of the License.
|
9
|
+
*
|
10
|
+
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
11
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
12
|
+
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
13
|
+
* details.
|
14
|
+
*
|
15
|
+
* You should have received a copy of the GNU Affero General Public License along
|
16
|
+
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
17
|
+
*/
|
18
|
+
|
19
|
+
import React from 'react'
|
20
|
+
import PropTypes from 'prop-types'
|
21
|
+
import I18n from 'i18nObj'
|
22
|
+
import {Text} from '@instructure/ui-elements'
|
23
|
+
import ThemeEditorColorRow from './ThemeEditorColorRow'
|
24
|
+
import ThemeEditorImageRow from './ThemeEditorImageRow'
|
25
|
+
import ThemeEditorVariableGroup from './ThemeEditorVariableGroup'
|
26
|
+
import RangeInput from './RangeInput'
|
27
|
+
import customTypes from './PropTypes'
|
28
|
+
import ThemeEditorFontFamilyRow from './ThemeEditorFontFamilyRow'
|
29
|
+
import ThemeEditorFontWeightRow from './ThemeEditorFontWeightRow'
|
30
|
+
import ThemeEditorFontSizeRow from './ThemeEditorFontSizeRow'
|
31
|
+
|
32
|
+
const activeIndexKey = 'Theme__editor-accordion-index'
|
33
|
+
|
34
|
+
export default class ThemeEditorAccordion extends React.Component {
|
35
|
+
static propTypes = {
|
36
|
+
variableSchema: customTypes.variableSchema,
|
37
|
+
brandConfigVariables: PropTypes.object.isRequired,
|
38
|
+
changedValues: PropTypes.object.isRequired,
|
39
|
+
changeSomething: PropTypes.func.isRequired,
|
40
|
+
getDisplayValue: PropTypes.func.isRequired,
|
41
|
+
themeState: PropTypes.object,
|
42
|
+
handleThemeStateChange: PropTypes.func
|
43
|
+
}
|
44
|
+
|
45
|
+
state = {
|
46
|
+
expandedIndex: Number(window.sessionStorage.getItem(activeIndexKey))
|
47
|
+
}
|
48
|
+
|
49
|
+
setStoredAccordionIndex(index) {
|
50
|
+
window.sessionStorage.setItem(activeIndexKey, index)
|
51
|
+
}
|
52
|
+
|
53
|
+
handleToggle = (event, expanded, index) => {
|
54
|
+
this.setState(
|
55
|
+
{
|
56
|
+
expandedIndex: index
|
57
|
+
},
|
58
|
+
() => {
|
59
|
+
this.setStoredAccordionIndex(index)
|
60
|
+
}
|
61
|
+
)
|
62
|
+
}
|
63
|
+
|
64
|
+
renderRow = varDef => {
|
65
|
+
const props = {
|
66
|
+
key: varDef.variable_name,
|
67
|
+
currentValue: this.props.brandConfigVariables[varDef.variable_name],
|
68
|
+
userInput: this.props.changedValues[varDef.variable_name],
|
69
|
+
onChange: this.props.changeSomething.bind(null, varDef.variable_name),
|
70
|
+
placeholder: this.props.getDisplayValue(varDef.variable_name),
|
71
|
+
themeState: this.props.themeState,
|
72
|
+
handleThemeStateChange: this.props.handleThemeStateChange,
|
73
|
+
varDef
|
74
|
+
}
|
75
|
+
|
76
|
+
switch (varDef.type) {
|
77
|
+
case 'color':
|
78
|
+
return <ThemeEditorColorRow {...props} />
|
79
|
+
case 'image':
|
80
|
+
return <ThemeEditorImageRow {...props} />
|
81
|
+
case 'percentage':
|
82
|
+
const defaultValue = props.currentValue || props.placeholder
|
83
|
+
return (
|
84
|
+
<RangeInput
|
85
|
+
key={varDef.variable_name}
|
86
|
+
labelText={varDef.human_name}
|
87
|
+
min={0}
|
88
|
+
max={1}
|
89
|
+
step={0.1}
|
90
|
+
defaultValue={defaultValue ? parseFloat(defaultValue) : 0.5}
|
91
|
+
name={`brand_config[variables][${varDef.variable_name}]`}
|
92
|
+
variableKey={varDef.variable_name}
|
93
|
+
onChange={value => props.onChange(value)}
|
94
|
+
themeState={props.themeState}
|
95
|
+
handleThemeStateChange={props.handleThemeStateChange}
|
96
|
+
formatValue={value => I18n.toPercentage(value * 100, {precision: 0})}
|
97
|
+
/>
|
98
|
+
)
|
99
|
+
case 'fontFamily':
|
100
|
+
return <ThemeEditorFontFamilyRow {...props} />
|
101
|
+
case 'fontSize':
|
102
|
+
return <ThemeEditorFontSizeRow {...props} />
|
103
|
+
case 'fontWeight':
|
104
|
+
return <ThemeEditorFontWeightRow {...props} />
|
105
|
+
default:
|
106
|
+
return null
|
107
|
+
}
|
108
|
+
}
|
109
|
+
|
110
|
+
render() {
|
111
|
+
return (
|
112
|
+
<div>
|
113
|
+
{this.props.variableSchema.map((variableGroup, index) => (
|
114
|
+
<ThemeEditorVariableGroup
|
115
|
+
key={variableGroup.group_name}
|
116
|
+
summary={
|
117
|
+
<Text as="h2" weight="bold">
|
118
|
+
{variableGroup.group_name}
|
119
|
+
</Text>
|
120
|
+
}
|
121
|
+
index={index}
|
122
|
+
expanded={index === this.state.expandedIndex}
|
123
|
+
onToggle={this.handleToggle}
|
124
|
+
>
|
125
|
+
{variableGroup.variables.map(this.renderRow)}
|
126
|
+
</ThemeEditorVariableGroup>
|
127
|
+
))}
|
128
|
+
</div>
|
129
|
+
)
|
130
|
+
}
|
131
|
+
}
|
@@ -0,0 +1,147 @@
|
|
1
|
+
import React, {Component} from 'react'
|
2
|
+
import PropTypes from 'prop-types'
|
3
|
+
import customTypes from './PropTypes'
|
4
|
+
import I18n from 'i18n!theme_editor'
|
5
|
+
import classnames from 'classnames'
|
6
|
+
import fonts from './Fonts'
|
7
|
+
|
8
|
+
export class ThemeEditorFontFamilyRow extends Component {
|
9
|
+
static propTypes = {
|
10
|
+
varDef: customTypes.fontFamily,
|
11
|
+
onChange: PropTypes.func.isRequired,
|
12
|
+
userInput: customTypes.userVariableInput,
|
13
|
+
placeholder: PropTypes.string.isRequired,
|
14
|
+
themeState: PropTypes.object,
|
15
|
+
handleThemeStateChange: PropTypes.func
|
16
|
+
}
|
17
|
+
|
18
|
+
static defaultProps = {
|
19
|
+
userInput: {},
|
20
|
+
themeState: {},
|
21
|
+
handleThemeStateChange() {}
|
22
|
+
}
|
23
|
+
|
24
|
+
state = {}
|
25
|
+
|
26
|
+
showWarning = () => this.props.userInput.invalid && this.inputNotFocused()
|
27
|
+
|
28
|
+
warningLabel = () => {
|
29
|
+
if (this.showWarning()) {
|
30
|
+
return (
|
31
|
+
<span role="alert">
|
32
|
+
<div className="ic-Form-message ic-Form-message--error" tabIndex="0">
|
33
|
+
<div className="ic-Form-message__Layout">
|
34
|
+
<i className="icon-warning" role="presentation" />
|
35
|
+
{I18n.t("'%{chosenFontFamily}' is not a valid fontFamily.", {
|
36
|
+
chosenFontFamily: this.props.userInput.val
|
37
|
+
})}
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</span>
|
41
|
+
)
|
42
|
+
} else {
|
43
|
+
// must return empty alert span so screenreaders
|
44
|
+
// read the error when it is inserted
|
45
|
+
return <span role="alert" />
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
changedFontFamily(value) {
|
50
|
+
// fail fast for no value
|
51
|
+
if (!value) return null
|
52
|
+
|
53
|
+
// set and read fontFamily values from a dom node to get only valid values
|
54
|
+
const tempNode = document.createElement('span')
|
55
|
+
tempNode.style.fontFamily = value
|
56
|
+
const fontFamily = tempNode.style.fontFamily
|
57
|
+
|
58
|
+
// reject invalid values
|
59
|
+
if (!fontFamily) return null
|
60
|
+
|
61
|
+
return fontFamily
|
62
|
+
}
|
63
|
+
|
64
|
+
inputChange = value => {
|
65
|
+
const invalidFontFamily = !!value && (!this.changedFontFamily(value))
|
66
|
+
this.props.onChange(value, invalidFontFamily)
|
67
|
+
if (!invalidFontFamily) {
|
68
|
+
this.props.handleThemeStateChange(this.props.varDef.variable_name, value)
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
inputNotFocused = () => this.textInput && this.textInput !== document.activeElement
|
73
|
+
|
74
|
+
updateIfMounted = () => {
|
75
|
+
this.forceUpdate()
|
76
|
+
}
|
77
|
+
|
78
|
+
textFontFamilyInput = () => (
|
79
|
+
<select
|
80
|
+
ref={c => (this.textInput = c)}
|
81
|
+
id={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
82
|
+
className={classnames({
|
83
|
+
'Theme__editor-fontFamily-block_input-text': true,
|
84
|
+
'Theme__editor-fontFamily-block_input': true,
|
85
|
+
'Theme__editor-fontFamily-block_input--has-error': this.props.userInput.invalid,
|
86
|
+
'custom-select': true
|
87
|
+
})}
|
88
|
+
style={{fontFamily: this.props.placeholder}}
|
89
|
+
aria-invalid={this.showWarning()}
|
90
|
+
onChange={event => this.inputChange(event.target.value)}
|
91
|
+
onBlur={this.updateIfMounted} >
|
92
|
+
|
93
|
+
{ fonts.map((font, key) => {
|
94
|
+
if(font == this.props.placeholder){
|
95
|
+
return (<option
|
96
|
+
key={key}
|
97
|
+
value={font}
|
98
|
+
style={{fontFamily: font}}
|
99
|
+
selected
|
100
|
+
>
|
101
|
+
{font}
|
102
|
+
</option>)
|
103
|
+
}else{
|
104
|
+
return (<option
|
105
|
+
key={key}
|
106
|
+
value={font}
|
107
|
+
style={{fontFamily: font}}
|
108
|
+
>
|
109
|
+
{font}
|
110
|
+
</option>)
|
111
|
+
}
|
112
|
+
})}
|
113
|
+
|
114
|
+
</select>
|
115
|
+
)
|
116
|
+
|
117
|
+
render() {
|
118
|
+
const fontFamilyInputValue = this.props.placeholder !== 'none' ? this.props.placeholder : null
|
119
|
+
return (
|
120
|
+
<section className="Theme__editor-accordion_element Theme__editor-fontFamily ic-Form-control border border-dark mt-1 mb-1 p-1 rounded">
|
121
|
+
<div className="Theme__editor-form--fontFamily">
|
122
|
+
<label
|
123
|
+
htmlFor={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
124
|
+
className="Theme__editor-fontFamily_title h6"
|
125
|
+
>
|
126
|
+
{this.props.varDef.human_name}
|
127
|
+
</label>
|
128
|
+
<hr />
|
129
|
+
<div className="Theme__editor-fontFamily-block border p-2">
|
130
|
+
{this.textFontFamilyInput()}
|
131
|
+
{this.warningLabel()}
|
132
|
+
<p
|
133
|
+
className="Theme__editor-fontFamily-label Theme__editor-fontFamily-block_label-sample border text-center shadow"
|
134
|
+
style={{fontFamily: this.props.placeholder}}
|
135
|
+
/* this <p> and <input type=fontFamily> are here so if you click the 'sample',
|
136
|
+
it will pop up a fontFamily picker on browsers that support it */
|
137
|
+
>
|
138
|
+
Text Example
|
139
|
+
</p>
|
140
|
+
</div>
|
141
|
+
</div>
|
142
|
+
</section>
|
143
|
+
)
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
export default ThemeEditorFontFamilyRow
|
@@ -0,0 +1,152 @@
|
|
1
|
+
import React, {Component} from 'react'
|
2
|
+
import PropTypes from 'prop-types'
|
3
|
+
import customTypes from './PropTypes'
|
4
|
+
import I18n from 'i18n!theme_editor'
|
5
|
+
import classnames from 'classnames'
|
6
|
+
|
7
|
+
export class ThemeEditorFontSizeRow extends Component {
|
8
|
+
static propTypes = {
|
9
|
+
varDef: customTypes.fontSize,
|
10
|
+
onChange: PropTypes.func.isRequired,
|
11
|
+
userInput: customTypes.userVariableInput,
|
12
|
+
placeholder: PropTypes.string.isRequired,
|
13
|
+
themeState: PropTypes.object,
|
14
|
+
handleThemeStateChange: PropTypes.func
|
15
|
+
}
|
16
|
+
|
17
|
+
static defaultProps = {
|
18
|
+
userInput: {},
|
19
|
+
themeState: {},
|
20
|
+
handleThemeStateChange() {}
|
21
|
+
}
|
22
|
+
|
23
|
+
state = {}
|
24
|
+
|
25
|
+
showWarning = () => this.props.userInput.invalid && this.inputNotFocused()
|
26
|
+
|
27
|
+
warningLabel = () => {
|
28
|
+
if (this.showWarning()) {
|
29
|
+
return (
|
30
|
+
<span role="alert">
|
31
|
+
<div className="ic-Form-message ic-Form-message--error" tabIndex="0">
|
32
|
+
<div className="ic-Form-message__Layout">
|
33
|
+
<i className="icon-warning" role="presentation" />
|
34
|
+
{I18n.t("'%{chosenFontSize}' is not a valid fontSize.", {
|
35
|
+
chosenFontSize: this.props.userInput.val
|
36
|
+
})}
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</span>
|
40
|
+
)
|
41
|
+
} else {
|
42
|
+
// must return empty alert span so screenreaders
|
43
|
+
// read the error when it is inserted
|
44
|
+
return <span role="alert" />
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
changedFontSize(value) {
|
49
|
+
let val = value.slice(0, (value.length - 2))
|
50
|
+
|
51
|
+
// fail fast for no value
|
52
|
+
if (!value) return null
|
53
|
+
|
54
|
+
// set and read fontSize values from a dom node to get only valid values
|
55
|
+
const tempNode = document.createElement('span')
|
56
|
+
tempNode.style.fontSize = value
|
57
|
+
const fontSize = tempNode.style.fontSize
|
58
|
+
|
59
|
+
// reject invalid values
|
60
|
+
if (!fontSize) return null
|
61
|
+
|
62
|
+
return fontSize
|
63
|
+
}
|
64
|
+
|
65
|
+
invalidNumber(sizeValue) {
|
66
|
+
console.log(sizeValue);
|
67
|
+
let val = sizeValue.slice(0, (sizeValue.length - 2))
|
68
|
+
console.log(val);
|
69
|
+
console.log(+val != NaN);
|
70
|
+
console.log((+val).toString().length == val.length);
|
71
|
+
console.log((+val > 4 && +val < 73));
|
72
|
+
console.log((+val).toString().length == val.length && +val > 4 && +val < 73);
|
73
|
+
|
74
|
+
return (+val == NaN) ? false : ((+val).toString().length != val.length && +val < 5 && +val > 72)
|
75
|
+
}
|
76
|
+
|
77
|
+
inputChange = value => {
|
78
|
+
let val;
|
79
|
+
if (value.includes("px")) {
|
80
|
+
val = value
|
81
|
+
}else{
|
82
|
+
val = `${value}px`;
|
83
|
+
}
|
84
|
+
|
85
|
+
const invalidFontSize = !!val && (!this.changedFontSize(val)) || this.invalidNumber(val)
|
86
|
+
this.props.onChange(val, invalidFontSize)
|
87
|
+
if (!invalidFontSize) {
|
88
|
+
this.props.handleThemeStateChange(this.props.varDef.variable_name, val)
|
89
|
+
}
|
90
|
+
}
|
91
|
+
|
92
|
+
inputNotFocused = () => this.textInput && this.textInput !== document.activeElement
|
93
|
+
|
94
|
+
updateIfMounted = () => {
|
95
|
+
this.forceUpdate()
|
96
|
+
}
|
97
|
+
|
98
|
+
textFontSizeInput = () => (
|
99
|
+
<span>
|
100
|
+
<input
|
101
|
+
ref={c => (this.textInput = c)}
|
102
|
+
type="text"
|
103
|
+
name="fontSize"
|
104
|
+
id={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
105
|
+
className={classnames({
|
106
|
+
'Theme__editor-fontSize-block_input-text': true,
|
107
|
+
'Theme__editor-fontSize-block_input': true,
|
108
|
+
'Theme__editor-fontSize-block_input--has-error': this.props.userInput.invalid,
|
109
|
+
'form-control': true
|
110
|
+
})}
|
111
|
+
placeholder={this.props.placeholder}
|
112
|
+
value={this.props.themeState[this.props.varDef.variable_name]}
|
113
|
+
aria-invalid={this.showWarning()}
|
114
|
+
onChange={event => this.inputChange(event.target.value)}
|
115
|
+
onBlur={this.updateIfMounted}
|
116
|
+
/>
|
117
|
+
</span>
|
118
|
+
)
|
119
|
+
|
120
|
+
render() {
|
121
|
+
const fontSizeInputValue = this.props.placeholder !== 'none' ? this.props.placeholder : null
|
122
|
+
return (
|
123
|
+
<section className="Theme__editor-accordion_element Theme__editor-fontFamily ic-Form-control border border-dark mt-1 mb-1 p-1 rounded">
|
124
|
+
<div className="Theme__editor-form--fontSize">
|
125
|
+
<label
|
126
|
+
htmlFor={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
127
|
+
className="Theme__editor-fontSize_title h6"
|
128
|
+
>
|
129
|
+
{this.props.varDef.human_name}
|
130
|
+
</label>
|
131
|
+
<hr />
|
132
|
+
<div className="Theme__editor-fontSize-block border p-2">
|
133
|
+
{this.textFontSizeInput()}
|
134
|
+
{this.warningLabel()}\
|
135
|
+
<br />
|
136
|
+
<small>Hint: Valid from 5 till 72 size!</small>
|
137
|
+
<p
|
138
|
+
className="Theme__editor-fontSize-label Theme__editor-fontSize-block_label-sample border text-center shadow"
|
139
|
+
style={{fontSize: this.props.placeholder}}
|
140
|
+
/* this <p> and <input type=fontSize> are here so if you click the 'sample',
|
141
|
+
it will pop up a fontSize picker on browsers that support it */
|
142
|
+
>
|
143
|
+
Text Example
|
144
|
+
</p>
|
145
|
+
</div>
|
146
|
+
</div>
|
147
|
+
</section>
|
148
|
+
)
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
export default ThemeEditorFontSizeRow
|
@@ -0,0 +1,176 @@
|
|
1
|
+
import React, {Component} from 'react'
|
2
|
+
import PropTypes from 'prop-types'
|
3
|
+
import customTypes from './PropTypes'
|
4
|
+
import I18n from 'i18n!theme_editor'
|
5
|
+
import classnames from 'classnames'
|
6
|
+
|
7
|
+
export class ThemeEditorFontWeightRow extends Component {
|
8
|
+
static propTypes = {
|
9
|
+
varDef: customTypes.fontWeight,
|
10
|
+
onChange: PropTypes.func.isRequired,
|
11
|
+
userInput: customTypes.userVariableInput,
|
12
|
+
placeholder: PropTypes.string.isRequired,
|
13
|
+
themeState: PropTypes.object,
|
14
|
+
handleThemeStateChange: PropTypes.func
|
15
|
+
}
|
16
|
+
|
17
|
+
static defaultProps = {
|
18
|
+
userInput: {},
|
19
|
+
themeState: {},
|
20
|
+
handleThemeStateChange() {}
|
21
|
+
}
|
22
|
+
|
23
|
+
state = {}
|
24
|
+
|
25
|
+
showWarning = () => this.props.userInput.invalid && this.inputNotFocused()
|
26
|
+
|
27
|
+
warningLabel = () => {
|
28
|
+
if (this.showWarning()) {
|
29
|
+
return (
|
30
|
+
<span role="alert">
|
31
|
+
<div className="ic-Form-message ic-Form-message--error" tabIndex="0">
|
32
|
+
<div className="ic-Form-message__Layout">
|
33
|
+
<i className="icon-warning" role="presentation" />
|
34
|
+
{I18n.t("'%{chosenFontWeight}' is not a valid fontWeight.", {
|
35
|
+
chosenFontWeight: this.props.userInput.val
|
36
|
+
})}
|
37
|
+
</div>
|
38
|
+
</div>
|
39
|
+
</span>
|
40
|
+
)
|
41
|
+
} else {
|
42
|
+
// must return empty alert span so screenreaders
|
43
|
+
// read the error when it is inserted
|
44
|
+
return <span role="alert" />
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
changedFontWeight(value) {
|
49
|
+
// fail fast for no value
|
50
|
+
if (!value) return null
|
51
|
+
|
52
|
+
// set and read fontWeight values from a dom node to get only valid values
|
53
|
+
const tempNode = document.createElement('span')
|
54
|
+
tempNode.style.fontWeight = value
|
55
|
+
const fontWeight = tempNode.style.fontWeight
|
56
|
+
|
57
|
+
// reject invalid values
|
58
|
+
if (!fontWeight) return null
|
59
|
+
|
60
|
+
return fontWeight
|
61
|
+
}
|
62
|
+
|
63
|
+
inputChange = value => {
|
64
|
+
const invalidFontWeight = !!value && (!this.changedFontWeight(value))
|
65
|
+
this.props.onChange(value, invalidFontWeight)
|
66
|
+
if (!invalidFontWeight) {
|
67
|
+
this.props.handleThemeStateChange(this.props.varDef.variable_name, value)
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
inputNotFocused = () => this.textInput && this.textInput !== document.activeElement
|
72
|
+
|
73
|
+
updateIfMounted = () => {
|
74
|
+
this.forceUpdate()
|
75
|
+
}
|
76
|
+
|
77
|
+
textFontWeightInput = () => (
|
78
|
+
<span>
|
79
|
+
<input
|
80
|
+
ref={c => (this.textInput = c)}
|
81
|
+
type="radio"
|
82
|
+
name="fontWeight"
|
83
|
+
id={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
84
|
+
className={classnames({
|
85
|
+
'Theme__editor-fontWeight-block_input-text': true,
|
86
|
+
'Theme__editor-fontWeight-block_input': true,
|
87
|
+
'Theme__editor-fontWeight-block_input--has-error': this.props.userInput.invalid
|
88
|
+
})}
|
89
|
+
placeholder={this.props.placeholder}
|
90
|
+
value="lighter"
|
91
|
+
aria-invalid={this.showWarning()}
|
92
|
+
onChange={event => this.inputChange(event.target.value)}
|
93
|
+
onBlur={this.updateIfMounted}
|
94
|
+
/>Lighter<br />
|
95
|
+
<input
|
96
|
+
ref={c => (this.textInput = c)}
|
97
|
+
type="radio"
|
98
|
+
name="fontWeight"
|
99
|
+
id={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
100
|
+
className={classnames({
|
101
|
+
'Theme__editor-fontWeight-block_input-text': true,
|
102
|
+
'Theme__editor-fontWeight-block_input': true,
|
103
|
+
'Theme__editor-fontWeight-block_input--has-error': this.props.userInput.invalid
|
104
|
+
})}
|
105
|
+
placeholder={this.props.placeholder}
|
106
|
+
value="normal"
|
107
|
+
aria-invalid={this.showWarning()}
|
108
|
+
onChange={event => this.inputChange(event.target.value)}
|
109
|
+
onBlur={this.updateIfMounted}
|
110
|
+
/>Normal<br />
|
111
|
+
<input
|
112
|
+
ref={c => (this.textInput = c)}
|
113
|
+
type="radio"
|
114
|
+
name="fontWeight"
|
115
|
+
id={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
116
|
+
className={classnames({
|
117
|
+
'Theme__editor-fontWeight-block_input-text': true,
|
118
|
+
'Theme__editor-fontWeight-block_input': true,
|
119
|
+
'Theme__editor-fontWeight-block_input--has-error': this.props.userInput.invalid
|
120
|
+
})}
|
121
|
+
placeholder={this.props.placeholder}
|
122
|
+
value="bold"
|
123
|
+
aria-invalid={this.showWarning()}
|
124
|
+
onChange={event => this.inputChange(event.target.value)}
|
125
|
+
onBlur={this.updateIfMounted}
|
126
|
+
/>Bold<br />
|
127
|
+
<input
|
128
|
+
ref={c => (this.textInput = c)}
|
129
|
+
type="radio"
|
130
|
+
name="fontWeight"
|
131
|
+
id={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
132
|
+
className={classnames({
|
133
|
+
'Theme__editor-fontWeight-block_input-text': true,
|
134
|
+
'Theme__editor-fontWeight-block_input': true,
|
135
|
+
'Theme__editor-fontWeight-block_input--has-error': this.props.userInput.invalid
|
136
|
+
})}
|
137
|
+
placeholder={this.props.placeholder}
|
138
|
+
value="bolder"
|
139
|
+
aria-invalid={this.showWarning()}
|
140
|
+
onChange={event => this.inputChange(event.target.value)}
|
141
|
+
onBlur={this.updateIfMounted}
|
142
|
+
/>Bolder
|
143
|
+
</span>
|
144
|
+
)
|
145
|
+
|
146
|
+
render() {
|
147
|
+
const fontWeightInputValue = this.props.placeholder !== 'none' ? this.props.placeholder : null
|
148
|
+
return (
|
149
|
+
<section className="Theme__editor-accordion_element Theme__editor-fontWeight ic-Form-control border border-dark mt-1 mb-1 p-1 rounded">
|
150
|
+
<div className="Theme__editor-form--fontWeight">
|
151
|
+
<label
|
152
|
+
htmlFor={`brand_config[variables][${this.props.varDef.variable_name}]`}
|
153
|
+
className="Theme__editor-fontWeight_title h6"
|
154
|
+
>
|
155
|
+
{this.props.varDef.human_name}
|
156
|
+
</label>
|
157
|
+
<hr />
|
158
|
+
<div className="Theme__editor-fontWeight-block border p-2">
|
159
|
+
{this.textFontWeightInput()}
|
160
|
+
{this.warningLabel()}
|
161
|
+
<p
|
162
|
+
className="Theme__editor-fontWeight-label Theme__editor-fontWeight-block_label-sample border text-center shadow"
|
163
|
+
style={{fontWeight: this.props.placeholder}}
|
164
|
+
/* this <p> and <input type=fontWeight> are here so if you click the 'sample',
|
165
|
+
it will pop up a fontWeight picker on browsers that support it */
|
166
|
+
>
|
167
|
+
Text Example
|
168
|
+
</p>
|
169
|
+
</div>
|
170
|
+
</div>
|
171
|
+
</section>
|
172
|
+
)
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
export default ThemeEditorFontWeightRow
|