jsl-ui 9.28.7 → 10.0.0

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 (166) hide show
  1. package/docs/AutoSuggestComponent.md +17 -0
  2. package/docs/ButtonComponent.md +14 -0
  3. package/docs/CheckBoxComponent.md +12 -0
  4. package/docs/DateComponent.md +12 -0
  5. package/docs/DateRangeComponent.md +13 -0
  6. package/docs/DateTimeComponent.md +13 -0
  7. package/docs/DialogComponent.md +15 -0
  8. package/docs/ExpanderComponent.md +13 -0
  9. package/docs/FormComponent.md +15 -0
  10. package/docs/FormFieldComponent.md +15 -0
  11. package/docs/GridComponent.md +19 -0
  12. package/docs/InputComponent.md +15 -0
  13. package/docs/IntervalComponent.md +13 -0
  14. package/docs/LoadingComponent.md +12 -0
  15. package/docs/NavigationComponent.md +17 -0
  16. package/docs/Notification.md +14 -0
  17. package/docs/NotificationComponent.md +13 -0
  18. package/docs/NumberComponent.md +12 -0
  19. package/docs/OverlayComponent.md +12 -0
  20. package/docs/ProgressComponent.md +12 -0
  21. package/docs/README.md +24 -0
  22. package/docs/RibbonMenuComponent.md +14 -0
  23. package/docs/SelectComponent.md +15 -0
  24. package/docs/SplitterComponent.md +14 -0
  25. package/docs/StackPanelComponent.md +13 -0
  26. package/docs/TabsComponent.md +16 -0
  27. package/docs/TimeComponent.md +13 -0
  28. package/docs/TreeViewComponent.md +16 -0
  29. package/examples/showcase/checks-and-expanders.ts +163 -0
  30. package/examples/showcase/cultures.ts +39 -0
  31. package/examples/showcase/dates.ts +182 -0
  32. package/examples/showcase/dialogs.ts +184 -0
  33. package/examples/showcase/feedback-and-navigation.ts +174 -0
  34. package/examples/showcase/fields.ts +178 -0
  35. package/examples/showcase/fonts/Jost-Variable.ttf +0 -0
  36. package/examples/showcase/fonts/OFL-Jost.txt +93 -0
  37. package/examples/showcase/grids.ts +150 -0
  38. package/examples/showcase/index.html +60 -0
  39. package/examples/showcase/layout-and-navigation.ts +47 -0
  40. package/examples/showcase/nivona.css +98 -0
  41. package/examples/showcase/selects.ts +158 -0
  42. package/examples/showcase/showcase.css +231 -0
  43. package/examples/showcase/showcase.ts +214 -0
  44. package/examples/showcase/tabs.ts +161 -0
  45. package/examples/showcase/themes.css +83 -0
  46. package/examples/showcase/themes.ts +54 -0
  47. package/lib/components/IntervalComponent.d.ts +5 -0
  48. package/lib/components/IntervalComponent.js +29 -13
  49. package/lib/components/auto-suggest/AutoSuggestComponent.d.ts +11 -9
  50. package/lib/components/auto-suggest/AutoSuggestComponent.js +25 -38
  51. package/lib/components/button/ButtonComponent.d.ts +30 -1
  52. package/lib/components/button/ButtonComponent.js +85 -4
  53. package/lib/components/checkbox/CheckBoxComponent.d.ts +11 -1
  54. package/lib/components/checkbox/CheckBoxComponent.js +66 -56
  55. package/lib/components/checkbox/CheckBoxStyle.scss +72 -85
  56. package/lib/components/date/DateComponent.d.ts +10 -0
  57. package/lib/components/date/DateComponent.js +92 -44
  58. package/lib/components/date-range/DateRangeComponent.d.ts +14 -3
  59. package/lib/components/date-range/DateRangeComponent.js +96 -86
  60. package/lib/components/date-range/DateRangeStyle.scss +35 -11
  61. package/lib/components/date-time/DateTimeComponent.d.ts +8 -0
  62. package/lib/components/date-time/DateTimeComponent.js +64 -23
  63. package/lib/components/date-time/DateTimeStyle.scss +10 -7
  64. package/lib/components/dialog/DialogComponent.d.ts +21 -7
  65. package/lib/components/dialog/DialogComponent.js +179 -122
  66. package/lib/components/expander/ExpanderComponent.d.ts +15 -1
  67. package/lib/components/expander/ExpanderComponent.js +85 -64
  68. package/lib/components/expander/ExpanderStyle.scss +61 -47
  69. package/lib/components/form-field/FormFieldComponent.d.ts +45 -15
  70. package/lib/components/form-field/FormFieldComponent.js +249 -96
  71. package/lib/components/form-field/FormFieldStyle.scss +36 -87
  72. package/lib/components/form-field/create-control.d.ts +7 -0
  73. package/lib/components/form-field/create-control.js +48 -0
  74. package/lib/components/input/InputComponent.d.ts +18 -1
  75. package/lib/components/input/InputComponent.js +68 -93
  76. package/lib/components/loading/LoadingComponent.d.ts +9 -2
  77. package/lib/components/loading/LoadingComponent.js +13 -12
  78. package/lib/components/loading/LoadingStyle.css +19 -29
  79. package/lib/components/navigation/NavigationComponent.d.ts +34 -10
  80. package/lib/components/navigation/NavigationComponent.js +261 -33
  81. package/lib/components/navigation/NavigationStyle.scss +62 -226
  82. package/lib/components/notification/Notification.d.ts +37 -4
  83. package/lib/components/notification/Notification.js +160 -41
  84. package/lib/components/notification/Notification.scss +103 -19
  85. package/lib/components/number/NumberComponent.d.ts +16 -2
  86. package/lib/components/number/NumberComponent.js +54 -53
  87. package/lib/components/overlay/OverlayComponent.d.ts +13 -7
  88. package/lib/components/overlay/OverlayComponent.js +46 -114
  89. package/lib/components/overlay/overlay.css +18 -57
  90. package/lib/components/progress/ProgressComponent.d.ts +1 -0
  91. package/lib/components/progress/ProgressComponent.js +6 -6
  92. package/lib/components/progress/ProgressStyle.scss +5 -15
  93. package/lib/components/ribbon-menu/RibbonMenuComponent.js +2 -2
  94. package/lib/components/ribbon-menu/RibbonMenuStyle.scss +6 -76
  95. package/lib/components/select/SelectComponent.d.ts +33 -3
  96. package/lib/components/select/SelectComponent.js +312 -278
  97. package/lib/components/select/SelectDDAreaComponent.d.ts +13 -7
  98. package/lib/components/select/SelectDDAreaComponent.js +215 -256
  99. package/lib/components/select/SelectStyle.scss +204 -186
  100. package/lib/components/slider/nouislider.css +40 -54
  101. package/lib/components/stack-panel/SplitterComponent.d.ts +19 -3
  102. package/lib/components/stack-panel/SplitterComponent.js +94 -111
  103. package/lib/components/stack-panel/SplitterStyle.scss +9 -45
  104. package/lib/components/stack-panel/StackPanelComponent.js +3 -3
  105. package/lib/components/stack-panel/StackPanelStyle.scss +10 -52
  106. package/lib/components/tabs/TabsComponent.d.ts +17 -1
  107. package/lib/components/tabs/TabsComponent.js +247 -123
  108. package/lib/components/tabs/TabsStyle.scss +138 -75
  109. package/lib/components/time/TimeComponent.d.ts +5 -0
  110. package/lib/components/time/TimeComponent.js +61 -69
  111. package/lib/components/time/TimeComponent.scss +4 -4
  112. package/lib/components/tree-view/TreeViewComponent.d.ts +10 -4
  113. package/lib/components/tree-view/TreeViewComponent.js +65 -32
  114. package/lib/components/tree-view/TreeViewStyle.scss +12 -96
  115. package/lib/core/date.d.ts +2 -0
  116. package/lib/core/date.js +6 -0
  117. package/lib/core/jq.js +11 -8
  118. package/lib/grid/slick-default-theme.css +107 -31
  119. package/lib/grid/slick.creator.js +23 -5
  120. package/lib/grid/slick.formatters.js +4 -3
  121. package/lib/grid/slick.grid.css +38 -26
  122. package/lib/grid/slick.grid.d.ts +1 -0
  123. package/lib/grid/slick.grid.js +2 -3
  124. package/lib/grid.css +3413 -454
  125. package/lib/index.css +2500 -1031
  126. package/lib/index.css.map +1 -1
  127. package/lib/index.d.ts +1 -0
  128. package/lib/index.js +1 -1
  129. package/lib/index.js.map +1 -1
  130. package/lib/interaction/moveable.d.ts +1 -0
  131. package/lib/interaction/moveable.js +8 -0
  132. package/lib/interaction/resizable.d.ts +1 -0
  133. package/lib/interaction/resizable.js +9 -0
  134. package/lib/ui/auto.suggest.css +31 -14
  135. package/lib/ui/auto.suggest.d.ts +1 -0
  136. package/lib/ui/auto.suggest.js +88 -18
  137. package/lib/ui/base.css +2 -48
  138. package/lib/ui/button.css +134 -0
  139. package/lib/ui/date-input.css +11 -0
  140. package/lib/ui/date.picker/css/tiny-date-picker.css +124 -325
  141. package/lib/ui/date.picker/date-picker-options.js +4 -3
  142. package/lib/ui/date.picker/lib/date-manip.js +9 -0
  143. package/lib/ui/date.picker/mode/base-mode.d.ts +2 -1
  144. package/lib/ui/date.picker/mode/base-mode.js +112 -22
  145. package/lib/ui/date.picker/mode/dropdown-mode.d.ts +2 -4
  146. package/lib/ui/date.picker/mode/dropdown-mode.js +29 -42
  147. package/lib/ui/date.picker/mode/index.d.ts +2 -1
  148. package/lib/ui/date.picker/mode/modal-mode.d.ts +2 -1
  149. package/lib/ui/date.picker/mode/modal-mode.js +4 -2
  150. package/lib/ui/date.picker/mode/permanent-mode.d.ts +2 -1
  151. package/lib/ui/date.picker/views/day-picker.js +24 -15
  152. package/lib/ui/date.picker/views/month-picker.js +1 -1
  153. package/lib/ui/date.picker/views/year-picker.js +3 -2
  154. package/lib/ui/date.picker.d.ts +2 -1
  155. package/lib/ui/dialog.css +144 -108
  156. package/lib/ui/dialog.d.ts +19 -1
  157. package/lib/ui/dialog.js +178 -60
  158. package/lib/ui/input.css +35 -0
  159. package/lib/ui/number.input.js +50 -37
  160. package/lib/ui/theme.css +28 -0
  161. package/package.json +12 -8
  162. package/lib/components/drop-down/DropDownComponent.d.ts +0 -27
  163. package/lib/components/drop-down/DropDownComponent.js +0 -60
  164. package/lib/components/expander/OldExpanderStyle.scss +0 -37
  165. package/lib/ui/drop.down.d.ts +0 -52
  166. package/lib/ui/drop.down.js +0 -2112
