@plitzi/sdk-elements 0.35.1 → 0.35.3

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 (28) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/dist/Element/hooks/useElementDataSource.mjs +18 -14
  3. package/dist/dataSource/GlobalSources.mjs +75 -61
  4. package/dist/elements/basic/Button/Button.d.ts +10 -1
  5. package/dist/elements/basic/Button/Button.mjs +7 -5
  6. package/dist/elements/basic/Button/declaration.d.ts +2 -0
  7. package/dist/elements/basic/Button/index.d.ts +2 -0
  8. package/dist/elements/declarations/index.d.ts +8 -0
  9. package/dist/elements/form/Form/Form.d.ts +9 -1
  10. package/dist/elements/form/Form/Form.mjs +79 -78
  11. package/dist/elements/form/Form/Settings.d.ts +2 -1
  12. package/dist/elements/form/Form/Settings.mjs +12 -6
  13. package/dist/elements/form/Form/declaration.d.ts +2 -0
  14. package/dist/elements/form/Form/declaration.mjs +1 -0
  15. package/dist/elements/form/Form/index.d.ts +2 -0
  16. package/dist/elements/form/FormControl/FormControl.d.ts +9 -1
  17. package/dist/elements/form/FormControl/FormControl.mjs +1 -0
  18. package/dist/elements/form/FormControl/Settings.d.ts +6 -2
  19. package/dist/elements/form/FormControl/Settings.mjs +106 -77
  20. package/dist/elements/form/FormControl/declaration.d.ts +4 -0
  21. package/dist/elements/form/FormControl/declaration.mjs +4 -0
  22. package/dist/elements/form/FormControl/helpers/validateField.d.ts +14 -0
  23. package/dist/elements/form/FormControl/helpers/validateField.mjs +13 -7
  24. package/dist/elements/form/FormControl/hocs/withFieldValue.d.ts +5 -1
  25. package/dist/elements/form/FormControl/hocs/withFieldValue.mjs +49 -39
  26. package/dist/elements/form/FormControl/index.d.ts +4 -0
  27. package/dist/index.d.ts +8 -0
  28. package/package.json +8 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # @plitzi/sdk-elements
2
2
 
