Skip to content

Commit

Permalink
Add grid areas to fields and buttons
Browse files Browse the repository at this point in the history
This commit gives fields and buttons default grid template areas
with an option to turn them off.
  • Loading branch information
hew authored and joegaudet committed Mar 10, 2023
1 parent f8f248a commit 2d20c90
Show file tree
Hide file tree
Showing 13 changed files with 1,197 additions and 32,811 deletions.
1 change: 1 addition & 0 deletions addon/components/field-for.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
this.using
"-field"
}}
{{style grid-area=this.gridArea}}
{{on "change" (stop-propagation)}}
...attributes
data-test-field-for={{this._testingSelector}}
Expand Down
30 changes: 28 additions & 2 deletions addon/components/field-for.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { arg } from 'ember-arg-types';
import { array, func, bool, string, object, any } from 'prop-types';
import { array, func, bool, string, object, any, oneOfType } from 'prop-types';
import { oneWay, notEmpty, gt, union, readOnly } from '@ember/object/computed';
import { dasherize } from '@ember/string';
import { isArray } from '@ember/array';
Expand Down Expand Up @@ -102,6 +102,16 @@ export default class FieldForComponent extends Component {
@readOnly('formFor.fieldClasses') fieldClasses;
@readOnly('formFor.testingClassPrefix') testingClassPrefix;

/**
* Disable named grid areas at the prop level by default
* @param {String} gridAreaName
* @public
*/
@arg(bool)
get useGridTemplate() {
return this.args?.form?.useGridTemplate ?? false;
}

/**
* Whether or not this field is a composite value, meaning
* that it exposes more than one value to the control layer
Expand All @@ -126,7 +136,7 @@ export default class FieldForComponent extends Component {
*
* @returns {String}
*/
@arg(string)
@arg(oneOfType([array, string]))
for = '';

/**
Expand Down Expand Up @@ -253,6 +263,22 @@ export default class FieldForComponent extends Component {
return !(this.isDestroyed && this.isDestroying) && this._valueIsDirty && this._valueIsNotBlank;
}

/**
* The name of the field's grid area
* @property gridArea
* @type String
* @default false
* @public
*/
get gridArea() {
return this.useGridTemplate ? this._gridAreaName : 'auto';
}

get _gridAreaName() {
const prefix = this.args.form.gridTemplatePrefix ?? '';
return `${prefix}${this._dasherizedParams}`;
}

get _valueIsDirty() {
return this._stringify(this._lastValidValue) !== this._stringify(this.value);
}
Expand Down
1 change: 1 addition & 0 deletions addon/components/form-button.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"
type={{if (eq this.buttonType "submit") "submit" "button"}}
disabled={{@disabled}}
{{style grid-area=this.gridArea}}
...attributes
data-test-form-button="{{this.buttonType}}"
{{on "click" (stop-propagation this.handleClick)}}
Expand Down
36 changes: 34 additions & 2 deletions addon/components/form-button.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { arg } from 'ember-arg-types';
import { string, bool } from 'prop-types';
import { action } from '@ember/object';

export default class FormButtonComponent extends Component {
@arg
/**
* The type of button (ie, submit)
* @param {String} buttonType
* @public
*/
@arg(string)
buttonType = 'button';

/**
* Disable named grid areas at the prop level by default
* @param {String} useGridTemplate
* @public
*/
@arg(bool)
get useGridTemplate() {
return this.args?.form?.useGridTemplate ?? false;
}

/**
* The name of the button's grid area
* @property gridArea
* @type String
* @default false
* @public
*/
get gridArea() {
return this.useGridTemplate ? this._gridAreaName : 'auto';
}

get _gridAreaName() {
const prefix = this.args.form.gridTemplatePrefix ?? '';
return `${prefix}${this.buttonType}`;
}

@tracked
isActing = false;

Expand Down
4 changes: 4 additions & 0 deletions addon/components/form-for.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
)
buttonActingClass=this.buttonActingClass
buttonType="button"
form=this
)
submit=(component
this.buttonComponent
Expand All @@ -41,6 +42,7 @@
buttonType="submit"
onClick=this.alternativeSubmit
disabled=this.isSubmitButtonDisabled
form=this
)
reset=(component
this.buttonComponent
Expand All @@ -56,6 +58,7 @@
isActing=this.isResetting
onClick=this.reset
buttonType="reset"
form=this
)
destroy=(component
this.buttonComponent
Expand All @@ -71,6 +74,7 @@
isActing=this.isDestroyingRecord
onClick=(fn this.confirmDestroy this.model)
buttonType="destroy"
form=this
)
errors=(component
"errors-for" errors=this.errors customErrorComponent=this.formFor.customErrorComponent
Expand Down
20 changes: 17 additions & 3 deletions addon/components/form-for.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Component from '@glimmer/component';
import { arg, func } from 'ember-arg-types';
import { bool, string, object, boolean } from 'prop-types';
import { bool, string, object } from 'prop-types';
import { next } from '@ember/runloop';
import { dasherize } from '@ember/string';
import { action, setProperties, notifyPropertyChange } from '@ember/object';
Expand Down Expand Up @@ -83,6 +83,8 @@ export default class FormForComponent extends Component {
@readOnly('formFor.testingClassPrefix') testingClassPrefix;
@readOnly('formFor.bemClassPrefix') bemClassPrefix;
@readOnly('formFor.useBemClass') useBemClassConfig;
@readOnly('formFor.gridTemplatePrefix') gridTemplatePrefix;
@readOnly('formFor.useGridTemplate') useGridTemplateConfig;
@readOnly('formFor.formClasses') formClasses;
@readOnly('formFor.buttonClasses') buttonClasses;
@readOnly('formFor.submittingClass') _submittingClasses;
Expand Down Expand Up @@ -155,6 +157,18 @@ export default class FormForComponent extends Component {
return this.useBemClassConfig || false;
}

/**
* Whether or not this form uses grid template areas in inline styles
* @property useGridTemplate
* @type boolean
* @default false
* @public
*/
@arg(bool)
get useGridTemplate() {
return this.useGridTemplateConfig || false;
}

@arg(string)
get submittingClasses() {
return this._submittingClasses;
Expand Down Expand Up @@ -405,7 +419,7 @@ export default class FormForComponent extends Component {
* @default true
* @public
*/
@arg(boolean)
@arg(bool)
confirmsDestroy = true;

/**
Expand Down Expand Up @@ -495,7 +509,7 @@ export default class FormForComponent extends Component {
@arg(string)
modelName = null;

@arg(boolean)
@arg(bool)
useCustomButtonComponent = true;

@arg(bool)
Expand Down
1 change: 1 addition & 0 deletions addon/services/form-for.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default class FormForService extends Service {
this.testingClassPrefix = this.config.testingClassPrefix;
this.bemClassPrefix = this.config.bemClassPrefix;
this.useBemClass = this.config.useBemClass;
this.useGridTemplate = this.config.useGridTemplate;
this.submittingClasses = this.config.submittingClasses;
this.fieldClasses = this.config.fieldClasses;
this.formClasses = this.config.formClasses;
Expand Down
2 changes: 2 additions & 0 deletions config/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ module.exports = function (/* environment, appConfig */) {
formClasses: 'form',
bemClassPrefix: '',
useBemClass: false,
gridTemplatePrefix: '',
useGridTemplate: false,
fieldForControlCalloutClasses: 'field-for-control-callout',
fieldForControlCalloutPosition: 'bottom left',
showRequiredIndicator: true,
Expand Down
Loading

0 comments on commit 2d20c90

Please sign in to comment.