@@ -1,47 +1,34 @@
1
1
  import { AutoSuggest } from "../../ui/auto.suggest";
2
- export class AutoSuggestComponent {
2
+ import { InputComponent } from "../input/InputComponent";
3
+ export class AutoSuggestComponent extends InputComponent {
3
4
  constructor(options) {
4
- this.options = options;
5
- // this.id = this.options.id ?? helper.newDomGuid();
5
+ super({ ...options, type: "text", onChange: undefined });
6
+ this.suggestOptions = { ...options };
6
7
  }
7
- render() {
8
- var _a;
9
- return {
10
- tag: "input",
11
- attr: { value: this.options.value, class: this.options.class, style: this.options.style, placeholder: (_a = this.options.placeholder) !== null && _a !== void 0 ? _a : "" }
12
- };
13
- }
14
- getRef() {
15
- return this.ref;
16
- }
17
- getValue() {
18
- if (this.dom == null) {
19
- return "";
20
- }
21
- return this.dom.value;
22
- }
23
- setValue(val) {
24
- if (this.dom == null) {
25
- return;
26
- }
27
- this.dom.value = val;
28
- }
29
- focus() {
30
- if (this.dom == null) {
8
+ getRef() { return this.ref; }
9
+ onCreate(node) {
10
+ super.onCreate(node);
11
+ this.input = node.dom;
12
+ if (this.suggestOptions.enabled === false || this.suggestOptions.readOnly) {
31
13
  return;
32
14
  }
33
- this.dom.focus();
34
- }
35
- onCreate(node) {
36
- this.dom = node.dom;
37
- AutoSuggest(node.dom, this.options);
38
- }
39
- onUpdate(node) {
40
- this.dom = node.dom;
15
+ this.ref = AutoSuggest(this.input, {
16
+ ...this.suggestOptions,
17
+ onChange: value => { var _a, _b, _c; this.setValue(value); (_b = (_a = this.suggestOptions).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, value); (_c = this.renderer) === null || _c === void 0 ? void 0 : _c.refresh(); },
18
+ onSelect: (event, term, element) => {
19
+ var _a, _b, _c;
20
+ this.setValue(term);
21
+ (_b = (_a = this.suggestOptions).onSelect) === null || _b === void 0 ? void 0 : _b.call(_a, event, term, element);
22
+ this.input.dispatchEvent(new Event("change", { bubbles: true }));
23
+ (_c = this.renderer) === null || _c === void 0 ? void 0 : _c.refresh();
24
+ }
25
+ });
41
26
  }
42
27
  onRemove() {
43
- if (this.ref != null) {
44
- this.ref.destroy();
45
- }
28
+ var _a;
29
+ (_a = this.ref) === null || _a === void 0 ? void 0 : _a.destroy();
30
+ this.ref = null;
31
+ this.input = null;
32
+ super.onRemove();
46
33
  }
47
34
  }
@@ -1,18 +1,47 @@
1
+ import "../../ui/button.css";
1
2
  import { IJSLComponent, IJSLVNode } from "jsl-render";
2
3
  import { EventHandler } from "../../interaction/eventhandler";
3
4
  export interface IButtonOptions {
4
- content: string | IJSLVNode | IJSLComponent;
5
+ content?: string | IJSLVNode | IJSLComponent;
5
6
  enabled?: boolean;
6
7
  class?: string;
7
8
  outlined?: boolean;
8
9
  style?: string;
9
10
  click?: EventHandler<MouseEvent> | ((evt?: MouseEvent) => void);
11
+ /** Optional decorative icon. Strings are text, not HTML or an icon-library class. */
12
+ icon?: string | IJSLVNode | IJSLComponent;
13
+ iconPosition?: "start" | "end";
14
+ /** Hide the content visually, keeping it as the accessible name. */
15
+ iconOnly?: boolean;
16
+ /** Supply an accessible name when there is no text content. */
17
+ ariaLabel?: string;
18
+ title?: string;
19
+ variant?: "solid" | "outline" | "ghost";
20
+ size?: "small" | "medium" | "large";
21
+ toggle?: boolean;
22
+ /** Initial toggle state. Use the component's pressed property to update it. */
23
+ pressed?: boolean;
24
+ onToggle?: EventHandler<boolean> | ((pressed?: boolean) => void);
25
+ /** Omitted by default to preserve native form-submit behavior. */
26
+ type?: "button" | "submit" | "reset";
10
27
  }
11
28
  export declare class ButtonComponent implements IJSLComponent {
29
+ State: {
30
+ pressed?: boolean;
31
+ dom?: HTMLButtonElement;
32
+ };
12
33
  private options;
13
34
  get click(): EventHandler<MouseEvent>;
35
+ get onToggle(): EventHandler<boolean>;
36
+ get pressed(): boolean;
37
+ /** Programmatic updates do not raise click or onToggle. */
38
+ set pressed(value: boolean);
14
39
  constructor(options: IButtonOptions);
15
40
  isEqual(node: IJSLComponent): boolean;
16
41
  render(): IJSLVNode;
42
+ onCreate(node: IJSLVNode): void;
43
+ onUpdate(node: IJSLVNode): void;
44
+ onRemove(): void;
45
+ private toNode;
17
46
  private raiseEvent;
18
47
  }
@@ -1,28 +1,109 @@
1
+ import "../../ui/button.css";
1
2
  import { EventHandler } from "../../interaction/eventhandler";
2
3
  export class ButtonComponent {
3
4
  get click() {
4
5
  return this.options.click;
5
6
  }
7
+ get onToggle() {
8
+ return this.options.onToggle;
9
+ }
10
+ get pressed() {
11
+ var _a;
12
+ return (_a = this.State.pressed) !== null && _a !== void 0 ? _a : !!this.options.pressed;
13
+ }
14
+ /** Programmatic updates do not raise click or onToggle. */
15
+ set pressed(value) {
16
+ this.State.pressed = !!value;
17
+ if (this.State.dom != null && this.options.toggle) {
18
+ this.State.dom.setAttribute("aria-pressed", String(this.pressed));
19
+ this.State.dom.classList.toggle("active", this.pressed);
20
+ }
21
+ }
6
22
  constructor(options) {
23
+ // jsl-render carries State across replacement component instances.
24
+ this.State = {};
7
25
  this.options = { ...{ enabled: true, class: "" }, ...options };
8
26
  this.options.click = EventHandler.Create(this.options.click);
27
+ this.options.onToggle = EventHandler.Create(this.options.onToggle);
9
28
  }
10
29
  isEqual(node) {
11
30
  return this.__proto__ === node.__proto__;
12
31
  }
13
32
  render() {
33
+ const variant = this.options.variant || (this.options.outlined ? "outline" : "solid");
34
+ const hasContent = this.options.content != null && this.options.content !== "";
35
+ const iconOnly = this.options.iconOnly || (!hasContent && this.options.icon != null);
36
+ const classes = ["jsl-button"];
37
+ if (variant !== "solid") {
38
+ classes.push("jsl-button-" + variant);
39
+ }
40
+ if (this.options.size && this.options.size !== "medium") {
41
+ classes.push("jsl-button-" + this.options.size);
42
+ }
43
+ if (iconOnly) {
44
+ classes.push("jsl-button-icon-only");
45
+ }
46
+ if (this.options.toggle && this.pressed) {
47
+ classes.push("active");
48
+ }
49
+ if (!this.options.enabled) {
50
+ classes.push("disabled");
51
+ }
52
+ classes.push(this.options.class);
53
+ const children = [];
54
+ if (hasContent) {
55
+ children.push(this.toNode(this.options.content, iconOnly ? "jsl-button-label-hidden" : "jsl-button-label"));
56
+ }
57
+ if (this.options.icon != null) {
58
+ const icon = this.toNode(this.options.icon, "jsl-button-icon");
59
+ icon.attr["aria-hidden"] = "true";
60
+ if (this.options.iconPosition === "end") {
61
+ children.push(icon);
62
+ }
63
+ else {
64
+ children.unshift(icon);
65
+ }
66
+ }
14
67
  return {
15
68
  tag: "button",
16
69
  attr: {
17
- class: "jsl-button " + (this.options.outlined ? "jsl-button-outline " : "") +
18
- this.options.class + (!this.options.enabled ? " disabled" : ""), style: this.options.style, click: this.raiseEvent
70
+ class: classes.filter(Boolean).join(" "),
71
+ style: this.options.style,
72
+ click: this.raiseEvent,
73
+ disabled: !this.options.enabled ? "disabled" : undefined,
74
+ "aria-pressed": this.options.toggle ? String(this.pressed) : undefined,
75
+ "aria-label": this.options.ariaLabel,
76
+ title: this.options.title,
77
+ type: this.options.type
19
78
  },
20
- content: typeof this.options.content === "string" ? this.options.content : "",
21
- children: typeof this.options.content !== "string" ? [this.options.content] : []
79
+ // Preserve the original DOM structure for existing text-only and custom-content buttons.
80
+ content: this.options.icon == null && !iconOnly && typeof this.options.content === "string" ? this.options.content : "",
81
+ children: this.options.icon == null && !iconOnly ?
82
+ (hasContent && typeof this.options.content !== "string" ? [this.options.content] : []) : children
83
+ };
84
+ }
85
+ onCreate(node) {
86
+ this.State.dom = node.dom;
87
+ }
88
+ onUpdate(node) {
89
+ this.State.dom = node.dom;
90
+ }
91
+ onRemove() {
92
+ this.State.dom = undefined;
93
+ }
94
+ toNode(content, className) {
95
+ return {
96
+ tag: "span", attr: { class: className },
97
+ content: typeof content === "string" ? content : "",
98
+ children: typeof content === "string" ? [] : [content]
22
99
  };
23
100
  }
24
101
  raiseEvent(evt) {
25
102
  if (this.options.enabled) {
103
+ if (this.options.toggle) {
104
+ this.pressed = !this.pressed;
105
+ this.onToggle.notify(this.pressed);
106
+ }
26
107
  this.options.click.notify(evt);
27
108
  }
28
109
  }
@@ -14,6 +14,9 @@ export interface ICheckBoxOptions<T = any> {
14
14
  property?: keyof T;
15
15
  bindMode?: "toModel" | "fromModel" | "both";
16
16
  converter?: IDataConverter<any, boolean>;
17
+ description?: string;
18
+ ariaLabel?: string;
19
+ indeterminate?: boolean;
17
20
  }
18
21
  export declare class CheckBoxComponent<T = any> implements IJSLComponent {
19
22
  private options;
@@ -22,7 +25,14 @@ export declare class CheckBoxComponent<T = any> implements IJSLComponent {
22
25
  constructor(options: ICheckBoxOptions<T>);
23
26
  render(): IJSLVNode;
24
27
  getValue(): boolean;
25
- setValue(val: boolean): void;
28
+ /** Updates checked state and writable bindings without raising onChange. */
29
+ setValue(value: boolean): void;
30
+ get indeterminate(): boolean;
31
+ set indeterminate(value: boolean);
26
32
  onCreate(node: IJSLVNode): void;
33
+ onRemove(): void;
34
+ private hasBinding;
35
+ private readModel;
36
+ private writeModel;
27
37
  private raiseEvent;
28
38
  }
@@ -2,80 +2,90 @@ import "./CheckBoxStyle.scss";
2
2
  import { EventHandler } from "../../interaction/eventhandler";
3
3
  import { helper } from "../../core/helper";
4
4
  export class CheckBoxComponent {
5
- get onChange() {
6
- return this.options.onChange;
7
- }
5
+ get onChange() { return this.options.onChange; }
8
6
  constructor(options) {
9
- var _a;
10
- this.options = { ...{ enabled: true, class: "", bindMode: "toModel" }, ...options };
11
- if (!this.options.id) {
12
- this.options.id = helper.newDomGuid();
13
- }
14
- if (this.options.bindTo != null && this.options.property != null && this.options.value == null) {
15
- this.options.value = (((_a = this.options.converter) === null || _a === void 0 ? void 0 : _a.toUI) ?
16
- this.options.converter.toUI(this.options.bindTo[this.options.property]) :
17
- this.options.bindTo[this.options.property]);
7
+ this.options = { enabled: true, class: "", bindMode: "toModel", ...options };
8
+ this.options.id = this.options.id || helper.newDomGuid();
9
+ if (this.hasBinding() && this.options.value == null) {
10
+ this.options.value = this.readModel();
18
11
  }
19
12
  this.options.onChange = EventHandler.Create(this.options.onChange);
20
13
  }
21
- // public isEqual(node: IJSLComponent): boolean {
22
- // return (this as any).__proto__ === (node as any).__proto__;
23
- // }
24
14
  render() {
25
15
  var _a;
26
- let val = this.options.value;
27
- if (this.options.bindMode !== "toModel" && this.options.bindTo != null && this.options.property != null) {
28
- const current = this.getValue();
29
- const newVal = (((_a = this.options.converter) === null || _a === void 0 ? void 0 : _a.toUI) ?
30
- this.options.converter.toUI(this.options.bindTo[this.options.property]) :
31
- this.options.bindTo[this.options.property]);
32
- val = newVal;
33
- if (newVal !== current) {
34
- if (this.currentDom != null) {
35
- this.currentDom.checked = val;
36
- }
37
- }
16
+ if (this.options.bindMode !== "toModel" && this.hasBinding()) {
17
+ this.options.value = this.readModel();
18
+ }
19
+ if (this.currentDom) {
20
+ this.currentDom.checked = !!this.options.value;
21
+ this.currentDom.indeterminate = !!this.options.indeterminate;
38
22
  }
39
23
  return {
40
- tag: "span",
41
- attr: { style: this.options.style },
42
- children: [{
43
- tag: "input",
44
- attr: {
45
- type: "checkbox",
46
- disabled: !this.options.enabled ? "disabled" : undefined,
47
- class: "checkbox-comp " + (this.options.class || ""),
48
- change: this.raiseEvent,
49
- checked: val ? "checked" : undefined,
50
- id: typeof this.options.id === "string" ? this.options.id : undefined
24
+ tag: "span", attr: {
25
+ class: "jsl-checkbox" + (!this.options.enabled ? " disabled" : ""),
26
+ style: this.options.style
27
+ }, children: [
28
+ {
29
+ tag: "input", attr: {
30
+ type: "checkbox", disabled: this.options.enabled ? undefined : "disabled",
31
+ class: "checkbox-comp " + ((_a = this.options.class) !== null && _a !== void 0 ? _a : ""),
32
+ checked: this.options.value ? "checked" : undefined,
33
+ id: this.options.id, "aria-label": this.options.ariaLabel,
34
+ "aria-describedby": this.options.description ? this.options.id + "-description" : undefined,
35
+ change: this.raiseEvent
51
36
  }
52
- }, { tag: "label", content: this.options.label, attr: { for: this.options.id } }]
37
+ },
38
+ { tag: "span", attr: { class: "checkbox-copy" }, children: [
39
+ { tag: "label", content: this.options.label, attr: { for: this.options.id, class: "checkbox-label" } },
40
+ { tag: "span", content: this.options.description, attr: {
41
+ id: this.options.id + "-description", class: "checkbox-description",
42
+ hidden: this.options.description ? undefined : "hidden"
43
+ } }
44
+ ] }
45
+ ]
53
46
  };
54
47
  }
55
- getValue() {
56
- var _a;
57
- return ((_a = this.currentDom) === null || _a === void 0 ? void 0 : _a.checked) || false;
58
- }
59
- setValue(val) {
60
- var _a;
61
- if (this.currentDom != null) {
62
- this.currentDom.checked = val;
48
+ getValue() { var _a, _b; return (_b = (_a = this.currentDom) === null || _a === void 0 ? void 0 : _a.checked) !== null && _b !== void 0 ? _b : !!this.options.value; }
49
+ /** Updates checked state and writable bindings without raising onChange. */
50
+ setValue(value) {
51
+ this.options.value = !!value;
52
+ if (this.currentDom) {
53
+ this.currentDom.checked = !!value;
63
54
  }
64
- if (this.options.bindTo && this.options.bindMode !== "fromModel" && this.options.property) {
65
- this.options.bindTo[this.options.property] = ((_a = this.options.converter) === null || _a === void 0 ? void 0 : _a.toData) ? this.options.converter.toData(val) : val;
55
+ this.writeModel(!!value);
56
+ }
57
+ get indeterminate() { var _a, _b; return (_b = (_a = this.currentDom) === null || _a === void 0 ? void 0 : _a.indeterminate) !== null && _b !== void 0 ? _b : !!this.options.indeterminate; }
58
+ set indeterminate(value) {
59
+ this.options.indeterminate = !!value;
60
+ if (this.currentDom) {
61
+ this.currentDom.indeterminate = !!value;
66
62
  }
67
63
  }
68
64
  onCreate(node) {
69
65
  this.currentDom = node.dom.querySelector("input");
66
+ this.currentDom.indeterminate = !!this.options.indeterminate;
67
+ }
68
+ onRemove() { this.currentDom = null; }
69
+ hasBinding() { return this.options.bindTo != null && this.options.property != null; }
70
+ readModel() {
71
+ var _a;
72
+ const value = this.options.bindTo[this.options.property];
73
+ return !!(((_a = this.options.converter) === null || _a === void 0 ? void 0 : _a.toUI) ? this.options.converter.toUI(value) : value);
70
74
  }
71
- raiseEvent(e, node) {
75
+ writeModel(value) {
72
76
  var _a;
73
- if (this.options.enabled) {
74
- const value = node.dom.checked;
75
- if (this.options.bindTo && this.options.bindMode !== "fromModel" && this.options.property) {
76
- this.options.bindTo[this.options.property] = ((_a = this.options.converter) === null || _a === void 0 ? void 0 : _a.toData) ? this.options.converter.toData(value) : value;
77
- }
78
- this.options.onChange.notify(value);
77
+ if (this.hasBinding() && this.options.bindMode !== "fromModel") {
78
+ this.options.bindTo[this.options.property] = ((_a = this.options.converter) === null || _a === void 0 ? void 0 : _a.toData) ? this.options.converter.toData(value) : value;
79
+ }
80
+ }
81
+ raiseEvent(event, node) {
82
+ if (!this.options.enabled) {
83
+ return false;
79
84
  }
85
+ this.currentDom = node.dom;
86
+ this.options.value = this.currentDom.checked;
87
+ this.options.indeterminate = this.currentDom.indeterminate;
88
+ this.writeModel(this.options.value);
89
+ this.onChange.notify(this.options.value);
80
90
  }
81
91
  }
@@ -1,86 +1,73 @@
1
- @keyframes checkbox-comp-hover-color{
2
- from{
3
- border-color:#C0C0C0;
4
- }
5
- to{
6
- border-color:#3B99FF;
7
- }
8
- }
9
- .checkbox-comp{
10
- position:absolute;
11
- display:none;
12
- }
13
- .checkbox-comp[disabled]{
14
- cursor:not-allowed
15
- }
16
- .checkbox-comp+label{
17
- position:relative;
18
- // display:block;
19
- padding-left:1.5em;
20
- cursor:pointer;
21
- vertical-align:middle;
22
- }
23
- .checkbox-comp+label:hover:before{
24
- animation-duration:.4s;
25
- animation-fill-mode:both;
26
- animation-name:checkbox-comp-hover-color;
27
- }
28
- .checkbox-comp+label:before{
29
- position:absolute;
30
- top:0;
31
- left:0;
32
- display:inline-block;
33
- width:1em;
34
- height:1em;
35
- content:'';
36
- border:1px solid #C0C0C0;
37
- }
38
- .checkbox-comp+label:after{
39
- position:absolute;
40
- display:none;
41
- content:''
42
- }
43
- .checkbox-comp[disabled]+label{
44
- cursor:not-allowed;
45
- // color:#C0C0C0;
46
- }
47
- .checkbox-comp[disabled]+label:hover,.checkbox-comp[disabled]+label:before,.checkbox-comp[disabled]+label:after{
48
- cursor:not-allowed
49
- }
50
- .checkbox-comp[disabled]+label:hover:before{
51
- border:1px solid #C0C0C0;
52
- animation-name:none
53
- }
54
- .checkbox-comp[disabled]+label:before{
55
- border-color:#C0C0C0;
56
- }
57
- .checkbox-comp:checked+label:before{
58
- animation-name:none
59
- }
60
- .checkbox-comp:checked+label:after{
61
- display:block
62
- }
63
- .checkbox-comp+label:before{
64
- border-radius:0.2em;
65
- }
66
- .checkbox-comp+label:after{
67
- top:0.1em; //2px;
68
- left:0.3em; //7px;
69
- box-sizing:border-box;
70
- width:0.5em; //6px;
71
- height:0.7em; //12px;
72
- transform:rotate(45deg);
73
- border-width:0.15em;
74
- border-style:solid;
75
- border-color:#fff;
76
- border-top:0;
77
- border-left:0
78
- }
79
- .checkbox-comp:checked+label:before{
80
- border-color:#3B99FF;
81
- background:#3B99FF;
82
- }
83
- .checkbox-comp:checked[disabled]+label:before{
84
- border-color:#c9e2f9;
85
- background:#c9e2f9
1
+ @import "../../ui/theme.css";
2
+
3
+ .jsl-checkbox {
4
+ display: inline-flex;
5
+ align-items: flex-start;
6
+ gap: .625rem;
7
+ max-width: 100%;
8
+ color: var(--jsl-color-text);
9
+ font: inherit;
10
+ font-size: .875rem;
11
+ line-height: 1.5;
12
+ vertical-align: middle;
13
+ }
14
+ .checkbox-comp {
15
+ appearance: none;
16
+ -webkit-appearance: none;
17
+ box-sizing: border-box;
18
+ position: relative;
19
+ display: inline-grid;
20
+ place-content: center;
21
+ flex: 0 0 1.125rem;
22
+ width: 1.125rem;
23
+ height: 1.125rem;
24
+ margin: calc((1.5em - 1.125rem) / 2) 0 0;
25
+ border: 1px solid var(--jsl-color-border);
26
+ border-radius: .25rem;
27
+ background: var(--jsl-color-surface);
28
+ color: var(--jsl-color-on-accent);
29
+ font: inherit;
30
+ cursor: pointer;
31
+ transition: background-color .12s, border-color .12s;
32
+ }
33
+ .checkbox-comp::after {
34
+ content: "";
35
+ width: 4px;
36
+ height: 8px;
37
+ margin-top: -2px;
38
+ border: solid currentColor;
39
+ border-width: 0 1.5px 1.5px 0;
40
+ transform: rotate(45deg);
41
+ opacity: 0;
42
+ }
43
+ .checkbox-comp:checked, .checkbox-comp:indeterminate {
44
+ border-color: var(--jsl-color-accent);
45
+ background: var(--jsl-color-accent);
46
+ }
47
+ .checkbox-comp:checked::after, .checkbox-comp:indeterminate::after { opacity: 1; }
48
+ .checkbox-comp:indeterminate::after {
49
+ width: 8px;
50
+ height: 0;
51
+ margin-top: 0;
52
+ border-width: 0 0 2px;
53
+ transform: none;
54
+ }
55
+ .checkbox-comp:focus-visible { outline: 2px solid var(--jsl-color-focus); outline-offset: 3px; }
56
+ .jsl-checkbox:has(.checkbox-comp:not(:disabled)):hover .checkbox-comp { border-color: var(--jsl-color-text-muted); }
57
+ .jsl-checkbox:has(.checkbox-comp:checked:not(:disabled)):hover .checkbox-comp,
58
+ .jsl-checkbox:has(.checkbox-comp:indeterminate:not(:disabled)):hover .checkbox-comp {
59
+ border-color: var(--jsl-color-accent-hover);
60
+ background: var(--jsl-color-accent-hover);
61
+ }
62
+ .checkbox-copy { min-width: 0; }
63
+ .checkbox-label { display: block; cursor: pointer; overflow-wrap: anywhere; }
64
+ .checkbox-description { display: block; margin-top: .1875rem; color: var(--jsl-color-text-muted); font-size: .75rem; line-height: 1.5; }
65
+ .checkbox-description[hidden] { display: none; }
66
+ .checkbox-comp:disabled { background: var(--jsl-color-disabled-surface); border-color: var(--jsl-color-border-subtle); cursor: not-allowed; }
67
+ .checkbox-comp:disabled:checked, .checkbox-comp:disabled:indeterminate { background: var(--jsl-color-disabled-text); border-color: var(--jsl-color-disabled-text); color: var(--jsl-color-disabled-surface); opacity: .65; }
68
+ .jsl-checkbox.disabled .checkbox-label { color: var(--jsl-color-disabled-text); cursor: not-allowed; }
69
+ @media (prefers-reduced-motion: reduce) { .checkbox-comp { transition: none; } }
70
+ @media (forced-colors: active) {
71
+ .checkbox-comp { appearance: auto; }
72
+ .checkbox-comp::after { display: none; }
86
73
  }
@@ -1,3 +1,4 @@
1
+ import "../../ui/date-input.css";
1
2
  import { IJSLComponent, IJSLVNode } from "jsl-render";
2
3
  import { IDatePickerOptions, IDatePicker } from "../../ui/date.picker";
3
4
  import { EventHandler } from "../../interaction/eventhandler";
@@ -7,6 +8,7 @@ export interface IDateComponentOptions<T = any> extends IDatePickerOptions {
7
8
  class?: string;
8
9
  style?: string;
9
10
  placeholder?: string;
11
+ ariaLabel?: string;
10
12
  value?: Date;
11
13
  onChange?: EventHandler<Date> | ((v?: Date) => void);
12
14
  bindTo?: T;
@@ -19,14 +21,22 @@ export declare class DateComponent<T = any> implements IJSLComponent {
19
21
  private options;
20
22
  private ref;
21
23
  private currentDom;
24
+ private modelValue;
22
25
  constructor(options: IDateComponentOptions<T>);
23
26
  get onChange(): EventHandler<Date>;
24
27
  render(): IJSLVNode;
25
28
  getValue(): string;
26
29
  getValueAsDate(): Date;
30
+ isValid(): boolean;
31
+ /** Updates the input and calendar without raising onChange. */
32
+ setValue(value: Date): void;
27
33
  getRef(): IDatePicker;
28
34
  onCreate(node: IJSLVNode): void;
29
35
  onUpdate(node: IJSLVNode): void;
30
36
  onRemove(): void;
37
+ private format;
38
+ private hasBinding;
39
+ private readModel;
31
40
  private raiseEvent;
41
+ private parseBoundary;
32
42
  }