3
+ ## 0.35.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 0211dc4: A form speaks the site's language when it refuses a value.
8
+
9
+ - **Every rule of a `formControl` can say what it wants to say.** `requiredMessage`, `minLengthMessage`,
10
+ `maxLengthMessage` and `formatMessage` join `patternMessage` and `matchesMessage`; left empty, each falls back to
11
+ the English sentence it said before. `formatMessage` is said when the value does not have the shape the control's
12
+ type asks for — an address, for an `email` — one attribute for every type that has a shape. Offered in the builder under the rule they belong to.
13
+ - **A `form` can turn the browser's own checks off (`noValidate`, "Skip Browser Validation" in the builder).** Left on
14
+ — the default, as before — the browser answers first for a blank required field and a malformed address, in a
15
+ bubble no style reaches and in the browser's language, while every other rule answers under the control. Turned
16
+ on, the form's rules are the only ones, and all of them answer under the control.
17
+ - **An `email` control checks the address itself,** by the same definition the browser uses, so the format is still
18
+ asked for when the browser's checks are off.
19
+
20
+ - Updated dependencies [0211dc4]
21
+ - @plitzi/sdk-auth@0.35.3
22
+ - @plitzi/sdk-dev-tools@0.35.3
23
+ - @plitzi/sdk-event-bridge@0.35.3
24
+ - @plitzi/sdk-interactions@0.35.3
25
+ - @plitzi/sdk-navigation@0.35.3
26
+ - @plitzi/sdk-schema@0.35.3
27
+ - @plitzi/sdk-shared@0.35.3
28
+
29
+ ## 0.35.2
30
+
31
+ ### Minor Changes
32
+
33
+ - 470aaf8: A booking form can ask for a date, and a toggle can say it is one.
34
+
35
+ - **`formControl` accepts `subType: 'date'`.** It renders the browser's own date picker and submits `YYYY-MM-DD`, so
36
+ a flow or a server action reads one format whatever the visitor's locale. Until now a date was a free text field
37
+ and every form that needed one parsed whatever somebody typed. Offered in the builder's Input Type list.
38
+ - **`button` accepts `ariaExpanded` and `ariaPressed`.** A button that opens a menu or an answer, or one that stays on
39
+ like a filter, can tell assistive technology so — statically, or bound to the state it flips
40
+ (`bind: { ariaExpanded: 'state.menuOpen' }`). Left out, neither attribute is rendered: an ordinary button does not
41
+ claim to control anything.
42
+
43
+ - 470aaf8: The theme is a data source, and a binding reads every source its template names.
44
+
45
+ - **`theme` global source.** `GlobalSources` publishes `runtime.sources.theme` as `{ mode, resolved }` for the area
46
+ the space paints in. `resolved` is always `light` or `dark`, so `{{ theme.resolved }}` is what a URL or a `when`
47
+ rule wants — a dashboard asking the API for a thumbnail in the visitor's scheme, for one. The comments that promised
48
+ `{{ theme.resolved }}` through the app store's `theme` mirror were wrong: nothing a binding reads lives there.
49
+ - **A binding subscribes to the roots of its `twigTemplate`.** It used to get only the head of its `source`, so a
50
+ binding on `list_spaces.item.id` whose template also said `{{ theme.resolved }}` or `{{ state.scope }}` resolved the
51
+ second name to nothing, silently. The names are read off the parsed template (`templateRootNames`, exported from
52
+ `@plitzi/sdk-shared/helpers/twigWrapper`). A name that is not a source is left out of the map rather than set to
53
+ `undefined`, so `{{ source }}` and the variables lifted to the template's root are never shadowed.
54
+ - **Authoring.** `theme` joins `GLOBAL_SOURCES`: `bind: { src: 'theme.resolved' }` is accepted, and an element can no
55
+ longer be named `theme`.
56
+
57
+ ### Patch Changes
58
+
59
+ - v0.35.2
60
+ - Updated dependencies
61
+ - Updated dependencies [470aaf8]
62
+ - @plitzi/sdk-auth@0.35.2
63
+ - @plitzi/sdk-dev-tools@0.35.2
64
+ - @plitzi/sdk-event-bridge@0.35.2
65
+ - @plitzi/sdk-interactions@0.35.2
66
+ - @plitzi/sdk-navigation@0.35.2
67
+ - @plitzi/sdk-schema@0.35.2
68
+ - @plitzi/sdk-shared@0.35.2
69
+
3
70
  ## 0.35.1
4
71
 
5
72
  ### Patch Changes
@@ -1,23 +1,27 @@
1
1
  import { useMemo as e } from "react";
2
2
  import { useCommonStore as t } from "@plitzi/sdk-shared/store";
3
+ import { templateRootNames as n } from "@plitzi/sdk-shared/helpers/twigWrapper";
3
4
  //#region src/Element/hooks/useElementDataSource.ts
