x4js 2.3.30 → 2.3.32
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/aicontext.md +40 -5
- package/aiguide.md +2 -0
- package/changelog.md +1357 -0
- package/package.json +2 -1
- package/src/components/button/button.module.scss +1 -1
- package/src/components/checkbox/checkbox.module.scss +4 -3
- package/src/components/checkbox/checkbox.ts +1 -0
- package/src/components/menu/menu.module.scss +59 -0
- package/src/components/menu/menu.ts +142 -0
- package/src/components/messages/circle-exclamation.svg +1 -1
- package/src/components/messages/circle-question.svg +1 -1
- package/src/components/messages/messages.module.scss +28 -0
- package/src/components/messages/messages.ts +7 -1
- package/src/components/notification/notification.module.scss +4 -0
- package/src/components/popup/popup.ts +22 -3
- package/src/components/radio/radio.module.scss +4 -5
- package/src/components/radio/radio.ts +1 -0
- package/src/components/spreadsheet/spreadsheet.ts +28 -21
- package/src/components/textedit/textedit.module.scss +1 -0
- package/src/components/textedit/textedit.ts +4 -1
- package/src/components/themes.scss +14 -0
- package/src/components/treeview/treeview.ts +44 -6
- package/src/core/core_clipboard.ts +25 -6
package/aicontext.md
CHANGED
|
@@ -42,7 +42,7 @@ CoreElement<E> named timers + event surface (no DOM)
|
|
|
42
42
|
│ ├── SvgComponent → Chart
|
|
43
43
|
│ ├── CSizer → HSizer / VSizer
|
|
44
44
|
│ ├── FileDialog, ScrollView, Viewport, DockingView, Carousel, Flex, Space
|
|
45
|
-
│ ├── HBox-based: ColorInput, Rating, Switch, Tag, Keyboard, TextEdit → AutoComplete, Breadcrumbs
|
|
45
|
+
│ ├── HBox-based: ColorInput, Rating, Switch, Tag, Keyboard, MenuBar, TextEdit → AutoComplete, Breadcrumbs
|
|
46
46
|
│ └── VBox-based: Calendar, ColorPicker, FileDrop, Panel, PropertyGrid, TextArea, SettingsView, SettingItem
|
|
47
47
|
└── Application<E> singleton, no DOM of its own
|
|
48
48
|
|
|
@@ -832,7 +832,10 @@ type TextEditProps = (TextInputProps | NumberProps | DateProps | TimeProps) & {
|
|
|
832
832
|
labelWidth?: number; inputWidth?: number; inputId?: string
|
|
833
833
|
inputGadgets?: Component[]; inputAttrs?: any
|
|
834
834
|
}
|
|
835
|
-
// style, tooltip, hidden, flex, stretch, height: on the box (label + field); dom_events: on the input
|
|
835
|
+
// style, tooltip, hidden, flex, stretch, height: on the box (label + field); dom_events: on the input,
|
|
836
|
+
// set when it is made, before the handlers of Input and of the class (the keys of an AutoComplete): they run
|
|
837
|
+
// first, and see the state before the class reacts (Enter before the suggestion is chosen). To run after them:
|
|
838
|
+
// textEdit.getInput( ).addDOMEvent( "keydown", ... ) once the component is made
|
|
836
839
|
class TextEdit extends HBox {
|
|
837
840
|
getValue(): string; setValue(value: string): void; getInput(): Input
|
|
838
841
|
}
|
|
@@ -886,6 +889,7 @@ interface CheckboxProps extends ComponentProps {
|
|
|
886
889
|
// button: "button danger"); without the box, the input is still reached by Tab (--checkbox-button-*, -danger-*)
|
|
887
890
|
// A toggle button is a Checkbox with cls "button": getCheck() tells whether it is pressed, change when it changes
|
|
888
891
|
// new Checkbox( { cls: "button", icon: icon_bold, tooltip: "Bold", change: ( ev ) => this.setBold( ev.value ) } )
|
|
892
|
+
// its icon 24px: --checkbox-button-icon-size, set by a class of the application ( .small { --checkbox-button-icon-size: 16px } )
|
|
889
893
|
// in a Form: without value (or a boolean one), a boolean; with one, the value when checked, null when not
|
|
890
894
|
class Checkbox extends Component {
|
|
891
895
|
getCheck(): boolean; setCheck(ck: boolean): void
|
|
@@ -911,6 +915,7 @@ class Radio extends Component {
|
|
|
911
915
|
}
|
|
912
916
|
// cls: "button" (a button; "button outline" rounded), "danger" (checked in red, its round or its button: "button
|
|
913
917
|
// danger"). Without the round, the input is still reached by Tab.
|
|
918
|
+
// its icon 24px: --radio-button-icon-size, set by a class of the application ( .small { --radio-button-icon-size: 16px } )
|
|
914
919
|
```
|
|
915
920
|
|
|
916
921
|
### `Switch`
|
|
@@ -1162,6 +1167,7 @@ interface TreeviewProps extends Omit<ComponentProps,"content"> {
|
|
|
1162
1167
|
click?: EventCallback<EvClick>
|
|
1163
1168
|
dblClick?: EventCallback<EvDblClick>
|
|
1164
1169
|
selectionChange?: EventCallback<EvSelectionChange>
|
|
1170
|
+
contextMenu?: EventCallback<EvContextMenu> // as a Listbox: the item under the mouse selected, ev.context its id (null out of the items), no menu of the browser
|
|
1165
1171
|
}
|
|
1166
1172
|
// emptyMsg: as for a Listbox. Without it the text is _tr.global.empty_list ("Empty list").
|
|
1167
1173
|
// There is no `renderer`: an item is drawn from its `text`, `iconId`, `cls` and `sub_cols`.
|
|
@@ -1194,6 +1200,7 @@ interface SpreadsheetColumn { // GridColumn +
|
|
|
1194
1200
|
interface EvCellChange { row; col /* index */; colId /* store key */; value /* writable */; oldValue }
|
|
1195
1201
|
class Spreadsheet extends Component {
|
|
1196
1202
|
getSelection(): /* cell */; navigate(sens: kbNav): boolean; lock(lock): void
|
|
1203
|
+
clearSelection(notify = true): void // no cell selected; notify: selectionChange, its selection empty
|
|
1197
1204
|
editCell(row, col, clear = false): boolean // cell must be visible
|
|
1198
1205
|
stopEdit(commit = true): void; isEditing(): boolean
|
|
1199
1206
|
}
|
|
@@ -1266,13 +1273,33 @@ class PropertyGrid extends VBox {
|
|
|
1266
1273
|
interface MenuItem {
|
|
1267
1274
|
text: string | UnsafeHtml
|
|
1268
1275
|
cls?: string; icon?: string; menu?: Menu; disabled?: boolean
|
|
1276
|
+
checked?: boolean | (() => boolean) // a check as icon when there is no icon
|
|
1269
1277
|
click?: DOMEventHandler
|
|
1278
|
+
shortcut?: string // "Mod+S": shown at the right (shortcutText), not added: see addShortcut
|
|
1270
1279
|
}
|
|
1271
1280
|
type MenuElement = MenuItem | Component | string // string "-" = title/separator
|
|
1272
1281
|
interface MenuProps extends Omit<PopupProps,"content"> { items: MenuElement[] }
|
|
1273
1282
|
class Menu extends Popup {} // displayAt/displayNear/displayCenter/close
|
|
1274
1283
|
```
|
|
1275
1284
|
|
|
1285
|
+
### `MenuBar`
|
|
1286
|
+
|
|
1287
|
+
```ts
|
|
1288
|
+
interface MenuBarItem {
|
|
1289
|
+
text: string; icon?: string; disabled?: boolean
|
|
1290
|
+
items: MenuElement[] | (() => MenuElement[]) // its Menu, built at each opening; a function is called then
|
|
1291
|
+
}
|
|
1292
|
+
interface MenuBarProps extends Omit<BoxProps,"content"> { items: MenuBarItem[] }
|
|
1293
|
+
class MenuBar extends HBox {}
|
|
1294
|
+
// a click on a title opens its menu under it, a second one closes it; while a menu is open, the mouse
|
|
1295
|
+
// on another title opens that one. No keyboard. For a web application: a desktop application
|
|
1296
|
+
// (Electron...) should use the menu of the system, not a MenuBar
|
|
1297
|
+
new MenuBar({ items: [
|
|
1298
|
+
{ text: "File", items: [{ text: "Open…", shortcut: "Mod+O", click: open }, "-", { text: "Quit", click: quit }] },
|
|
1299
|
+
{ text: "Edit", items: () => [{ text: "Undo", disabled: !canUndo(), click: undo }] },
|
|
1300
|
+
] })
|
|
1301
|
+
```
|
|
1302
|
+
|
|
1276
1303
|
### `BtnGroup`
|
|
1277
1304
|
|
|
1278
1305
|
```ts
|
|
@@ -1336,7 +1363,8 @@ class Tabs extends Box {
|
|
|
1336
1363
|
```ts
|
|
1337
1364
|
interface PopupProps extends ComponentProps {
|
|
1338
1365
|
autoClose?: boolean | string // true, or a group name: closed by a press outside; while it is shown,
|
|
1339
|
-
// a wheel outside every popup is ignored (the page does not scroll)
|
|
1366
|
+
// a wheel outside every popup is ignored (the page does not scroll);
|
|
1367
|
+
// a press in a popup closes the other groups opened after it, not its own
|
|
1340
1368
|
sizable?: boolean; movable?: boolean
|
|
1341
1369
|
}
|
|
1342
1370
|
class Popup extends Box {
|
|
@@ -1344,7 +1372,8 @@ class Popup extends Box {
|
|
|
1344
1372
|
displayNear(rc: Rect, dst?: string, src?: string, offset?: {x,y}): void
|
|
1345
1373
|
displayCenter(center?: boolean): void
|
|
1346
1374
|
close(): void
|
|
1347
|
-
dismiss(after?: boolean): void
|
|
1375
|
+
dismiss(after?: boolean): void // closes the popups of its autoClose group; after: only those opened
|
|
1376
|
+
// after it (none when it is no longer open)
|
|
1348
1377
|
isOpen(): boolean
|
|
1349
1378
|
// show()/hide() inherited from Component; show() routes to displayCenter()
|
|
1350
1379
|
}
|
|
@@ -1386,6 +1415,10 @@ class MessageBox extends Dialog {
|
|
|
1386
1415
|
static showAsync(msg: string|UnsafeHtml, buttons?: BtnGroupItem[], title?: string,
|
|
1387
1416
|
icon_type?: "error"|"question"): Promise<string>
|
|
1388
1417
|
}
|
|
1418
|
+
// no icon_type: an error (its icon, the title _tr.global.error, the class "error"); its title bar and its buttons
|
|
1419
|
+
// in the colours of the alerts: a filled button in --alert-*, an outline one with a red border when focused.
|
|
1420
|
+
// The "!" of an error, the "?" of a question: white in the disc of the icon (--msgbox-icon-mark-color,
|
|
1421
|
+
// --msgbox-question-icon-mark-color)
|
|
1389
1422
|
class InputBox extends Dialog {
|
|
1390
1423
|
getValue(): string
|
|
1391
1424
|
// static showAsync(msg, value, title?, options?: {password?, trim?}): Promise<string> (null if cancelled or closed)
|
|
@@ -1760,6 +1793,7 @@ new Button({ label: 'Paste', click: async () => {
|
|
|
1760
1793
|
- The events go to the component that has the focus: give it a `tabindex`.
|
|
1761
1794
|
- Out of an event, the browser may refuse, and there is no system clipboard on a page that is not served in https. What the application set last is then what `getClipboard` gives: copy and paste still work inside the application.
|
|
1762
1795
|
- An image is written as a PNG; another format is converted. Files can be read in a `paste` event only, and cannot be written.
|
|
1796
|
+
- An image offered in several formats (Inkscape: a SVG, then a PNG) is read as the PNG, by `getClipboard` and `getEventClipboard`; else the first image.
|
|
1763
1797
|
|
|
1764
1798
|
---
|
|
1765
1799
|
|
|
@@ -1835,7 +1869,8 @@ by the browser, in its own locale, whatever this one.
|
|
|
1835
1869
|
--color-primary-a0 … --color-primary-a100 /* the scale: a0 the background, a100 the text, the accent between */
|
|
1836
1870
|
/* the globals the components use: --background-primary / -secondary / -ternary / -hover / -active / -input,
|
|
1837
1871
|
--text-primary / -secondary / -ternary, --border / -light / -hover / -focus, --accent-background / -hover /
|
|
1838
|
-
-focus / -active / -light, --accent-color (the text on the accent), --
|
|
1872
|
+
-focus / -active / -light, --accent-color (the text on the accent), --accent-text (the accent as a text on the
|
|
1873
|
+
background: a button checked or focused; light in the dark theme), --disabled-*, --icon-color / -active,
|
|
1839
1874
|
--alert-*, --warning-*, --success-*, --shadow-color (the shadow of what floats: dialog, list, notification, tooltip) */
|
|
1840
1875
|
```
|
|
1841
1876
|
// The greys are mixes of a0 and a100: a theme that reverses the scale gets them light on dark.
|
package/aiguide.md
CHANGED
|
@@ -5,6 +5,8 @@ This is not a suggestion but an imperative rule.
|
|
|
5
5
|
|
|
6
6
|
For exact classes, properties and method signatures, always use `aicontext.md` or inspect the current x4 TypeScript sources.
|
|
7
7
|
|
|
8
|
+
**At each update of x4, read its `changelog.md`** (in `node_modules/x4js`): the sections from the version the project used to the new one, before writing code. It says what changed and the migrations to make (a variable renamed, a behaviour changed, a fix an application may have worked around).
|
|
9
|
+
|
|
8
10
|
**Do not invent x4 APIs.**
|
|
9
11
|
|
|
10
12
|
## 1. General rule
|