dlg-ui 1.0.27 → 1.0.29

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 (40) hide show
  1. package/addon/components/checkbox-group.hbs +15 -0
  2. package/addon/components/checkbox-group.js +31 -0
  3. package/addon/components/checkbox.hbs +11 -0
  4. package/addon/components/checkbox.js +23 -0
  5. package/addon/components/date-picker.hbs +13 -0
  6. package/addon/components/date-picker.js +19 -0
  7. package/addon/components/dropdown.hbs +6 -3
  8. package/addon/components/dropdown.js +23 -21
  9. package/addon/components/form/field.hbs +18 -0
  10. package/addon/components/form/field.js +29 -0
  11. package/addon/components/form.hbs +8 -0
  12. package/addon/components/form.js +26 -0
  13. package/addon/components/header-dropdown.js +20 -20
  14. package/addon/components/modal.hbs +20 -0
  15. package/addon/components/modal.js +25 -0
  16. package/addon/components/radio.hbs +3 -4
  17. package/addon/components/radio.js +17 -16
  18. package/addon/components/text-input.hbs +12 -0
  19. package/addon/components/text-input.js +24 -0
  20. package/addon/styles/addon.css +2 -1
  21. package/addon/styles/button.css +1 -1
  22. package/addon/styles/checkbox.css +5 -0
  23. package/addon/styles/date-picker.css +16 -0
  24. package/addon/styles/dropdown.css +9 -1
  25. package/addon/styles/form.css +34 -0
  26. package/addon/styles/modal.css +49 -0
  27. package/addon/styles/navbar.css +2 -1
  28. package/addon/styles/text-input.css +21 -0
  29. package/addon/validations/base-validator.js +11 -0
  30. package/addon/validations/presence.js +24 -0
  31. package/addon/validations/validation-builder.js +28 -0
  32. package/app/components/checkbox-group.js +1 -0
  33. package/app/components/checkbox.js +1 -0
  34. package/app/components/date-picker.js +1 -0
  35. package/app/components/form/field.js +1 -0
  36. package/app/components/form.js +1 -0
  37. package/app/components/modal.js +1 -0
  38. package/app/components/text-input.js +1 -0
  39. package/index.js +6 -1
  40. package/package.json +5 -5