4
- var n = ({ bindings: n, sources: r }) => {
5
- let i = e(() => {
6
- let e = new Set(r ?? []);
7
- for (let t of Object.values(n ?? {})) if (Array.isArray(t)) {
8
- for (let { source: n } of t) if (n) {
9
- let t = n.indexOf(".");
10
- e.add(t > -1 ? n.substring(0, t) : n);
11
- }
12
- }
5
+ var r = ({ source: e, transformers: t }) => {
6
+ let r = [];
7
+ if (e) {
8
+ let t = e.indexOf(".");
9
+ r.push(t > -1 ? e.substring(0, t) : e);
10
+ }
11
+ for (let { action: e, params: i } of t ?? []) e === "twigTemplate" && i.template && r.push(...n(i.template));
12
+ return r;
13
+ }, i = ({ bindings: n, sources: i }) => {
14
+ let a = e(() => {
15
+ let e = new Set(i ?? []);
16
+ for (let t of Object.values(n ?? {})) if (Array.isArray(t)) for (let n of t) for (let t of r(n)) e.add(t);
13
17
  return e.size > 0 && !e.has("variables") && e.add("variables"), [...e];
14
- }, [n, r]), a = e(() => i.map((e) => `runtime.sources.${e}`), [i]), [o] = t(a);
18
+ }, [n, i]), o = e(() => a.map((e) => `runtime.sources.${e}`), [a]), [s] = t(o);
15
19
  return e(() => {
16
20
  let e = {};
17
- return i.forEach((t, n) => {
18
- e[t] = o[n];
21
+ return a.forEach((t, n) => {
22
+ s[n] !== void 0 && (e[t] = s[n]);
19
23
  }), e;
20
- }, [i, o]);
24
+ }, [a, s]);
21
25
  };
22
26
  //#endregion
23
- export { n as default };
27
+ export { i as default };
@@ -2,67 +2,68 @@ import { use as e, useCallback as t, useMemo as n } from "react";
2
2
  import { useCommonStore as r, useCommonStoreSync as i, useRenderSettings as a } from "@plitzi/sdk-shared/store";
3
3
  import { get as o } from "@plitzi/plitzi-ui/helpers";
4
4
  import { getPathsFromObeject as s } from "@plitzi/sdk-shared/helpers/utils";
5
- import c from "@plitzi/sdk-shared/dataSource/hooks/useRegisterSource";
6
- import l from "@plitzi/sdk-auth/AuthContext";
7
- import { resolveVariables as u } from "@plitzi/sdk-shared/dataSource";
5
+ import c, { SPACE_THEME_AREA as l } from "@plitzi/sdk-shared/theme/useTheme";
6
+ import u from "@plitzi/sdk-shared/dataSource/hooks/useRegisterSource";
7
+ import d from "@plitzi/sdk-auth/AuthContext";
8
+ import { resolveVariables as f } from "@plitzi/sdk-shared/dataSource";
8
9
  //#region src/dataSource/GlobalSources.tsx
9
- var d = ({ children: d }) => {
10
- let { environment: f } = a(), [[p, m, h, g, _, v]] = r([
10
+ var p = ({ children: p }) => {
11
+ let { environment: m } = a(), [[h, g, _, v, y, b]] = r([
11
12
  "schema.variables",
12
13
  "navigation.routeParams",
13
14
  "navigation.queryParams",
14
15
  "navigation.hostname",
15
16
  "navigation.origin",
16
17
  "navigation.currentPageId"
17
- ]), y = n(() => u(p, {
18
- routeParams: m,
19
- queryParams: h,
20
- hostname: g,
21
- environment: f
18
+ ]), x = n(() => f(h, {
19
+ routeParams: g,
20
+ queryParams: _,
21
+ hostname: v,
22
+ environment: m
22
23
  }), [
23
- f,
24
- g,
25
- h,
26
24
  m,
27
- p
28
- ]), b = t(() => s(y).map((e) => ({
25
+ v,
26
+ _,
27
+ g,
28
+ h
29
+ ]), S = t(() => s(x).map((e) => ({
29
30
  path: e,
30
31
  name: `variables.${e}`
31
- })), [y]);
32
- c({
32
+ })), [x]);
33
+ u({
33
34
  id: "global",
34
35
  source: "variables",
35
36
  name: "Variables",
36
- fields: b
37
- }), i("runtime.sources.variables", y);
38
- let [x = {}] = r("pageDefinitions"), S = n(() => Object.values(x).map((e) => ({
37
+ fields: S
38
+ }), i("runtime.sources.variables", x);
39
+ let [C = {}] = r("pageDefinitions"), w = n(() => Object.values(C).map((e) => ({
39
40
  value: e.id,
40
41
  label: o(e, "attributes.name", e.id)
41
- })), [x]), C = n(() => ({
42
- routeParams: m,
43
- queryParams: h,
44
- origin: _,
45
- currentPageId: v
42
+ })), [C]), T = n(() => ({
43
+ routeParams: g,
44
+ queryParams: _,
45
+ origin: y,
46
+ currentPageId: b
46
47
  }), [
47
- m,
48
- h,
48
+ g,
49
49
  _,
50
- v
51
- ]), w = t(() => {
50
+ y,
51
+ b
52
+ ]), E = t(() => {
52
53
  let e = s({
53
- routeParams: m,
54
- queryParams: h
54
+ routeParams: g,
55
+ queryParams: _
55
56
  }).map((e) => ({
56
57
  path: e,
57
58
  name: `navigation.${e}`
58
59
  })), t = {
59
60
  path: "origin",
60
61
  name: "Origin"
61
- }, n = S.length > 0 ? {
62
+ }, n = w.length > 0 ? {
62
63
  path: "currentPageId",
63
64
  name: "Current Page",
64
65
  inputType: "select",
65
- values: S
66
+ values: w
66
67
  } : {
67
68
  path: "currentPageId",
68
69
  name: "Current Page"
@@ -73,61 +74,74 @@ var d = ({ children: d }) => {
73
74
  n
74
75
  ];
75
76
  }, [
76
- m,
77
- h,
78
- S
77
+ g,
78
+ _,
79
+ w
79
80
  ]);
80
- c({
81
+ u({
81
82
  id: "global",
82
83
  source: "navigation",
83
84
  name: "Navigation",
84
- fields: w
85
- }), i("runtime.sources.navigation", C);
86
- let { user: T, authenticated: E } = e(l), [D = "basic"] = r("schema.settings.userProvider"), O = n(() => D === "" ? {} : {
87
- isAuthenticated: E,
88
- accessToken: T?.accessToken ?? "",
85
+ fields: E
86
+ }), i("runtime.sources.navigation", T);
87
+ let { user: D, authenticated: O } = e(d), [k = "basic"] = r("schema.settings.userProvider"), A = n(() => k === "" ? {} : {
88
+ isAuthenticated: O,
89
+ accessToken: D?.accessToken ?? "",
89
90
  details: {
90
91
  username: "",
91
92
  email: "",
92
93
  roles: "",
93
94
  permissions: "",
94
95
  verified: "",
95
- ...T?.details ?? {}
96
+ ...D?.details ?? {}
96
97
  }
97
98
  }, [
99
+ k,
98
100
  D,
99
- T,
100
- E
101
- ]), k = t(() => s(O).map((e) => ({
101
+ O
102
+ ]), j = t(() => s(A).map((e) => ({
102
103
  path: e,
103
104
  name: `user.${e}`
104
- })), [O]);
105
- c({
105
+ })), [A]);
106
+ u({
106
107
  id: "global",
107
108
  source: "auth",
108
109
  name: "Auth State",
109
- fields: k
110
- }), i("runtime.sources.auth", O);
111
- let [A] = r("runtime.state"), j = t(() => s(A).map((e) => ({
110
+ fields: j
111
+ }), i("runtime.sources.auth", A);
112
+ let [M] = r("runtime.state"), N = t(() => s(M).map((e) => ({
112
113
  path: e,
113
114
  name: `state.${e}`
114
- })), [A]);
115
- c({
115
+ })), [M]);
116
+ u({
116
117
  id: "global",
117
118
  source: "state",
118
119
  name: "State",
119
- fields: j
120
- }), i("runtime.sources.state", A);
121
- let [M] = r("runtime.host"), N = t(() => s(M).map((e) => ({
120
+ fields: N
121
+ }), i("runtime.sources.state", M);
122
+ let [P] = r("runtime.host"), F = t(() => s(P).map((e) => ({
122
123
  path: e,
123
124
  name: `host.${e}`
124
- })), [M]);
125
- return c({
125
+ })), [P]);
126
+ u({
126
127
  id: "global",
127
128
  source: "host",
128
129
  name: "Host",
129
- fields: N
130
- }), i("runtime.sources.host", M), d;
130
+ fields: F
131
+ }), i("runtime.sources.host", P);
132
+ let { theme: I, resolvedTheme: L } = c(l), R = n(() => ({
133
+ mode: I,
134
+ resolved: L
135
+ }), [I, L]), z = t(() => s(R).map((e) => ({
136
+ path: e,
137
+ name: `theme.${e}`
138
+ })), [R]);
139
+ return u({
140
+ id: "global",
141
+ source: "theme",
142
+ name: "Theme",
143
+ fields: z
144
+ }), i("runtime.sources.theme", R), p;
131
145
  };
132
146
  //#endregion
133
- export { d as default };
147
+ export { p as default };
@@ -7,8 +7,17 @@ export type ButtonProps = {
7
7
  content?: string;
8
8
  subType?: 'button' | 'submit' | 'reset';
9
9
  disabled?: boolean;
10
+ /**
11
+ * For a button that shows and hides something — a menu, an answer, a panel: `true` while that is open.
12
+ *
13
+ * Left out, the button claims to control nothing, which is not the same as `false` ("it controls something, and it
14
+ * is closed"). A screen reader announces the difference, so an ordinary button must not get a default here.
15
+ */
16
+ ariaExpanded?: boolean;
17
+ /** For a button that stays on or off — a filter, a mode: `true` while it is on. Left out, it is a plain button. */
18
+ ariaPressed?: boolean;
10
19
  };
11
- declare const Button: ({ ref, className, children, contentPlacement, content, subType, disabled }: ButtonProps) => import("react").JSX.Element;
20
+ declare const Button: ({ ref, className, children, contentPlacement, content, subType, disabled, ariaExpanded, ariaPressed }: ButtonProps) => import("react").JSX.Element;
12
21
  declare const _default: {
13
22
  (props: import('../../../Element/hocs/withElement').WithElementProps<ButtonProps>): import("react").JSX.Element;
14
23
  displayName: string;
@@ -6,15 +6,17 @@ import i from "@plitzi/sdk-shared/hooks/usePlitziServiceContext";
6
6
  import { jsxs as a } from "react/jsx-runtime";
7
7
  import o from "clsx";
8
8
  //#region src/elements/basic/Button/Button.tsx
9
- var s = ({ ref: e, className: s = "", children: c, contentPlacement: l = "after", content: u = "Button", subType: d = "button", disabled: f = !1 }) => {
10
- let { definition: { label: p } } = t(), { settings: { previewMode: m } } = i(), h = r(() => typeof u == "string" ? u : p, [u, p]);
9
+ var s = ({ ref: e, className: s = "", children: c, contentPlacement: l = "after", content: u = "Button", subType: d = "button", disabled: f = !1, ariaExpanded: p, ariaPressed: m }) => {
10
+ let { definition: { label: h } } = t(), { settings: { previewMode: g } } = i(), _ = r(() => typeof u == "string" ? u : h, [u, h]);
11
11
  return /* @__PURE__ */ a(n, {
12
12
  ref: e,
13
13
  tag: "button",
14
- type: m ? d : "button",
15
- className: o("plitzi-component__button", s, { "container--empty--skip": !m && !c && u }),
14
+ type: g ? d : "button",
15
+ className: o("plitzi-component__button", s, { "container--empty--skip": !g && !c && u }),
16
16
  disabled: f,
17
- "aria-label": h,
17
+ "aria-label": _,
18
+ "aria-expanded": p,
19
+ "aria-pressed": m,
18
20
  children: [
19
21
  l === "before" && u,
20
22
  c,
@@ -123,5 +123,7 @@ declare const declaration: {
123
123
  disabled?: boolean | undefined;
124
124
  subType?: "button" | "submit" | "reset" | undefined;
125
125
  contentPlacement?: "before" | "after" | undefined;
126
+ ariaExpanded?: boolean | undefined;
127
+ ariaPressed?: boolean | undefined;
126
128
  }>>;
127
129
  export default declaration;
@@ -122,5 +122,7 @@ declare const Button: {
122
122
  disabled?: boolean | undefined;
123
123
  subType?: "button" | "submit" | "reset" | undefined;
124
124
  contentPlacement?: "before" | "after" | undefined;
125
+ ariaExpanded?: boolean | undefined;
126
+ ariaPressed?: boolean | undefined;
125
127
  }>>;
126
128
  export default Button;
@@ -320,6 +320,8 @@ export declare const elementDeclarations: {
320
320
  disabled?: boolean | undefined;
321
321
  subType?: "button" | "submit" | "reset" | undefined;
322
322
  contentPlacement?: "before" | "after" | undefined;
323
+ ariaExpanded?: boolean | undefined;
324
+ ariaPressed?: boolean | undefined;
323
325
  }>>;
324
326
  readonly Container: {
325
327
  readonly type: "container";
@@ -789,6 +791,7 @@ export declare const elementDeclarations: {
789
791
  readonly method: "get";
790
792
  readonly actionUrl: "";
791
793
  readonly managedByInteractions: false;
794
+ readonly noValidate: false;
792
795
  readonly errors: {};
793
796
  readonly values: {};
794
797
  };
@@ -836,6 +839,7 @@ export declare const elementDeclarations: {
836
839
  } & import('@plitzi/sdk-shared/authoring/declare').ElementAttributesBrand<Partial<{
837
840
  values: Record<string, unknown>;
838
841
  method: "get" | "post";
842
+ noValidate: boolean;
839
843
  actionUrl: string;
840
844
  managedByInteractions: boolean;
841
845
  errors: Record<string, string>;
@@ -853,8 +857,12 @@ export declare const elementDeclarations: {
853
857
  readonly disabled: false;
854
858
  readonly options: readonly [];
855
859
  readonly required: true;
860
+ readonly requiredMessage: "";
856
861
  readonly minLength: 0;
862
+ readonly minLengthMessage: "";
857
863
  readonly maxLength: 0;
864
+ readonly maxLengthMessage: "";
865
+ readonly formatMessage: "";
858
866
  readonly pattern: "";
859
867
  readonly patternMessage: "";
860
868
  readonly matches: "";
@@ -7,6 +7,14 @@ export type FormProps = {
7
7
  method: 'get' | 'post';
8
8
  actionUrl: string;
9
9
  managedByInteractions: boolean;
10
+ /**
11
+ * Turns the browser's own checks off, leaving the controls' rules as the whole of the validation.
12
+ *
13
+ * Left on, the browser answers first for the two rules it knows (a blank required field, a malformed address) in a
14
+ * bubble no style reaches and in the BROWSER's language, while every other rule answers under the control. On, every
15
+ * rule answers under the control in the words its `…Message` gives — `validateField` asks for both of those itself.
16
+ */
17
+ noValidate: boolean;
10
18
  errors: Record<string, string>;
11
19
  values: Record<string, unknown>;
12
20
  };
@@ -27,7 +35,7 @@ export type FormContextValue = {
27
35
  setFieldValue: (name: string, value: FieldValue | null) => void;
28
36
  setFieldError: (name: string, error: string) => void;
29
37
  };
30
- declare const Form: ({ ref, className, children, method, actionUrl, managedByInteractions, errors, values }: FormProps) => import("react").JSX.Element;
38
+ declare const Form: ({ ref, className, children, method, actionUrl, managedByInteractions, noValidate, errors, values }: FormProps) => import("react").JSX.Element;
31
39
  declare const _default: {
32
40
  (props: import('../../../Element/hocs/withElement').WithElementProps<FormProps>): import("react").JSX.Element;
33
41
  displayName: string;