@lundal/zed-solid 0.0.12 → 0.0.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.
@@ -7,6 +7,6 @@ export type IconButtonProps = {
7
7
  type: "primary" | "secondary" | "tertiary";
8
8
  icon: JSX.Element;
9
9
  label: string;
10
- onClick: () => void;
10
+ onClick: "submit" | (() => void);
11
11
  };
12
12
  export declare function IconButton(props: IconButtonProps): JSX.Element;
package/dist/index.d.ts CHANGED
@@ -22,3 +22,6 @@ export * from './Row.tsx';
22
22
  export * from './Select.tsx';
23
23
  export * from './Spinner.tsx';
24
24
  export * from './TextBox.tsx';
25
+ export * from './signals/createForm.ts';
26
+ export * from './signals/createInterval.ts';
27
+ export * from './signals/createSize.ts';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import './style.css';
2
2
  import "@fontsource/inter/400.css";
3
3
  import "@fontsource/inter/500.css";
4
- import { sharedConfig, createRenderEffect, untrack, createComponent, For, createMemo, createSignal, onMount } from "solid-js";
4
+ import { sharedConfig, createRenderEffect, untrack, createComponent, For, createMemo, createSignal, onMount, onCleanup } from "solid-js";
5
5
  import { A } from "@solidjs/router";
6
6
  function reconcileArrays(parentNode, a, b) {
7
7
  let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = a[aEnd - 1].nextSibling, map = null;
@@ -684,22 +684,24 @@ var _tmpl$$a = /* @__PURE__ */ template(`<button>`);
684
684
  function IconButton(props) {
685
685
  return (() => {
686
686
  var _el$ = _tmpl$$a();
687
- _el$.$$click = () => !props.busy && props.onClick();
687
+ _el$.$$click = () => props.onClick !== "submit" && !props.busy && props.onClick();
688
688
  insert(_el$, () => props.icon);
689
689
  createRenderEffect((_p$) => {
690
- var _v$ = mergeClasses(`z-button z-button--icon z-button--${props.type}`, props.class), _v$2 = props.style, _v$3 = props.busy, _v$4 = props.label, _v$5 = props.label;
690
+ var _v$ = mergeClasses(`z-button z-button--icon z-button--${props.type}`, props.class), _v$2 = props.style, _v$3 = props.busy, _v$4 = props.label, _v$5 = props.label, _v$6 = props.onClick === "submit" ? "submit" : "button";
691
691
  _v$ !== _p$.e && className(_el$, _p$.e = _v$);
692
692
  _p$.t = style(_el$, _v$2, _p$.t);
693
693
  _v$3 !== _p$.a && setAttribute(_el$, "aria-busy", _p$.a = _v$3);
694
694
  _v$4 !== _p$.o && setAttribute(_el$, "aria-label", _p$.o = _v$4);
695
695
  _v$5 !== _p$.i && setAttribute(_el$, "title", _p$.i = _v$5);
696
+ _v$6 !== _p$.n && setAttribute(_el$, "type", _p$.n = _v$6);
696
697
  return _p$;
697
698
  }, {
698
699
  e: void 0,
699
700
  t: void 0,
700
701
  a: void 0,
701
702
  o: void 0,
702
- i: void 0
703
+ i: void 0,
704
+ n: void 0
703
705
  });
704
706
  return _el$;
705
707
  })();
@@ -1014,6 +1016,80 @@ function TextBox(props) {
1014
1016
  })();
1015
1017
  }
1016
1018
  delegateEvents(["input"]);