@@ -0,0 +1,15 @@
1
+ <div class={{@class}} {{did-insert this.initCheckboxGroup}}>
2
+ <div class="label">
3
+ {{this.args.label}}
4
+ </div>
5
+ <div>
6
+ {{#each this.args.options as |option|}}
7
+ <Checkbox
8
+ @model={{this.value}}
9
+ @valuePath={{option.label}}
10
+ @option={{option}}
11
+ @onChange={{this.onChange}}
12
+ />
13
+ {{/each}}
14
+ </div>
15
+ </div>
@@ -0,0 +1,31 @@
1
+ import Component from '@glimmer/component';
2
+ import { get, set } from '@ember/object';
3
+
4
+ export default class CheckboxGroupComponent extends Component {
5
+ get value() {
6
+ const value = get(this.args.model, this.args.valuePath);
7
+ return value !== undefined ? value : this.placeholder;
8
+ }
9
+
10
+ set value(newValue) {
11
+ set(this.args.model, this.args.valuePath, newValue);
12
+ return newValue;
13
+ }
14
+
15
+ initCheckboxGroup = () => {
16
+ if (typeof this.value !== 'object') {
17
+ this.value = {};
18
+ }
19
+ this.args.options.forEach(option => {
20
+ if (this.value[option.label] === undefined) {
21
+ set(this.value, option.label, false);
22
+ } else {
23
+ set(this.value, option.label, this.value[option.label]);
24
+ }
25
+ });
26
+ }
27
+
28
+ onChange = (value) => {
29
+ this.args.onChange?.(value);
30
+ }
31
+ }
@@ -0,0 +1,11 @@
1
+ <div class={{@class}}>
2
+ <div class="label">
3
+ {{this.args.label}}
4
+ </div>
5
+ <div class="checkbox-container">
6
+ <div>
7
+ <input type="checkbox" id="checkboxId" checked={{this.value}} {{on "change" (fn this.onChange)}} />
8
+ <label for="checkboxId">{{@option.label}}</label>
9
+ </div>
10
+ </div>
11
+ </div>
@@ -0,0 +1,23 @@
1
+ import Component from '@glimmer/component';
2
+ import { get, set } from '@ember/object';
3
+
4
+ export default class CheckboxComponent extends Component {
5
+ get value() {
6
+ const value = get(this.args.model, this.args.valuePath);
7
+ return value !== undefined ? value : this.placeholder;
8
+ }
9
+
10
+ set value(newValue) {
11
+ set(this.args.model, this.args.valuePath, newValue);
12
+ return newValue;
13
+ }
14
+
15
+ onChange = () => {
16
+ if (this.value === undefined) {
17
+ this.value = true;
18
+ } else {
19
+ this.value = !this.value;
20
+ }
21
+ this.args.onChange?.(this.value);
22
+ }
23
+ }
@@ -0,0 +1,13 @@
1
+ <div class="date-picker-wrapper {{@class}}">
2
+ <div class="label">
3
+ {{this.args.label}}
4
+ </div>
5
+ <input
6
+ class="date-picker"
7
+ type="date"
8
+ id="start"
9
+ name="trip-start"
10
+ value={{this.value}}
11
+ {{on "input" this.onChange}}
12
+ />
13
+ </div>
@@ -0,0 +1,19 @@
1
+ import Component from '@glimmer/component';
2
+ import { get, set } from '@ember/object';
3
+
4
+ export default class DatePickerComponent extends Component {
5
+ get value() {
6
+ const value = get(this.args.model, this.args.valuePath);
7
+ return value !== undefined ? value : this.placeholder;
8
+ }
9
+
10
+ set value(newValue) {
11
+ set(this.args.model, this.args.valuePath, newValue);
12
+ return newValue;
13
+ }
14
+
15
+ onChange = (event) => {
16
+ this.value = event.target.value;
17
+ this.args.onChange?.(this.value);
18
+ }
19
+ }
@@ -1,7 +1,10 @@
1
1
  <div class='dropdown-wrapper {{@class}}' {{did-insert this.loadClickListener}}>
2
+ <div class='label'>
3
+ {{this.args.label}}
4
+ </div>
2
5
  <div class='dropdown-select {{if this.isOpen "open"}}'>
3
- {{#if this.selectedOption}}
4
- {{this.selectedOption.label}}
6
+ {{#if this.value.label}}
7
+ {{this.value.label}}
5
8
  {{! TODO - If there is no label, then they submitted just strings and we can use those for a dropdown }}
6
9
  {{else}}
7
10
  <span class='dropdown-placeholder'>
@@ -10,7 +13,7 @@
10
13
  {{/if}}
11
14
  </div>
12
15
  <div class={{this.dropdownClass}}>
13
- {{#each @options as |option|}}
16
+ {{#each this.options as |option|}}
14
17
  <div
15
18
  class='dropdown-option'
16
19
  {{on 'click' (fn this.makeSelection option)}}
@@ -1,10 +1,9 @@
1
1
  import Component from '@glimmer/component';
2
- import { action } from '@ember/object';
2
+ import { action, get, set } from '@ember/object';
3
3
  import { tracked } from '@glimmer/tracking';
4
4
 
5
5
  export default class DropdownComponent extends Component {
6
6
  @tracked isOpen = false;
7
- @tracked _selectedOption = this.args.selectedOption;
8
7
 
9
8
  get dropdownClass() {
10
9
  if (this.isOpen) {
@@ -14,12 +13,13 @@ export default class DropdownComponent extends Component {
14
13
  }
15
14
  }
16
15
 
17
- get selectedOption() {
18
- if (this.args.selectedOption) {
19
- return this.args.selectedOption;
20
- } else {
21
- null;
22
- }
16
+ get options() {
17
+ let options = [];
18
+ options.push({ label: null });
19
+ this.args.options.forEach((option) => {
20
+ options.push(option);
21
+ });
22
+ return options;
23
23
  }
24
24
 
25
25
  get placeholder() {
@@ -30,26 +30,28 @@ export default class DropdownComponent extends Component {
30
30
  }
31
31
  }
32
32
 
33
+ get value() {
34
+ const value = get(this.args.model, this.args.valuePath);
35
+ return value !== undefined ? value : this.placeholder;
36
+ }
37
+
38
+ set value(newValue) {
39
+ set(this.args.model, this.args.valuePath, newValue);
40
+ return newValue;
41
+ }
42
+
33
43
  constructor() {
34
44
  super(...arguments);
35
- if (!this.args.onSelect) {
36
- console.warn('Dropdown 2-way binding needs an onSelect action');
37
- }
38
45
  if (!this.args.options) {
39
46
  throw new Error('Dropdown requires an options array');
40
47
  }
41
- if (this.args.forceSelection && !this.args.selectedOption) {
42
- throw new Error(
43
- 'Dropdown requires a selected option when forceSelection is true'
44
- );
45
- }
46
48
  }
47
49
 
48
50
  saveSelection(value) {
49
51
  if (!this.args.preventDefault) {
50
- this._selectedOption = value;
52
+ this.value = value;
51
53
  }
52
- this.args.onSelect(value);
54
+ this.args.onSelect?.(value);
53
55
  }
54
56
 
55
57
  @action
@@ -75,12 +77,12 @@ export default class DropdownComponent extends Component {
75
77
 
76
78
  @action
77
79
  makeSelection(option) {
78
- if (!this.args.forceSelection && option === this.selectedOption) {
80
+ if (option === this.value) {
79
81
  this.saveSelection(null);
80
- this.isOpen = false;
81
82
  } else {
82
83
  this.saveSelection(option);
83
- this.isOpen = false;
84
84
  }
85
+ this.isOpen = false;
86
+ this.args.onChange?.(this.value);
85
87
  }
86
88
  }
@@ -0,0 +1,18 @@
1
+ <div class="form-field">
2
+ <div class="label">
3
+ {{@label}} {{#if @required}}<span class="required">*</span>{{/if}}
4
+ </div>
5
+ <div class="field-input {{if this.error "has-error"}}">
6
+ {{yield (hash
7
+ Checkbox=(component "checkbox" valuePath=@valuePath class="field-border" onChange=this.onChange)
8
+ CheckboxGroup=(component "checkbox-group" valuePath=@valuePath class="field-border" onChange=this.onChange)
9
+ DatePicker=(component "date-picker" valuePath=@valuePath onChange=this.onChange)
10
+ Dropdown=(component "dropdown" valuePath=@valuePath onChange=this.onChange)
11
+ Radio=(component "radio" valuePath=@valuePath class="field-border" onChange=this.onChange)
12
+ TextInput=(component "text-input" valuePath=@valuePath onChange=this.onChange)
13
+ )}}
14
+ </div>
15
+ <div class="field-validation">
16
+ {{this.error}}
17
+ </div>
18
+ </div>
@@ -0,0 +1,29 @@
1
+ import Component from '@glimmer/component';
2
+ import PresenceValidator from '../../validations/presence';
3
+
4
+ export default class FormFieldComponent extends Component {
5
+ get error() {
6
+ return this.args.errors?.[this.args.valuePath] || null;
7
+ }
8
+
9
+ get fieldType() {
10
+ return this.args.field?.constructor?.name || null;
11
+ }
12
+
13
+ get didValidate() {
14
+ return this.args.didValidate;
15
+ }
16
+
17
+ constructor() {
18
+ super(...arguments);
19
+ if (this.args.required) {
20
+ this.args.addValidator(new PresenceValidator(this.args.valuePath));
21
+ }
22
+ }
23
+
24
+ onChange = () => {
25
+ if (this.didValidate) {
26
+ this.args.validate();
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,8 @@
1
+ <div class="form-wrapper {{@class}}">
2
+ <form>
3
+ {{yield (hash Field=(component "form/field" addValidator=this.addValidator didValidate=this.didValidate errors=this.errors validate=this.validate))}}
4
+ </form>
5
+ <ButtonPrimary @onClick={{this.submitForm}}>
6
+ Submit
7
+ </ButtonPrimary>
8
+ </div>
@@ -0,0 +1,26 @@
1
+ import Component from '@glimmer/component';
2
+ import ValidationBuilder from '../validations/validation-builder';
3
+ import { tracked } from '@glimmer/tracking';
4
+
5
+ export default class FormComponent extends Component {
6
+ @tracked validations = new ValidationBuilder();
7
+ @tracked errors = null;
8
+
9
+ get didValidate() {
10
+ return this.validations.didValidate;
11
+ }
12
+
13
+ addValidator = (validator) => {
14
+ this.validations.addValidation(validator);
15
+ }
16
+
17
+ submitForm = () => {
18
+ this.validate();
19
+ }
20
+
21
+ validate = () => {
22
+ let res = this.validations.validate(this.args.model);
23
+ console.log(res);
24
+ this.errors = res;
25
+ }
26
+ }
@@ -1,27 +1,18 @@
1
1
  import Component from '@glimmer/component';
2
- import { action } from '@ember/object';
2
+ import { action, get, set } from '@ember/object';
3
3
  import { tracked } from '@glimmer/tracking';
4
4
 
5
5
  export default class DropdownComponent extends Component {
6
6
  @tracked isOpen = false;
7
- @tracked _selectedOption = this.selectedOption;
8
7
 
9
8
  get displaySelectedOption() {
10
- if (this._selectedOption) {
11
- return this._selectedOption.label;
9
+ if (this.value?.label) {
10
+ return this.value.label;
12
11
  } else {
13
12
  return this.placeholder;
14
13
  }
15
14
  }
16
15
 
17
- get selectedOption() {
18
- if (this.args.selectedOption) {
19
- return this.args.selectedOption;
20
- } else {
21
- null;
22
- }
23
- }
24
-
25
16
  get placeholder() {
26
17
  if (this.args.placeholder) {
27
18
  return this.args.placeholder;
@@ -30,11 +21,21 @@ export default class DropdownComponent extends Component {
30
21
  }
31
22
  }
32
23
 
24
+ get value() {
25
+ if (!this.args.model || !this.args.valuePath) {
26
+ return undefined;
27
+ }
28
+ const value = get(this.args.model, this.args.valuePath);
29
+ return value !== undefined ? value : this.placeholder;
30
+ }
31
+
32
+ set value(newValue) {
33
+ set(this.args.model, this.args.valuePath, newValue);
34
+ return newValue;
35
+ }
36
+
33
37
  constructor() {
34
38
  super(...arguments);
35
- if (!this.args.onSelect) {
36
- console.warn('Dropdown 2-way binding needs an onSelect action');
37
- }
38
39
  if (!this.args.options) {
39
40
  throw new Error('Dropdown requires an options array');
40
41
  }
@@ -42,9 +43,9 @@ export default class DropdownComponent extends Component {
42
43
 
43
44
  saveSelection(value) {
44
45
  if (!this.args.preventDefault) {
45
- this._selectedOption = value;
46
+ this.value = value;
46
47
  }
47
- this.args.onSelect(value);
48
+ this.args.onSelect?.(value);
48
49
  }
49
50
 
50
51
  @action
@@ -71,12 +72,11 @@ export default class DropdownComponent extends Component {
71
72
 
72
73
  @action
73
74
  makeSelection(option) {
74
- if (option === this.selectedOption) {
75
- this.isOpen = false;
75
+ if (option === this.value) {
76
76
  } else {
77
77
  this.saveSelection(option);
78
- this.isOpen = false;
79
78
  }
79
+ this.isOpen = false;
80
80
  }
81
81
 
82
82
  @action
@@ -0,0 +1,20 @@
1
+ <div class="modal-backdrop {{if this.isOpen "modal-open" "modal-closed"}}">
2
+ <div class="modal">
3
+ <a {{on "click" this.toggleModal}}><FaIcon @icon={{this.icon}} class="modal-x"/></a>
4
+ <div class="modal-header">
5
+ <h1 style="margin-top: 0;">{{yield to="header"}}</h1>
6
+ </div>
7
+ <div class="modal-body">
8
+ {{yield to="body"}}
9
+ </div>
10
+ <div class="modal-footer">
11
+ <ButtonPrimary @onClick={{this.toggleModal}}>
12
+ Cancel
13
+ </ButtonPrimary>
14
+ <ButtonPrimary @onClick={{this.acceptAndClose}} style="margin-left: 1em;">
15
+ Done
16
+ </ButtonPrimary>
17
+ {{yield to="footer"}}
18
+ </div>
19
+ </div>
20
+ </div>
@@ -0,0 +1,25 @@
1
+ import Component from '@glimmer/component';
2
+ import { faCircleXmark } from '@fortawesome/free-solid-svg-icons';
3
+
4
+ export default class ModalComponent extends Component {
5
+ get isOpen() {
6
+ return this.args.isOpen ?? false;
7
+ }
8
+
9
+ get icon() {
10
+ return faCircleXmark;
11
+ }
12
+
13
+ acceptAndClose = () => {
14
+ if (this.args.onAccept) {
15
+ this.args.onAccept();
16
+ }
17
+ this.toggleModal();
18
+ }
19
+
20
+ toggleModal = () => {
21
+ if (this.args.toggleModal) {
22
+ this.args.toggleModal();
23
+ }
24
+ }
25
+ }
@@ -1,5 +1,5 @@
1
- <div class="radio-container">
2
- <div class="radio-label">
1
+ <div class="radio-container {{@class}}">
2
+ <div class="label">
3
3
  {{this.args.label}}
4
4
  </div>
5
5
  <div class="radio-options">
@@ -8,9 +8,8 @@
8
8
  <input
9
9
  type="radio"
10
10
  id={{option.label}}
11
- checked={{option.isChecked}}
11
+ checked={{eq option.label this.value.label}}
12
12
  name={{this.args.name}}
13
- checked={{option.isChecked}}
14
13
  {{on "change" (fn this.onChange option)}}
15
14
  />
16
15
  <label for={{option.label}}>
@@ -1,25 +1,26 @@
1
1
  import Component from '@glimmer/component';
2
- import { action } from '@ember/object';
3
- import { tracked } from '@glimmer/tracking';
2
+ import { get, set } from '@ember/object';
4
3
 
5
4
  export default class RadioComponent extends Component {
6
- @tracked
7
- selectedOption = this.args.defaultOption || {};
8
-
9
5
  get options() {
10
- let options = [];
11
- this.args.options.forEach((option) => {
12
- if (option.label === this.selectedOption.label) {
13
- option.isChecked = true;
14
- }
15
- options.push(option);
16
- });
17
6
  return this.args.options || [];
18
7
  }
19
8
 
20
- @action
21
- onChange(option) {
22
- this.selectedOption = option;
23
- this.args.onChange(option);
9
+ get value() {
10
+ if (!this.args.model || !this.args.valuePath) {
11
+ return undefined;
12
+ }
13
+ const value = get(this.args.model, this.args.valuePath);
14
+ return value !== undefined ? value : this.placeholder;
15
+ }
16
+
17
+ set value(newValue) {
18
+ set(this.args.model, this.args.valuePath, newValue);
19
+ return newValue;
20
+ }
21
+
22
+ onChange = (option) => {
23
+ this.value = option;
24
+ this.args.onChange?.(option);
24
25
  }
25
26
  }
@@ -0,0 +1,12 @@
1
+ <div class="text-input-wrapper">
2
+ <div class="label">
3
+ {{this.args.label}}
4
+ </div>
5
+ <input
6
+ type="text"
7
+ class="text-input"
8
+ placeholder={{this.args.placeholder}}
9
+ value={{this.value}}
10
+ {{on "input" this.updateValue}}
11
+ />
12
+ </div>
@@ -0,0 +1,24 @@
1
+ import Component from '@glimmer/component';
2
+ import { get, set } from '@ember/object';
3
+
4
+ export default class TextInputComponent extends Component {
5
+
6
+ get placeholder() {
7
+ return this.args.placeholder || 'Enter text...';
8
+ }
9
+
10
+ get value() {
11
+ const value = get(this.args.model, this.args.valuePath);
12
+ return value !== undefined ? value : this.placeholder;
13
+ }
14
+
15
+ set value(newValue) {
16
+ set(this.args.model, this.args.valuePath, newValue);
17
+ return newValue;
18
+ }
19
+
20
+ updateValue = (event) => {
21
+ this.value = event.target.value;
22
+ this.args.onChange?.(this.value);
23
+ }
24
+ }
@@ -17,8 +17,9 @@
17
17
  height: fit-content;
18
18
  }
19
19
 
20
- .radio-label {
20
+ .label {
21
21
  font-weight: bold;
22
+ margin-bottom: 0.25em;
22
23
  }
23
24
 
24
25
  .radio-options {
@@ -1,7 +1,7 @@
1
1
  .btn-primary {
2
2
  background-color: #eee;
3
3
  color: black;
4
- border: solid;
4
+ border: 2px solid;
5
5
  padding: 10px 20px;
6
6
  cursor: pointer;
7
7
  width: fit-content;
@@ -0,0 +1,5 @@
1
+ .checkbox-container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ margin-bottom: 5px;
5
+ }
@@ -0,0 +1,16 @@
1
+ .date-picker {
2
+ min-height: 2.375em;
3
+ width: 100%;
4
+ border: 2px solid;
5
+ padding: 8px 20px 8px 8px;
6
+ box-sizing: border-box;
7
+ font-family: inherit;
8
+ font-size: inherit;
9
+ font-weight: inherit;
10
+ border-color: inherit;
11
+ background-color: #eee;
12
+ }
13
+
14
+ .date-picker-wrapper {
15
+ border-color: inherit;
16
+ }
@@ -1,6 +1,7 @@
1
1
  .dropdown-option {
2
2
  border-bottom-style: solid;
3
3
  border-width: 2px;
4
+ border-color: inherit;
4
5
  width: 100%;
5
6
  padding-left: 8px;
6
7
  padding-right: 8px;
@@ -8,6 +9,9 @@
8
9
  padding-bottom: 6px;
9
10
  box-sizing: border-box;
10
11
  cursor: pointer;
12
+ min-height: 2.375em;
13
+ display: flex;
14
+ align-items: center;
11
15
  }
12
16
 
13
17
  .dropdown-option:hover {
@@ -23,6 +27,7 @@
23
27
  border-style: solid;
24
28
  border-top-style: none;
25
29
  border-bottom-style: none;
30
+ border-color: inherit;
26
31
  border-width: 2px;
27
32
  background-color: #f6f6f6;
28
33
  transform: scaleY(0);
@@ -60,8 +65,10 @@
60
65
  cursor: pointer;
61
66
  border-style: solid;
62
67
  border-width: 2px;
68
+ border-color: inherit;
63
69
  background-color: #eee;
64
70
  user-select: none;
71
+ min-height: 2.375em;
65
72
  }
66
73
 
67
74
  .dropdown-select::after {
@@ -85,6 +92,7 @@
85
92
  .dropdown-wrapper {
86
93
  width: 100%;
87
94
  position: relative;
95
+ border-color: inherit;
88
96
  }
89
97
 
90
98
  .header-dropdown-options {
@@ -118,7 +126,7 @@
118
126
  max-width: 100%;
119
127
  padding-top: 8px;
120
128
  padding-bottom: 2px;
121
- padding-right: 25px;
129
+ padding-right: 20px;
122
130
  box-sizing: border-box;
123
131
  position: relative;
124
132
  overflow: hidden;
@@ -0,0 +1,34 @@
1
+ .field-border {
2
+ border: 2px solid transparent;
3
+ }
4
+
5
+ .has-error > .field-border {
6
+ border: red solid 2px;
7
+ }
8
+
9
+ .field-validation {
10
+ position: absolute;
11
+ color: red;
12
+ font-style: italic;
13
+ }
14
+
15
+ .field-input {
16
+ box-sizing: border-box;
17
+ margin-bottom: 0.25em;
18
+ }
19
+
20
+ .form-field {
21
+ margin-bottom: 2.25em;
22
+ }
23
+
24
+ .form-wrapper {
25
+ margin-bottom: 2em;
26
+ }
27
+
28
+ .has-error {
29
+ border-color: red;
30
+ }
31
+
32
+ .required {
33
+ color: red;
34
+ }
@@ -0,0 +1,49 @@
1
+ .modal {
2
+ position: absolute;
3
+ top: 25%;
4
+ left: 50%;
5
+ transform: translate(-50%, -50%);
6
+ display: flex;
7
+ flex-direction: column;
8
+ background: white;
9
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
10
+ padding: 1em;
11
+ }
12
+
13
+ .modal-backdrop {
14
+ position: fixed;
15
+ top: 0;
16
+ left: 0;
17
+ width: 100%;
18
+ height: 100%;
19
+ background: rgba(0, 0, 0, 0.5);
20
+ z-index: 999;
21
+ }
22
+
23
+ .modal-backdrop.modal-closed {
24
+ display: none;
25
+ }
26
+
27
+ .modal-header {
28
+ display: flex;
29
+ justify-content: space-between;
30
+ margin-right: 100px;
31
+ }
32
+
33
+ .modal-body {
34
+ margin-bottom: 1em;
35
+ }
36
+
37
+ .modal-footer {
38
+ display: flex;
39
+ justify-content: flex-end;
40
+ }
41
+
42
+ .modal-x {
43
+ cursor: pointer;
44
+ min-height: 2em;
45
+ min-width: 2em;
46
+ position: absolute;
47
+ top: 10px;
48
+ right: 10px;
49
+ }
@@ -12,7 +12,6 @@
12
12
  height: fit-content;
13
13
  display: flex;
14
14
  justify-content: space-between;
15
- align-items: center;
16
15
  z-index: 10;
17
16
  padding: 0 1em;
18
17
  }
@@ -73,6 +72,8 @@
73
72
  width: fit-content;
74
73
  white-space: nowrap;
75
74
  font-weight: bold;
75
+ display: flex;
76
+ align-items: center;
76
77
  }
77
78
 
78
79
  .navbar-wrapper {
@@ -0,0 +1,21 @@
1
+ .text-input {
2
+ min-height: 2.375em;
3
+ width: 100%;
4
+ border: 2px solid;
5
+ border-color: inherit;
6
+ padding: 8px 20px 8px 8px;
7
+ box-sizing: border-box;
8
+ font-family: inherit;
9
+ font-size: inherit;
10
+ font-weight: inherit;
11
+ background-color: #eee;
12
+ }
13
+
14
+ .text-input:focus-visible {
15
+ border-radius: 0 !important;
16
+ outline: none;
17
+ }
18
+
19
+ .text-input-wrapper {
20
+ border-color: inherit;
21
+ }
@@ -0,0 +1,11 @@
1
+ import { tracked } from '@glimmer/tracking';
2
+
3
+ export default class BaseValidator {
4
+ @tracked errorMessage = '';
5
+ @tracked isValid = false;
6
+ @tracked valuePath = '';
7
+
8
+ validate(value) {
9
+ throw new Error('The validate method must be implemented by subclasses');
10
+ }
11
+ }
@@ -0,0 +1,24 @@
1
+ import BaseValidator from './base-validator';
2
+
3
+ export default class PresenceValidator extends BaseValidator {
4
+ constructor(valuePath) {
5
+ super();
6
+ this.valuePath = valuePath;
7
+ }
8
+
9
+ validate(value) {
10
+ if (value === ''
11
+ || value === null
12
+ || value === undefined
13
+ || (typeof value === 'boolean' && value === false)
14
+ || (typeof value === 'object' && !Object.values(value).some(v => v ? true : false))) {
15
+ this.errorMessage = 'This field is required';
16
+ this.isValid = false;
17
+ return this.errorMessage;
18
+ }
19
+
20
+ this.isValid = true;
21
+ this.errorMessage = null;
22
+ return null;
23
+ }
24
+ }
@@ -0,0 +1,28 @@
1
+ import { tracked } from '@glimmer/tracking';
2
+ import { get } from '@ember/object';
3
+
4
+ export default class ValidationBuilder {
5
+ @tracked validations;
6
+ @tracked didValidate = false;
7
+
8
+ constructor() {
9
+ this.validations = [];
10
+ }
11
+
12
+ addValidation(validator) {
13
+ this.validations.push(validator);
14
+ }
15
+
16
+ validate(model) {
17
+ let errors = {};
18
+ for (let validator of this.validations) {
19
+ const value = get(model, validator.valuePath);
20
+ validator.validate(value);
21
+ if (!validator.isValid) {
22
+ errors[validator.valuePath] = validator.errorMessage;
23
+ }
24
+ }
25
+ this.didValidate = true;
26
+ return Object.keys(errors).length ? errors : null;
27
+ }
28
+ }
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/checkbox-group';
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/checkbox';
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/date-picker';
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/form/field';
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/form';
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/modal';
@@ -0,0 +1 @@
1
+ export { default } from 'dlg-ui/components/text-input';
package/index.js CHANGED
@@ -27,11 +27,16 @@ module.exports = {
27
27
  const addonCssPath = path.join(stylesDir, 'addon.css');
28
28
 
29
29
  const cssFiles = [
30
+ 'button.css',
31
+ 'checkbox.css',
32
+ 'date-picker.css',
30
33
  'dropdown.css',
31
34
  'fly-in.css',
35
+ 'form.css',
36
+ 'modal.css',
32
37
  'navbar.css',
33
38
  'player-card.css',
34
- 'button.css',
39
+ 'text-input.css',
35
40
  ];
36
41
 
37
42
  // Start with existing addon.css content (without the @import statements)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dlg-ui",
3
- "version": "1.0.27",
3
+ "version": "1.0.29",
4
4
  "description": "The default blueprint for ember-cli addons.",
5
5
  "keywords": [
6
6
  "ember-addon"
@@ -27,6 +27,10 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@ember/string": "^3.1.1",
30
+ "@fortawesome/ember-fontawesome": "^3.1.0",
31
+ "@fortawesome/fontawesome-svg-core": "^7.1.0",
32
+ "@fortawesome/free-solid-svg-icons": "^7.1.0",
33
+ "ember-auto-import": "^2.4.3",
30
34
  "ember-cli-babel": "^8.2.0",
31
35
  "ember-cli-htmlbars": "^6.3.0"
32
36
  },
@@ -38,15 +42,11 @@
38
42
  "@ember/render-modifiers": "^3.0.0",
39
43
  "@ember/test-helpers": "^2.8.1",
40
44
  "@embroider/test-setup": "^1.8.3",
41
- "@fortawesome/ember-fontawesome": "^3.1.0",
42
- "@fortawesome/fontawesome-svg-core": "^7.1.0",
43
- "@fortawesome/free-solid-svg-icons": "^7.1.0",
44
45
  "@glimmer/component": "^1.1.2",
45
46
  "babel-eslint": "^10.1.0",
46
47
  "broccoli-asset-rev": "^3.0.0",
47
48
  "broccoli-funnel": "^3.0.8",
48
49
  "broccoli-merge-trees": "^4.2.0",
49
- "ember-auto-import": "^2.4.3",
50
50
  "ember-cli": "~4.12.0",
51
51
  "ember-cli-dependency-checker": "^3.3.1",
52
52
  "ember-cli-inject-live-reload": "^2.1.0",