alchemy-form 0.3.0-alpha.1 → 0.3.0-alpha.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 0.3.0-alpha.2 (2024-02-25)
2
+
3
+ * Added `.alchemy-badge` class
4
+ * Use badges & microcopy for showing in-line empty values
5
+ * Also set the `al-field`'s model attribute inside `al-table` elements
6
+ * Depend on the `alchemy-styleboost` peer dependency
7
+ * Let enum values use automatic styleboost colors in indexes + show correct titles
8
+
1
9
  ## 0.3.0-alpha.1 (2024-02-15)
2
10
 
3
11
  * Upgrade to Alchemy v1.4.0
@@ -1,2 +1 @@
1
- @import "./general/index.scss";
2
- @import "./elements/index.scss";
1
+ @use "elements";
@@ -0,0 +1,41 @@
1
+ @use "styleboost";
2
+
3
+ :root {
4
+ --badge-font-size: 0.9rem;
5
+ --badge-font-weight: 400;
6
+ --badge-line-height: 1;
7
+ --badge-border-radius: 5px;
8
+ --badge-padding: 4px 8px;
9
+ --badge-white-space: nowrap;
10
+ --badge-user-select: none;
11
+ --badge-gap: 5px;
12
+ }
13
+
14
+ .alchemy-badge {
15
+ display: inline-flex;
16
+ text-align: center;
17
+
18
+ gap: var(--badge-gap);
19
+ user-select: var(--badge-user-select);
20
+ padding: var(--badge-padding);
21
+ font-size: var(--badge-font-size);
22
+ font-weight: var(--badge-font-weight);
23
+ line-height: var(--badge-line-height);
24
+ border-radius: var(--badge-border-radius);
25
+ color: var(--badge-color, var(--color-theme-fill-text));
26
+ background-color: var(--badge-bg, var(--color-theme-fill));
27
+ white-space: var(--badge-white-space);
28
+ }
29
+
30
+ $counter: 0;
31
+
32
+ // Iterate over all the available colors and create a badge color set for each
33
+ // We do this without the badge class to lower specificity
34
+ @each $color, $value in styleboost.$colors {
35
+ $counter: $counter + 1;
36
+
37
+ [data-badge-color-set="#{$counter}"] {
38
+ --badge-color: var(--color-shade-#{$counter});
39
+ --badge-bg: var(--color-tint-#{$counter});
40
+ }
41
+ }
@@ -1,33 +1,10 @@
1
- :root {
2
- --al-button-font-size: 1em;
3
- --al-button-font-weight: 400;
4
- --al-button-bg-color: rgb(89, 105, 225);
5
- --al-button-bg-color-hover: rgb(105, 118, 218);
6
- --al-button-text-color: white;
7
- }
1
+ @use "styleboost";
8
2
 
9
3
  al-button {
10
- display: inline-block;
11
- font-size: var(--al-button-font-size);
12
- font-weight: var(--al-button-font-weight);
13
- background-color: var(--al-button-bg-color);
14
- color: var(--al-button-text-color);
15
- cursor: pointer;
16
- user-select: none;
4
+ @extend .default-button;
17
5
 
6
+ display: inline-block;
18
7
  position: relative;
19
- padding: 0.5em 1em;
20
- text-align: center;
21
- text-decoration: none;
22
- vertical-align: bottom;
23
- transition: 0.1s;
24
- overflow: hidden;
25
- line-height: 1.5;
26
-
27
- al-icon,
28
- .icon {
29
- line-height: 1 !important;
30
- }
31
8
 
32
9
  .apb-content {
33
10
  display: flex;
@@ -42,11 +19,7 @@ al-button {
42
19
 
43
20
  &[disabled] {
44
21
  pointer-events: none;
45
- filter: saturate(0.5);
22
+ filter: unquote("saturate(0.5)");
46
23
  cursor: not-allowed;
47
24
  }
48
-
49
- &:hover {
50
- background-color: var(--al-button-bg-color-hover);
51
- }
52
25
  }
@@ -1,3 +1,5 @@
1
+ @use "form/general" as *;
2
+
1
3
  .textareabox,
2
4
  .inputbox {
3
5
  $inputbox: &;
@@ -1,5 +1,8 @@
1
+ @use "styleboost" as *;
2
+
1
3
  al-field {
2
4
  display: block;
5
+ --badge-font-size: 1rem;
3
6
 
4
7
  &[field-type="boolean"] {
5
8
 
@@ -8,34 +11,22 @@ al-field {
8
11
  justify-content: flex-start;
9
12
  }
10
13
 
11
- .boolean-wrapper {
12
- &.boolean-true {
13
- --boolean-color: green;
14
- --text-color: white;
15
- }
16
-
17
- &.boolean-false {
18
- --boolean-color: red;
19
- --text-color: white;
20
- }
21
-
22
- &.boolean-null {
23
- --boolean-color: #f3f3f3;
24
- --text-color: #666;
25
- font-style: italic;
26
- }
27
-
28
- background-color: var(--boolean-color);
29
- border-radius: 5px;
30
- padding: 4px 8px;
31
- min-width: 1rem;
32
- color: var(--text-color, white);
33
- display: inline-flex;
14
+ .boolean-true {
15
+ @extend .use-truthy-theme;
16
+ }
17
+
18
+ .boolean-false {
19
+ @extend .use-falsy-theme;
20
+ }
21
+
22
+ .value-icon {
23
+ margin-right: 0.5rem;
34
24
  }
35
25
  }
36
26
 
37
- .alchemy-field-empty-value {
38
- color: #666;
27
+ .alchemy-field-empty-value-placeholder {
28
+ --color-theme-fill: var(--color-inactive-bg);
29
+ --color-theme-fill-text: var(--color-inactive-bg-text);
39
30
  font-style: italic;
40
31
  }
41
32
  }
@@ -1,12 +1,17 @@
1
+ @use "styleboost";
2
+
1
3
  al-form {
2
4
  .error-area:empty {
3
5
  display: none;
4
6
  }
5
7
 
6
8
  .error-area:not(:empty) {
7
- border: 1px solid #a80000;
8
- color: #a80000;
9
+ @extend .use-danger-theme;
10
+ border: 1px solid var(--color-theme-accent);
11
+ color: var(--color-theme-bg-text);
12
+ background-color: var(--color-theme-bg);
9
13
  padding: 0.2rem;
14
+ border-radius: 4px;
10
15
  }
11
16
  }
12
17
 
@@ -2,11 +2,9 @@ al-table {
2
2
  display: flex;
3
3
  flex-flow: column;
4
4
  border: 1px solid #dadee0;
5
- font-family: sans-serif;
6
5
  background-color: white;
7
6
 
8
7
  table {
9
- border-collapse: collapse;
10
8
  width: 100%;
11
9
  color: inherit;
12
10
  }
@@ -33,6 +31,14 @@ al-table {
33
31
  color: inherit;
34
32
  }
35
33
  }
34
+
35
+ th input {
36
+ width: 100%;
37
+ padding: 0px 12px;
38
+ border: 1px solid var(--color-input-border);
39
+ color: var(--text-color);
40
+ height: 2rem;
41
+ }
36
42
  }
37
43
 
38
44
  td, th {
@@ -41,6 +47,10 @@ al-table {
41
47
  cursor: default;
42
48
  }
43
49
 
50
+ td al-field[field-type="fixed_decimal"] {
51
+ text-align: right;
52
+ }
53
+
44
54
  tr:last-of-type {
45
55
  td, th {
46
56
  border-bottom: 0;
@@ -1,18 +1,19 @@
1
- @import "_button.scss";
2
- @import "_code_input.scss";
3
- @import "_feedback_input.scss";
4
- @import "_field.scss";
5
- @import "_field_array.scss";
6
- @import "_field_translatable.scss";
7
- @import "_form.scss";
8
- @import "_pager.scss";
9
- @import "_query_builder.scss";
10
- @import "_select.scss";
11
- @import "_state.scss";
12
- @import "_table.scss";
13
- @import "_toggle.scss";
14
- @import "_tabs.scss";
15
- @import "_pathway.scss";
16
- @import "_apex_charts.scss";
17
- @import "_virtual_scroll.scss";
18
- @import "_settings_editor.scss";
1
+ @use "_badge.scss";
2
+ @use "_button.scss";
3
+ @use "_code_input.scss";
4
+ @use "_feedback_input.scss";
5
+ @use "_field.scss";
6
+ @use "_field_array.scss";
7
+ @use "_field_translatable.scss";
8
+ @use "_form.scss";
9
+ @use "_pager.scss";
10
+ @use "_query_builder.scss";
11
+ @use "_select.scss";
12
+ @use "_state.scss";
13
+ @use "_table.scss";
14
+ @use "_toggle.scss";
15
+ @use "_tabs.scss";
16
+ @use "_pathway.scss";
17
+ @use "_apex_charts.scss";
18
+ @use "_virtual_scroll.scss";
19
+ @use "_settings_editor.scss";
@@ -1,2 +1,2 @@
1
- @import "_textsizes.scss";
2
- @import "_colors.scss";
1
+ @forward "_textsizes.scss";
2
+ @forward "_colors.scss";
@@ -254,7 +254,7 @@ WithDataprovider.setMethod(function loadRemoteData(fetch_config) {
254
254
  *
255
255
  * @author Jelle De Loecker <jelle@elevenways.be>
256
256
  * @since 0.2.0
257
- * @version 0.2.0
257
+ * @version 0.3.0
258
258
  *
259
259
  * @param {Object} config
260
260
  *
@@ -265,7 +265,7 @@ WithDataprovider.setMethod(function fetchRemoteData(config) {
265
265
  let pledge;
266
266
 
267
267
  if (this.dataprovider) {
268
- pledge = Pledge.cast(this.dataprovider.loadData(config, this));
268
+ pledge = Pledge.Swift.cast(this.dataprovider.loadData(config, this));
269
269
  } else {
270
270
 
271
271
  let method = (this.method || 'get').toLowerCase();
@@ -650,8 +650,72 @@ Field.setProperty(function value_to_render() {
650
650
  }
651
651
  });
652
652
 
653
+ /**
654
+ * Get the placeholder for empty values (if any)
655
+ *
656
+ * @author Jelle De Loecker <jelle@elevenways.be>
657
+ * @since 0.3.0
658
+ * @version 0.3.0
659
+ */
660
+ Field.setProperty(function allow_empty_value_placeholder() {
661
+ return !!(this.applied_options?.empty_value_placeholder ?? true);
662
+ });
663
+
664
+ /**
665
+ * Create the empty value placeholder text
666
+ *
667
+ * @author Jelle De Loecker <jelle@elevenways.be>
668
+ * @since 0.3.0
669
+ * @version 0.3.0
670
+ *
671
+ * @return {string|HTMLElement|Microcopy}
672
+ */
673
+ Field.setMethod(function createEmptyValuePlaceholderText() {
674
+
675
+ let microcopy = this.applied_options?.empty_value_placeholder;
676
+
677
+ if (microcopy) {
678
+ return microcopy;
679
+ }
680
+
681
+ microcopy = Classes.Alchemy.Microcopy('empty-value-placeholder', {
682
+ field_name : this.field_name,
683
+ model_name : this.model,
684
+ field_type : this.field_type,
685
+ zone : this.zone,
686
+ path : this.config?.path_in_document,
687
+ });
688
+
689
+ return microcopy;
690
+ });
691
+
692
+ /**
693
+ * Get variables needed to render this
694
+ *
695
+ * @author Jelle De Loecker <jelle@elevenways.be>
696
+ * @since 0.3.0
697
+ * @version 0.3.0
698
+ */
699
+ Field.setMethod(function prepareRenderVariables() {
700
+
701
+ let value = this.value_to_render,
702
+ value_is_empty = value == null || value === '' || (Array.isArray(value) ? value.length == 0 : false);
703
+
704
+ let result = {
705
+ alchemy_field : this,
706
+ field_context : this,
707
+ view_files : this.view_files,
708
+ wrapper_files : this.wrapper_files,
709
+ value,
710
+ value_is_empty,
711
+ };
712
+
713
+ return result;
714
+ });
715
+
653
716
  /**
654
717
  * Apply options
718
+ * (Like options from a FieldConfig instance)
655
719
  *
656
720
  * @author Jelle De Loecker <jelle@elevenways.be>
657
721
  * @since 0.1.12
@@ -597,7 +597,7 @@ Table.setMethod(function showPagination() {
597
597
  *
598
598
  * @author Jelle De Loecker <jelle@elevenways.be>
599
599
  * @since 0.1.8
600
- * @version 0.2.0
600
+ * @version 0.3.0
601
601
  *
602
602
  * @param {FieldConfig} field_config The config on how to display the field
603
603
  * @param {Object} container The container where the field should be in
@@ -640,6 +640,7 @@ Table.setMethod(function getFieldConfigView(field_config, container) {
640
640
  alchemy_field.field_name = field.name;
641
641
  alchemy_field.config = field;
642
642
  alchemy_field.original_value = value;
643
+ alchemy_field.model = field?.schema?.model_name;
643
644
 
644
645
  return alchemy_field;
645
646
  });
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "alchemy-form",
3
3
  "description": "Form plugin for Alchemy",
4
- "version": "0.3.0-alpha.1",
4
+ "version": "0.3.0-alpha.2",
5
5
  "repository": {
6
6
  "type" : "git",
7
7
  "url" : "https://github.com/11ways/alchemy-form.git"
8
8
  },
9
9
  "peerDependencies": {
10
10
  "alchemymvc" : ">=1.4.0||>=1.4.0-alpha",
11
- "alchemy-media" : ">=0.9.0||>=0.9.0-alpha"
11
+ "alchemy-media" : ">=0.9.0||>=0.9.0-alpha",
12
+ "alchemy-styleboost": ">=0.5.0||>=0.5.0-alpha"
12
13
  },
13
14
  "license": "MIT",
14
15
  "engines": {
@@ -1,16 +1,5 @@
1
- <% wrapper_files = self.wrapper_files %>
2
- <% view_files = self.view_files %>
3
- <%
4
- variables = {
5
- alchemy_field : self,
6
- field_context : self,
7
- view_files : view_files,
8
- value : self.value_to_render,
9
- }
10
- %>
11
-
12
1
  <% if (wrapper_files) { %>
13
- <% include(wrapper_files, variables) %>
2
+ <% include(wrapper_files) %>
14
3
  <% } %>
15
4
 
16
5
  <% if (wrapper_files) start('field') %>
@@ -3,7 +3,7 @@
3
3
  <% if (value || value === false) { %>
4
4
  {{ value }}
5
5
  <% } else { %>
6
- <span class="alchemy-field-empty-value">
6
+ <span class="alchemy-badge alchemy-field-empty-value-placeholder">
7
7
  {%t
8
8
  "empty-value"
9
9
  field=field_context.config.name
@@ -1,19 +1,26 @@
1
- <span
2
- class="alchemy-field-value boolean-wrapper"
3
- >
4
- <%
5
- new_class = '';
1
+ {% if (value_is_empty AND self.allow_empty_value_placeholder) %}
2
+ <span class="alchemy-field-value">
3
+ <span class="alchemy-badge alchemy-field-empty-value-placeholder">
4
+ {{ self.createEmptyValuePlaceholderText() }}
5
+ </span>
6
+ </span>
7
+ {% else %}
8
+ <span class="alchemy-badge alchemy-field-value">
9
+ <% $0.classList.add('boolean-' + value) %>
6
10
 
7
- if (value) {
8
- new_class = 'boolean-true';
9
- } else if (value === false) {
10
- new_class = 'boolean-false';
11
- } else {
12
- new_class = 'boolean-null';
13
- value = 'empty';
14
- }
11
+ {% if value %}
12
+ <al-icon class="value-icon" icon-name="check"></al-icon>
13
+ {% else %}
14
+ <al-icon class="value-icon" icon-name="xmark"></al-icon>
15
+ {% /if %}
15
16
 
16
- $0.classList.add(new_class);
17
- %>
18
- {{ value }}
19
- </span>
17
+ {%t
18
+ "" + value
19
+ field_name=self.field_name
20
+ model_name=self.model
21
+ field_type=self.field_type
22
+ zone=self.zone
23
+ path=self.config.path_in_document
24
+ %}
25
+ </span>
26
+ {% /if %}
@@ -1,28 +1,35 @@
1
- <%
2
- date_format = '';
1
+ {% if (value_is_empty AND self.allow_empty_value_placeholder) %}
2
+ <span class="alchemy-field-value">
3
+ <span class="alchemy-badge alchemy-field-empty-value-placeholder">
4
+ {{ self.createEmptyValuePlaceholderText() }}
5
+ </span>
6
+ </span>
7
+ {% else %}
8
+ <%
9
+ date_format = '';
3
10
 
4
- if (alchemy_field && alchemy_field.applied_options) {
5
- date_format = alchemy_field.applied_options.date_format;
6
- }
11
+ if (alchemy_field && alchemy_field.applied_options) {
12
+ date_format = alchemy_field.applied_options.date_format;
13
+ }
7
14
 
8
- if (!date_format || date_format == 'timeago' || date_format == 'time-ago' || date_format == 'time_ago') {
9
- date_format = 'relative';
10
- }
15
+ if (!date_format || date_format == 'timeago' || date_format == 'time-ago' || date_format == 'time_ago') {
16
+ date_format = 'relative';
17
+ }
11
18
 
12
- if (alchemy_field?.config?.options?.time_ago) {
13
- date_format = 'relative';
14
- }
19
+ if (alchemy_field?.config?.options?.time_ago) {
20
+ date_format = 'relative';
21
+ }
22
+ %>
15
23
 
16
- %>
17
-
18
- <% if (date_format == 'relative') { %>
19
- <time-ago
20
- class="alchemy-field-value"
21
- date={% value.toISOString() %}
22
- ></time-ago>
23
- <% } else { %>
24
- <time
25
- class="alchemy-field-value"
26
- datetime={% value.toISOString() %}
27
- >{{ value.format(date_format) }}</time>
28
- <% } %>
24
+ <% if (date_format == 'relative') { %>
25
+ <time-ago
26
+ class="alchemy-field-value"
27
+ date={% value.toISOString() %}
28
+ ></time-ago>
29
+ <% } else { %>
30
+ <time
31
+ class="alchemy-field-value"
32
+ datetime={% value.toISOString() %}
33
+ >{{ value.format(date_format) }}</time>
34
+ <% } %>
35
+ {% /if %}
@@ -1 +1,32 @@
1
- <span class="alchemy-field-value alchemy-field-enum">{{ value }}</span>
1
+ {% if (value_is_empty AND self.allow_empty_value_placeholder) %}
2
+ <span class="alchemy-field-value">
3
+ <span class="alchemy-badge alchemy-field-empty-value-placeholder">
4
+ {{ self.createEmptyValuePlaceholderText() }}
5
+ </span>
6
+ </span>
7
+ {% else %}
8
+ {% set enum_config to self.config.getValueConfiguration(value) %}
9
+ {% set display_value to OR enum_config.title OR enum_config.name OR value %}
10
+
11
+ <span class="alchemy-badge alchemy-field-value alchemy-field-enum">
12
+ <% $0.classList.add('enum-' + value) %>
13
+
14
+ {% if enum_config.number %}
15
+ <% $0.dataset.badgeColorSet = enum_config.number %>
16
+ {% /if %}
17
+
18
+ {% if enum_config.color %}
19
+ <% $0.style.setProperty('--badge-bg', enum_config.color) %>
20
+ {% /if %}
21
+
22
+ {% if enum_config.text_color %}
23
+ <% $0.style.setProperty('--badge-color', enum_config.text_color) %>
24
+ {% /if %}
25
+
26
+ {% if enum_config.icon %}
27
+ <al-icon class="value-icon" icon-name={% enum_config.icon %}></al-icon>
28
+ {% /if %}
29
+
30
+ <span class="alchemy-enum-display-value">{{ display_value }}</span>
31
+ </span>
32
+ {% /if %}
@@ -1 +1,9 @@
1
- <code class="alchemy-field-value">{{ value }}</code>
1
+ {% if (value_is_empty AND self.allow_empty_value_placeholder) %}
2
+ <span class="alchemy-field-value">
3
+ <span class="alchemy-badge alchemy-field-empty-value-placeholder">
4
+ {{ self.createEmptyValuePlaceholderText() }}
5
+ </span>
6
+ </span>
7
+ {% else %}
8
+ <code class="alchemy-field-value">{{ value }}</code>
9
+ {% /if %}
@@ -1,6 +1,14 @@
1
1
  <div>
2
- <span class="alchemy-field-value">{{ value }}</span>
3
- {% if alchemy_field.config.options.suffix %}
4
- <span class="alchemy-field-suffix">{{ alchemy_field.config.options.suffix }}</span>
2
+ {% if (value_is_empty AND self.allow_empty_value_placeholder) %}
3
+ <span class="alchemy-field-value">
4
+ <span class="alchemy-badge alchemy-field-empty-value-placeholder">
5
+ {{ self.createEmptyValuePlaceholderText() }}
6
+ </span>
7
+ </span>
8
+ {% else %}
9
+ <span class="alchemy-field-value">{{ value }}</span>
10
+ {% if alchemy_field.config.options.suffix %}
11
+ <span class="alchemy-field-suffix">{{ alchemy_field.config.options.suffix }}</span>
12
+ {% /if %}
5
13
  {% /if %}
6
14
  </div>