1019
+ function createForm(options) {
1020
+ const [fields, setFields] = createSignal(options.initiator());
1021
+ const errors = createMemo(() => options.validator(fields()));
1022
+ const invalid = createMemo(() => containsTruthy(errors()));
1023
+ const [state, setState] = createSignal({
1024
+ type: "HideErrors"
1025
+ });
1026
+ return {
1027
+ fields,
1028
+ errors: () => state().type === "ShowErrors" ? errors() : {},
1029
+ state,
1030
+ busy: () => state().type === "Submitting",
1031
+ update: (fields2) => {
1032
+ setFields((prevFields) => ({ ...prevFields, ...fields2 }));
1033
+ },
1034
+ reset: () => {
1035
+ setFields(() => options.initiator());
1036
+ },
1037
+ submit: () => {
1038
+ if (state().type === "Submitting") {
1039
+ return;
1040
+ }
1041
+ if (invalid()) {
1042
+ setState({ type: "ShowErrors" });
1043
+ return;
1044
+ }
1045
+ setState({ type: "Submitting" });
1046
+ options.submitter(fields()).then((value) => {
1047
+ var _a;
1048
+ setState({ type: "Success", value });
1049
+ (_a = options.onSuccess) == null ? void 0 : _a.call(options, value);
1050
+ }).catch((error) => {
1051
+ var _a;
1052
+ setState({ type: "Failure", error });
1053
+ (_a = options.onFailure) == null ? void 0 : _a.call(options, error);
1054
+ });
1055
+ }
1056
+ };
1057
+ }
1058
+ function containsTruthy(value) {
1059
+ if (!value) {
1060
+ return false;
1061
+ }
1062
+ if (typeof value === "object") {
1063
+ if (Array.isArray(value)) {
1064
+ return value.some(containsTruthy);
1065
+ } else {
1066
+ return Object.values(value).some(containsTruthy);
1067
+ }
1068
+ }
1069
+ return true;
1070
+ }
1071
+ function createInterval(fn, interval = 1e3) {
1072
+ const [value, setValue] = createSignal(fn());
1073
+ const id = setInterval(() => setValue(fn), interval);
1074
+ onCleanup(() => clearInterval(id));
1075
+ return value;
1076
+ }
1077
+ function createSize(element) {
1078
+ const [size, setSize] = createSignal({ width: 0, height: 0 });
1079
+ let observer;
1080
+ onMount(() => {
1081
+ const _element = element();
1082
+ observer = new ResizeObserver(() => {
1083
+ setSize({ width: _element.offsetWidth, height: _element.offsetHeight });
1084
+ });
1085
+ observer.observe(_element);
1086
+ });
1087
+ onCleanup(() => {
1088
+ observer == null ? void 0 : observer.disconnect();
1089
+ observer = void 0;
1090
+ });
1091
+ return size;
1092
+ }
1017
1093
  export {
1018
1094
  Button,
1019
1095
  Card,
@@ -1039,5 +1115,8 @@ export {
1039
1115
  Row,
1040
1116
  Select,
1041
1117
  Spinner,
1042
- TextBox
1118
+ TextBox,
1119
+ createForm,
1120
+ createInterval,
1121
+ createSize
1043
1122
  };
@@ -0,0 +1,38 @@
1
+ import { Accessor } from 'solid-js';
2
+
3
+ type Options<Fields, Errors, Success, Failure> = {
4
+ initiator: () => Fields;
5
+ validator: (fields: Fields) => Errors;
6
+ submitter: (fields: Fields) => Promise<Success>;
7
+ onSuccess?: (result: Success) => void;
8
+ onFailure?: (result: Failure) => void;
9
+ };
10
+ type Form<Fields, Errors, Success, Failure> = {
11
+ fields: Accessor<Fields>;
12
+ errors: Accessor<Partial<Errors>>;
13
+ state: Accessor<State<Success, Failure>>;
14
+ busy: Accessor<boolean>;
15
+ update: (fields: Partial<Fields>) => void;
16
+ reset: () => void;
17
+ submit: () => void;
18
+ };
19
+ export declare function createForm<Fields, Errors, Success, Failure>(options: Options<Fields, Errors, Success, Failure>): Form<Fields, Errors, Success, Failure>;
20
+ type State<Value, Error> = HideErrors | ShowErrors | Submitting | Success<Value> | Failure<Error>;
21
+ type HideErrors = {
22
+ type: "HideErrors";
23
+ };
24
+ type ShowErrors = {
25
+ type: "ShowErrors";
26
+ };
27
+ type Submitting = {
28
+ type: "Submitting";
29
+ };
30
+ type Success<Value> = {
31
+ type: "Success";
32
+ value: Value;
33
+ };
34
+ type Failure<Error> = {
35
+ type: "Failure";
36
+ error: Error;
37
+ };
38
+ export {};
@@ -0,0 +1,11 @@
1
+ import { Accessor } from 'solid-js';
2
+
3
+ /**
4
+ * Create a readonly signal that is recomputed at regular intervals
5
+ *
6
+ * ### Example
7
+ * ```ts
8
+ * const now = createInterval(() => Date.now());
9
+ * ```
10
+ */
11
+ export declare function createInterval<T>(fn: () => T, interval?: number): Accessor<T>;
@@ -0,0 +1,24 @@
1
+ import { Accessor } from 'solid-js';
2
+
3
+ type Size = {
4
+ width: number;
5
+ height: number;
6
+ };
7
+ /**
8
+ * Create a readonly signal for an element's size
9
+ *
10
+ * ### Example
11
+ * ```tsx
12
+ * export function Example() {
13
+ * let element!: HTMLDivElement;
14
+ * const size = createSize(() => element);
15
+ * return (
16
+ * <div ref={element}>
17
+ * Size: {JSON.stringify(size())}
18
+ * </div>
19
+ * );
20
+ * }
21
+ * ```
22
+ */
23
+ export declare function createSize(element: Accessor<HTMLElement>): Accessor<Size>;
24
+ export {};
package/dist/style.css CHANGED
@@ -651,7 +651,6 @@ dialog:focus-visible {
651
651
  --z-button-secondary-text: #e6e6e6;
652
652
  --z-button-tertiary-fill: transparent;
653
653
  --z-button-tertiary-text: #e6e6e6;
654
- --z-button-icon-fill: #2c2c35;
655
654
  --z-input-border: #79798a; /* Lc 30 */
656
655
  --z-input-active-border: #6068ff; /* Lc 30 */
657
656
  --z-input-active-fill: #7882ff; /* Lc 40 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lundal/zed-solid",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "license": "LGPL-3.0-or-later",
5
5
  "type": "module",
6
6
  "module": "dist/index.js",