@appcorp/fusion-storybook 0.1.101 → 0.2.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.
@@ -14,7 +14,7 @@
14
14
  */
15
15
  "use client";
16
16
  import { jsx as _jsx } from "react/jsx-runtime";
17
- import { useMemo } from "react";
17
+ import { useMemo, useCallback } from "react";
18
18
  import { COMPONENT_TYPE } from "@appcorp/shadcn/components/enhanced-table";
19
19
  import { createGenericModulePage, } from "@react-pakistan/util-functions/factory/generic-component-factory";
20
20
  import { useAdmissionModule, AdmissionProvider, ADMISSION_DRAWER, ADMISSION_ACTION_TYPES, } from "./context";
@@ -46,13 +46,15 @@ const tableBodyCols = [
46
46
  // ============================================================================
47
47
  // COMPONENT FACTORY (creates JSX elements when config is created, not during render)
48
48
  // ============================================================================
49
- const createComponentInstances = () => ({
49
+ // Memoized component instances - created once and reused
50
+ const componentInstancesCache = {
50
51
  filter: _jsx(AdmissionFilter, {}),
51
52
  form: _jsx(AdmissionForm, {}),
52
53
  moreActions: _jsx(AdmissionMoreActions, {}),
53
54
  view: _jsx(AdmissionView, {}),
54
- });
55
- const createAdmissionConfig = ({ cancelLabel, dispatch, drawer, drawerTitle, labelActions, labelClass, labelEnabled, labelFirstName, labelId, labelLastName, labelRegistrationCode, labelStatus, saveLabel, searchPlaceholder, tableDescription, tableTitle, }) => {
55
+ };
56
+ const createComponentInstances = () => componentInstancesCache;
57
+ const createAdmissionConfig = ({ cancelLabel, drawerTitle, labelActions, labelClass, labelEnabled, labelFirstName, labelId, labelLastName, labelRegistrationCode, labelStatus, saveLabel, searchPlaceholder, tableDescription, tableTitle, onClearFilters, }) => {
56
58
  const components = createComponentInstances();
57
59
  return {
58
60
  moduleName: "admission",
@@ -76,10 +78,8 @@ const createAdmissionConfig = ({ cancelLabel, dispatch, drawer, drawerTitle, lab
76
78
  tableDescription,
77
79
  tableTitle,
78
80
  viewContent: components.view,
79
- size: drawer === ADMISSION_DRAWER.FORM_DRAWER ? "full" : "small",
80
- onClearFilters: () => {
81
- dispatch({ type: ADMISSION_ACTION_TYPES.RESET_FORM });
82
- },
81
+ size: "small",
82
+ onClearFilters,
83
83
  };
84
84
  };
85
85
  // ============================================================================
@@ -88,10 +88,16 @@ const createAdmissionConfig = ({ cancelLabel, dispatch, drawer, drawerTitle, lab
88
88
  const GenericAdmissionPage = createGenericModulePage();
89
89
  const AdmissionPageInner = (props) => {
90
90
  const context = useAdmissionModule();
91
- // Memoize config creation - destructure props to avoid object reference changes
92
- const admissionConfig = useMemo(() => createAdmissionConfig({
93
- dispatch: context.dispatch,
94
- drawer: context.state.drawer,
91
+ // Create a stable onClearFilters callback.
92
+ // dispatch from useReducer is stable across renders, so we can safely use an empty dependency array
93
+ // or only depend on dispatch (which never changes). Using empty array is safest.
94
+ const handleClearFilters = useCallback(() => {
95
+ context.dispatch({ type: ADMISSION_ACTION_TYPES.RESET_FORM });
96
+ }, []);
97
+ // Memoize config creation with translation props only.
98
+ // The key insight: we create the config ONCE when translations change,
99
+ // then apply drawer sizing as a separate, cheaper operation below.
100
+ const baseConfig = useMemo(() => createAdmissionConfig({
95
101
  cancelLabel: props.cancelLabel,
96
102
  drawerTitle: props.drawerTitle,
97
103
  labelActions: props.labelActions,
@@ -106,9 +112,8 @@ const AdmissionPageInner = (props) => {
106
112
  searchPlaceholder: props.searchPlaceholder,
107
113
  tableDescription: props.tableDescription,
108
114
  tableTitle: props.tableTitle,
115
+ onClearFilters: handleClearFilters,
109
116
  }), [
110
- context.dispatch,
111
- context.state.drawer,
112
117
  props.cancelLabel,
113
118
  props.drawerTitle,
114
119
  props.labelActions,
@@ -123,7 +128,24 @@ const AdmissionPageInner = (props) => {
123
128
  props.searchPlaceholder,
124
129
  props.tableDescription,
125
130
  props.tableTitle,
131
+ handleClearFilters,
126
132
  ]);
133
+ // Apply drawer sizing without recreating the entire config.
134
+ // We use a technique where we only update the size property and pass it separately,
135
+ // ensuring GenericAdmissionPage gets a stable reference unless translation props change.
136
+ const admissionConfig = useMemo(() => {
137
+ const isFormDrawerOpen = context.state.drawer === ADMISSION_DRAWER.FORM_DRAWER;
138
+ // Create a new config only if drawer state actually affects sizing
139
+ // This prevents unnecessary recreations of the same-sized config
140
+ if (isFormDrawerOpen && baseConfig.size === "full") {
141
+ return baseConfig; // Already full size, no need to recreate
142
+ }
143
+ if (!isFormDrawerOpen && baseConfig.size === "small") {
144
+ return baseConfig; // Already small size, no need to recreate
145
+ }
146
+ // Only recreate if size needs to change
147
+ return Object.assign(Object.assign({}, baseConfig), { size: isFormDrawerOpen ? "full" : "small" });
148
+ }, [baseConfig, context.state.drawer]);
127
149
  const hasPermission = resolveRbacPermissions({
128
150
  userRole: props.userRole,
129
151
  moduleName: "Admission",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appcorp/fusion-storybook",
3
- "version": "0.1.101",
3
+ "version": "0.2.1",
4
4
  "scripts": {
5
5
  "build-storybook": "storybook build",
6
6
  "build:next": "next build",