foldkit 0.46.0 → 0.47.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.
@@ -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
  };
@@ -1 +1 @@
1
- {"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,OAAO,EACR,MAAM,UAAU,CAAA;AAIjB,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,CAAA;AAElB,eAAO,MAAM,KAAK,gIAOhB,CAAA"}
1
+ {"version":3,"file":"vdom.d.ts","sourceRoot":"","sources":["../src/vdom.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,OAAO,EACR,MAAM,UAAU,CAAA;AAEjB,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,CAAA;AAElB,eAAO,MAAM,KAAK,gIAOhB,CAAA"}
package/dist/vdom.js CHANGED
@@ -1,5 +1,4 @@
1
- import { attributesModule, classModule, datasetModule, eventListenersModule, init, styleModule, toVNode, } from 'snabbdom';
2
- import { propsModule } from './propsModule';
1
+ import { attributesModule, classModule, datasetModule, eventListenersModule, init, propsModule, styleModule, toVNode, } from 'snabbdom';
3
2
  export { toVNode };
4
3
  export const patch = init([
5
4
  attributesModule,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foldkit",
3
- "version": "0.46.0",
3
+ "version": "0.47.0",
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",
@@ -1,3 +0,0 @@
1
- import type { Module } from 'snabbdom';
2
- export declare const propsModule: Module;
3
- //# sourceMappingURL=propsModule.d.ts.map
@@ -1 +0,0 @@
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"}
@@ -1,50 +0,0 @@
1
- /** A custom props module that extends snabbdom's built-in propsModule with
2
- * proper cleanup of removed properties.
3
- *
4
- * Snabbdom's propsModule only iterates over _new_ props — it never resets
5
- * old props that disappeared between renders. This means `elm.disabled = true`
6
- * persists even after `Disabled(true)` is removed from the attribute array.
7
- * Since a disabled button swallows click events at the browser level, an
8
- * `OnClick` handler that replaces `Disabled` at the same index silently fails.
9
- *
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) {
14
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
15
- const elm = vnode.elm;
16
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
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) {
24
- return;
25
- }
26
- oldProps = oldProps ?? {};
27
- props = props ?? {};
28
- for (const key in props) {
29
- const cur = props[key];
30
- const old = oldProps[key];
31
- if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
32
- elm[key] = cur;
33
- }
34
- }
35
- for (const key in oldProps) {
36
- if (!(key in props)) {
37
- const old = oldProps[key];
38
- if (typeof old === 'boolean') {
39
- elm[key] = false;
40
- }
41
- else if (typeof old === 'string') {
42
- elm[key] = '';
43
- }
44
- else if (typeof old === 'number') {
45
- elm[key] = 0;
46
- }
47
- }
48
- }
49
- }
50
- export const propsModule = { create: updateProps, update: updateProps };