foldkit 0.46.1 → 0.47.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"propsModule.d.ts","sourceRoot":"","sources":["../src/propsModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AA0DtC,eAAO,MAAM,WAAW,EAAE,MAAqD,CAAA"}
1
+ {"version":3,"file":"propsModule.d.ts","sourceRoot":"","sources":["../src/propsModule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAyDtC,eAAO,MAAM,WAAW,EAAE,MAAqD,CAAA"}
@@ -7,33 +7,34 @@
7
7
  * Since a disabled button swallows click events at the browser level, an
8
8
  * `OnClick` handler that replaces `Disabled` at the same index silently fails.
9
9
  *
10
- * Instead of relying on the old vnode's `data.props` for cleanup (which
11
- * requires snabbdom to patch rather than recreate), this module tracks which
12
- * properties it has set on each DOM element via a WeakMap. On every create or
13
- * update hook, it compares the tracked set against the new vnode's props and
14
- * resets anything that was removed to its type-appropriate default: booleans →
15
- * false, strings → '', numbers → 0. The WeakMap entries are garbage-collected
16
- * when the element is removed from the DOM. */
17
- const managedProps = new WeakMap();
18
- function updateProps(_oldVnode, vnode) {
10
+ * This module adds a second loop (mirroring what snabbdom's attributesModule
11
+ * already does) that resets removed props to type-appropriate defaults:
12
+ * booleans false, strings '', numbers 0. */
13
+ function updateProps(oldVnode, vnode) {
19
14
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
20
15
  const elm = vnode.elm;
21
16
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
22
- const props = (vnode.data?.props ?? {});
23
- const previous = managedProps.get(elm) ?? {};
24
- if (props === previous) {
17
+ let oldProps = oldVnode.data?.props;
18
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
19
+ let props = vnode.data?.props;
20
+ if (!oldProps && !props) {
21
+ return;
22
+ }
23
+ if (oldProps === props) {
25
24
  return;
26
25
  }
26
+ oldProps = oldProps ?? {};
27
+ props = props ?? {};
27
28
  for (const key in props) {
28
29
  const cur = props[key];
29
- const old = previous[key];
30
+ const old = oldProps[key];
30
31
  if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
31
32
  elm[key] = cur;
32
33
  }
33
34
  }
34
- for (const key in previous) {
35
+ for (const key in oldProps) {
35
36
  if (!(key in props)) {
36
- const old = previous[key];
37
+ const old = oldProps[key];
37
38
  if (typeof old === 'boolean') {
38
39
  elm[key] = false;
39
40
  }
@@ -45,6 +46,5 @@ function updateProps(_oldVnode, vnode) {
45
46
  }
46
47
  }
47
48
  }
48
- managedProps.set(elm, { ...props });
49
49
  }
50
50
  export const propsModule = { create: updateProps, update: updateProps };
@@ -0,0 +1,31 @@
1
+ import { Schema as S } from 'effect';
2
+ import * as Command from '../../command';
3
+ import { type Html } from '../../html';
4
+ export declare const Model: S.Struct<{
5
+ isEnabled: typeof S.Boolean;
6
+ dialog: S.Struct<{
7
+ id: typeof S.String;
8
+ isOpen: typeof S.Boolean;
9
+ isAnimated: typeof S.Boolean;
10
+ transitionState: S.Literal<["Idle", "EnterStart", "EnterAnimating", "LeaveStart", "LeaveAnimating"]>;
11
+ maybeFocusSelector: S.OptionFromSelf<typeof S.String>;
12
+ }>;
13
+ }>;
14
+ export type Model = typeof Model.Type;
15
+ export declare const ClickedToggle: import("../../schema").CallableTaggedStruct<"ClickedToggle", {}>;
16
+ export declare const ClickedSubmit: import("../../schema").CallableTaggedStruct<"ClickedSubmit", {}>;
17
+ export declare const GotDialogMessage: import("../../schema").CallableTaggedStruct<"GotDialogMessage", {
18
+ message: S.Union<[import("../../schema").CallableTaggedStruct<"Opened", {}>, import("../../schema").CallableTaggedStruct<"Closed", {}>, import("../../schema").CallableTaggedStruct<"CompletedShowDialog", {}>, import("../../schema").CallableTaggedStruct<"CompletedCloseDialog", {}>, import("../../schema").CallableTaggedStruct<"AdvancedTransitionFrame", {}>, import("../../schema").CallableTaggedStruct<"EndedTransition", {}>]>;
19
+ }>;
20
+ export declare const Message: S.Union<[import("../../schema").CallableTaggedStruct<"ClickedToggle", {}>, import("../../schema").CallableTaggedStruct<"ClickedSubmit", {}>, import("../../schema").CallableTaggedStruct<"GotDialogMessage", {
21
+ message: S.Union<[import("../../schema").CallableTaggedStruct<"Opened", {}>, import("../../schema").CallableTaggedStruct<"Closed", {}>, import("../../schema").CallableTaggedStruct<"CompletedShowDialog", {}>, import("../../schema").CallableTaggedStruct<"CompletedCloseDialog", {}>, import("../../schema").CallableTaggedStruct<"AdvancedTransitionFrame", {}>, import("../../schema").CallableTaggedStruct<"EndedTransition", {}>]>;
22
+ }>]>;
23
+ export type Message = typeof Message.Type;
24
+ export declare const initialModel: Model;
25
+ export declare const update: (model: Model, message: Message) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
26
+ /** Plain view — no dialog wrapper. */
27
+ export declare const view: (model: Model) => Html;
28
+ /** View with submit button inside a dialog's panelContent. */
29
+ export declare const viewWithDialog: (model: Model) => Html;
30
+ export declare const viewWithLazyDialog: (model: Model) => Html;
31
+ //# sourceMappingURL=disabledButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disabledButton.d.ts","sourceRoot":"","sources":["../../../src/test/apps/disabledButton.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,MAAM,IAAI,CAAC,EAAE,MAAM,QAAQ,CAAA;AAExD,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,KAAK,IAAI,EAAQ,MAAM,YAAY,CAAA;AAM5C,eAAO,MAAM,KAAK;;;;;;;;;EAGhB,CAAA;AACF,MAAM,MAAM,KAAK,GAAG,OAAO,KAAK,CAAC,IAAI,CAAA;AAIrC,eAAO,MAAM,aAAa,kEAAqB,CAAA;AAC/C,eAAO,MAAM,aAAa,kEAAqB,CAAA;AAC/C,eAAO,MAAM,gBAAgB;;EAE3B,CAAA;AAEF,eAAO,MAAM,OAAO;;IAA0D,CAAA;AAC9E,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,IAAI,CAAA;AAIzC,eAAO,MAAM,YAAY,EAAE,KAG1B,CAAA;AAID,eAAO,MAAM,MAAM,GACjB,OAAO,KAAK,EACZ,SAAS,OAAO,KACf,SAAS,CAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAyBxD,CAAA;AAeH,sCAAsC;AACtC,eAAO,MAAM,IAAI,GAAI,OAAO,KAAK,KAAG,IAOjC,CAAA;AAEH,8DAA8D;AAC9D,eAAO,MAAM,cAAc,GAAI,OAAO,KAAK,KAAG,IAY3C,CAAA;AAKH,eAAO,MAAM,kBAAkB,GAAI,OAAO,KAAK,KAAG,IAY/C,CAAA"}
@@ -0,0 +1,60 @@
1
+ import { Effect, Match as M, Schema as S } from 'effect';
2
+ import * as Command from '../../command';
3
+ import { html } from '../../html';
4
+ import { m } from '../../message';
5
+ import * as Dialog from '../../ui/dialog';
6
+ // MODEL
7
+ export const Model = S.Struct({
8
+ isEnabled: S.Boolean,
9
+ dialog: Dialog.Model,
10
+ });
11
+ // MESSAGE
12
+ export const ClickedToggle = m('ClickedToggle');
13
+ export const ClickedSubmit = m('ClickedSubmit');
14
+ export const GotDialogMessage = m('GotDialogMessage', {
15
+ message: Dialog.Message,
16
+ });
17
+ export const Message = S.Union(ClickedToggle, ClickedSubmit, GotDialogMessage);
18
+ // INIT
19
+ export const initialModel = {
20
+ isEnabled: false,
21
+ dialog: Dialog.init({ id: 'test-dialog', isOpen: true }),
22
+ };
23
+ // UPDATE
24
+ export const update = (model, message) => M.value(message).pipe(M.withReturnType(), M.tagsExhaustive({
25
+ ClickedToggle: () => [{ ...model, isEnabled: !model.isEnabled }, []],
26
+ ClickedSubmit: () => [model, []],
27
+ GotDialogMessage: ({ message: dialogMessage }) => {
28
+ const [nextDialog, commands] = Dialog.update(model.dialog, dialogMessage);
29
+ return [
30
+ { ...model, dialog: nextDialog },
31
+ commands.map(Command.mapEffect(Effect.map(dialogMessage => GotDialogMessage({ message: dialogMessage })))),
32
+ ];
33
+ },
34
+ }));
35
+ // VIEW
36
+ const { div, button, Class, Disabled, OnClick } = html();
37
+ const submitButton = (isEnabled) => button([
38
+ Class('submit'),
39
+ ...(isEnabled ? [OnClick(ClickedSubmit())] : [Disabled(true)]),
40
+ ], ['Submit']);
41
+ /** Plain view — no dialog wrapper. */
42
+ export const view = (model) => div([], [
43
+ button([OnClick(ClickedToggle())], ['Toggle']),
44
+ submitButton(model.isEnabled),
45
+ ]);
46
+ /** View with submit button inside a dialog's panelContent. */
47
+ export const viewWithDialog = (model) => div([], [
48
+ button([OnClick(ClickedToggle())], ['Toggle']),
49
+ Dialog.view({
50
+ model: model.dialog,
51
+ toParentMessage: (dialogMessage) => GotDialogMessage({ message: dialogMessage }),
52
+ panelContent: submitButton(model.isEnabled),
53
+ }),
54
+ ]);
55
+ /** View using Dialog.lazy with panelContent passed dynamically. */
56
+ const lazyDialogView = Dialog.lazy({});
57
+ export const viewWithLazyDialog = (model) => div([], [
58
+ button([OnClick(ClickedToggle())], ['Toggle']),
59
+ lazyDialogView(model.dialog, (dialogMessage) => GotDialogMessage({ message: dialogMessage }), submitButton(model.isEnabled)),
60
+ ]);
@@ -86,8 +86,11 @@ export type ViewConfig<Message> = Readonly<{
86
86
  export declare const close: (model: Model) => readonly [Model, ReadonlyArray<Command.Command<Message>>];
87
87
  /** Renders a headless dialog component backed by the native `<dialog>` element with `showModal()`. */
88
88
  export declare const view: <Message>(config: ViewConfig<Message>) => Html;
89
- /** Creates a memoized dialog view. Static config is captured in a closure;
90
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
91
- export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toParentMessage" | "onClosed">) => ((model: Model, toParentMessage: ViewConfig<Message>["toParentMessage"]) => Html);
89
+ /** Creates a memoized dialog view. Static config (className, panelClassName,
90
+ * etc.) is captured in a closure. Dynamic fields `model`, `toParentMessage`,
91
+ * and `panelContent` are compared by reference per render via `createLazy`.
92
+ * When any of them change, the view re-renders; otherwise the cached VNode is
93
+ * reused and snabbdom skips the entire subtree. */
94
+ export declare const lazy: <Message>(staticConfig: Omit<ViewConfig<Message>, "model" | "toParentMessage" | "onClosed" | "panelContent">) => ((model: Model, toParentMessage: ViewConfig<Message>["toParentMessage"], panelContent: Html) => Html);
92
95
  export {};
93
96
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/dialog/index.ts"],"names":[],"mappings":"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"}
@@ -174,13 +174,17 @@ export const view = (config) => {
174
174
  const content = isVisible ? [backdrop, panel] : [];
175
175
  return keyed('dialog')(id, dialogAttributes, content);
176
176
  };
177
- /** Creates a memoized dialog view. Static config is captured in a closure;
178
- * only `model` and `toParentMessage` are compared per render via `createLazy`. */
177
+ /** Creates a memoized dialog view. Static config (className, panelClassName,
178
+ * etc.) is captured in a closure. Dynamic fields `model`, `toParentMessage`,
179
+ * and `panelContent` — are compared by reference per render via `createLazy`.
180
+ * When any of them change, the view re-renders; otherwise the cached VNode is
181
+ * reused and snabbdom skips the entire subtree. */
179
182
  export const lazy = (staticConfig) => {
180
183
  const lazyView = createLazy();
181
- return (model, toParentMessage) => lazyView((currentModel, currentToMessage) => view({
184
+ return (model, toParentMessage, panelContent) => lazyView((currentModel, currentToMessage, currentPanelContent) => view({
182
185
  ...staticConfig,
183
186
  model: currentModel,
184
187
  toParentMessage: currentToMessage,
185
- }), [model, toParentMessage]);
188
+ panelContent: currentPanelContent,
189
+ }), [model, toParentMessage, panelContent]);
186
190
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foldkit",
3
- "version": "0.46.1",
3
+ "version": "0.47.1",
4
4
  "description": "A frontend framework for TypeScript, built on Effect, using The Elm Architecture",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",