x4js 2.3.12 → 2.3.14

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.
@@ -12,8 +12,12 @@
12
12
  --propertygrid-odd-background: var(--color-primary-a5);
13
13
  --propertygrid-even-background: transparent;
14
14
  --propertygrid-disabled-background: rgb(170 170 170 / 14%);
15
+ --propertygrid-hover-background: var(--color-primary-a10);
16
+ --propertygrid-focus-background: var(--color-primary-a20);
17
+ --propertygrid-input-background: rgba(255,255,255,0.6);
15
18
 
16
19
  --propertygrid-group-background: var( --color-primary-a5 );
20
+ --propertygrid-group-color: var( --color-primary-a50 );
17
21
  }
18
22
 
19
23
  .x4propertygrid {
@@ -36,19 +40,23 @@
36
40
  margin: 0;
37
41
  }
38
42
 
43
+ // Two columns shared by all the rows: the titles, as wide as the longest
44
+ // of them but never more than half of the grid, and the editors, which
45
+ // take the rest.
39
46
  .root {
40
47
  display: grid;
41
- grid-template-columns: 1fr;
48
+ grid-template-columns: fit-content( 50% ) 1fr;
42
49
  grid-template-rows: auto;
43
50
  }
44
51
 
45
52
  .group {
53
+ grid-column: 1 / -1;
46
54
  padding: 6px 4px 4px 4px;
47
55
  min-height: 2em;
48
56
  background-color: var( --propertygrid-group-background );
49
57
  margin-bottom: 8px;
50
58
  box-shadow: 4px 3px 8px rgba(0, 0, 0, 0.4);
51
- color: var(--color-primary-a50);
59
+ color: var( --propertygrid-group-color );
52
60
  display: flex;
53
61
  align-items: center;
54
62
  padding: 8px;
@@ -75,14 +83,14 @@
75
83
 
76
84
  &>.x4button {
77
85
  background-color: transparent;
78
- color: var(--color-primary-a50);
86
+ color: var( --propertygrid-group-color );
79
87
  }
80
-
88
+
81
89
  &>.x4label {
82
90
  .x4icon {
83
91
  .fa-secondary,
84
92
  .fa-primary {
85
- fill: var( --color-primary-a50 );
93
+ fill: var( --propertygrid-group-color );
86
94
  }
87
95
 
88
96
  width: 1em;
@@ -103,52 +111,62 @@
103
111
  }
104
112
 
105
113
  &:not( :last-child ) {
106
- border-bottom: 1px solid var(--color-primary-a50);
114
+ border-bottom: 1px solid var( --propertygrid-group-color );
107
115
  //box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2);
108
116
  }
109
117
  }
110
118
 
119
+ // A row has no box of its own: its two cells go straight on the columns
120
+ // of the grid, which is how all the titles get the same width. (A row is
121
+ // a fieldset: it cannot be a subgrid.) What a row looked like, background
122
+ // and bottom line, is carried by its cells.
111
123
  .row {
112
- border-bottom: 1px solid var( --border-light );
113
- //border-top: none;
114
- //border-left: 1px solid var(--color-primary-a50);
115
- //border-right: 1px solid var(--color-primary-a50);
124
+ display: contents;
125
+
126
+ > .cell {
127
+ min-width: 0;
128
+ padding: 4px;
129
+ border-bottom: 1px solid var( --border-light );
130
+
131
+ input {
132
+ background: var( --propertygrid-input-background );
133
+ }
134
+ }
116
135
 
117
- &.even:not(:disabled) {
136
+ &.even:not(:disabled) > .cell {
118
137
  background-color: var(--propertygrid-even-background)
119
138
  }
120
-
121
- &.odd:not(:disabled) {
139
+
140
+ &.odd:not(:disabled) > .cell {
122
141
  background-color: var(--propertygrid-odd-background)
123
142
  }
124
-
125
- &.odd:disabled {
143
+
144
+ &.odd:disabled > .cell {
126
145
  background-color: var(--propertygrid-disabled-background)
127
146
  }
128
-
129
- &:has(:focus) {
130
- background-color: var(--color-primary-a20);
131
- }
132
147
 
133
- &:hover {
134
- background-color: var(--color-primary-a10);
148
+ &:has(:focus) > .cell {
149
+ background-color: var( --propertygrid-focus-background );
135
150
  }
136
-
137
- .cell {
138
- flex-grow: 1;
139
- flex-basis: 10px;
140
- padding: 4px;
141
151
 
142
- input {
143
- background: rgba(255,255,255,0.6);
144
- }
152
+ &:hover > .cell {
153
+ background-color: var( --propertygrid-hover-background );
145
154
  }
146
155
 
147
- .cell:first-child {
156
+ > .cell:first-child {
148
157
  border-right: 1px solid var( --border );
149
158
  }
150
159
 
151
- .hdr {
160
+ // a row without title (a button): its editor takes the two columns
161
+ > .cell:only-child {
162
+ grid-column: 1 / -1;
163
+ }
164
+
165
+ // The title, centered in the height of the row. Wider than half of
166
+ // the grid, it is cut by the column and goes on several lines.
167
+ > .hdr {
168
+ display: flex;
169
+ align-items: center;
152
170
  padding: 8px;
153
171
  padding-left: 34px;
154
172
  }
@@ -23,6 +23,8 @@ import { ListboxID, ListItem } from "../listbox/listbox"
23
23
  import { Label, SimpleText } from "../label/label"
24
24
  import { asap, class_ns, isFunction, isNumber } from '../../core/core_tools';
25
25
  import { Icon, ScrollView } from '../components'
26
+ import { ColorInput } from '../colorinput/colorinput'
27
+ import { EvColorChange } from '../colorpicker/colorpicker'
26
28
 
27
29
  import icons from "../assets/icons"
28
30
 
@@ -32,12 +34,14 @@ type IValue = boolean | number | string;
32
34
  type IValueCB = ( name: string) => IValue;
33
35
 
34
36
  export interface PropertyValue {
35
- type: 'boolean' | 'number' | 'string' | 'password' | 'options' | 'label' | 'button';
37
+ type: 'boolean' | 'number' | 'string' | 'password' | 'options' | 'color' | 'label' | 'button';
36
38
  title?: string;
37
39
  desc?: string;
38
40
  name?: string;
39
41
  value: IValue | IValueCB;
40
42
  options?: ListItem[];
43
+ swatches?: string[] | ( ( ) => string[] ); // for colors: offered in the picker; a function is called when it opens
44
+ nullable?: boolean; // for colors: "no color" can be chosen, the value is then null
41
45
  callback?: ( name: string, value: any ) => void;
42
46
  live?: boolean; // for live update
43
47
  cls?: string;
@@ -67,6 +71,16 @@ export interface PropertyProps extends ComponentProps {
67
71
  * @cssvar
68
72
  * ```
69
73
  * --propertygrid-background
74
+ * --propertygrid-odd-background
75
+ * --propertygrid-even-background
76
+ * --propertygrid-disabled-background
77
+ * --propertygrid-hover-background
78
+ * --propertygrid-focus-background
79
+ * --propertygrid-input-background
80
+ * --propertygrid-group-background
81
+ * --propertygrid-group-color
82
+ * --propertygrid-gadget-background
83
+ * --propertygrid-gadget-color
70
84
  * ```
71
85
  */
72
86
 
@@ -260,10 +274,23 @@ export class PropertyGrid extends VBox {
260
274
  }
261
275
  });
262
276
  }
277
+ else if (item.type === 'color') {
278
+ editor = new ColorInput({
279
+ id: item.name,
280
+ color: value as string,
281
+ format: "hex",
282
+ picker: true,
283
+ swatches: item.swatches,
284
+ nullable: item.nullable,
285
+ change: ( e: EvColorChange ) => {
286
+ item.callback?.( item.name, e.value );
287
+ }
288
+ });
289
+ }
263
290
  else if (item.type === 'label') {
264
- editor = new Label({
291
+ editor = new Label({
265
292
  id: item.name,
266
- text: value as string,
293
+ text: value as string,
267
294
  });
268
295
  }
269
296
  else if (item.type === 'button') {
@@ -347,6 +374,12 @@ export class PropertyGrid extends VBox {
347
374
  editor.setNumValue( value as number, -2 );
348
375
  }
349
376
  }
377
+ else if (item.type === 'color') {
378
+ const editor = this.root.query<ColorInput>( '#'+item.name );
379
+ if( editor ) {
380
+ editor.setColor( value as string );
381
+ }
382
+ }
350
383
  else if (item.type === 'label') {
351
384
  const label = this.root.query<Label>( '#'+item.name );
352
385
  if( label ) {
@@ -70,6 +70,15 @@ export const makeUniqueComponentId = ( ) => {
70
70
  return `x4-${gen_id++}`;
71
71
  }
72
72
 
73
+ /**
74
+ * CSS properties. A number gets "px", except for the unitless properties
75
+ * (opacity, lineHeight, flexGrow...).
76
+ */
77
+
78
+ export type StyleProps = {
79
+ [K in keyof CSSStyleDeclaration]?: CSSStyleDeclaration[K] | number;
80
+ };
81
+
73
82
  /**
74
83
  * Base properties for all components.
75
84
  */
@@ -80,7 +89,7 @@ export interface ComponentProps {
80
89
  /** Namespace for SVG/MathML elements. */
81
90
  ns?: string;
82
91
  /** Inline CSS styles. */
83
- style?: Partial<CSSStyleDeclaration>;
92
+ style?: StyleProps;
84
93
  /** HTML attributes. */
85
94
  attrs?: Record<string,string|number|boolean>;
86
95
  /** Child content (components, strings, or HTML). */
@@ -685,17 +694,17 @@ export class Component<P extends ComponentProps = ComponentProps, E extends Comp
685
694
  * @returns The component instance for chaining.
686
695
  */
687
696
 
688
- setStyle( style: Partial<CSSStyleDeclaration> ): this {
697
+ setStyle( style: StyleProps ): this {
689
698
  const _style = (this.dom as HTMLElement).style;
690
699
 
691
700
  for( const name in style ) {
692
-
693
- let value = style[name];
701
+
702
+ let value: any = style[name];
694
703
  if( !unitless[name] && (isNumber(value) || RE_NUMBER.test(value)) ) {
695
704
  value += "px";
696
705
  }
697
706
 
698
- _style[name] = value;
707
+ (_style as any)[name] = value;
699
708
  }
700
709
 
701
710
  return this;
@@ -264,7 +264,7 @@ export class Rect implements IRect {
264
264
 
265
265
  moveTo( x: number, y: number ) {
266
266
  this.left = x;
267
- this.top = x;
267
+ this.top = y;
268
268
 
269
269
  return this;
270
270
  }