Compare commits
15 Commits
9c64217b72
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 52a97f2a97 | |||
| 6c141b71da | |||
| 89fed20f70 | |||
| 9414421430 | |||
| c4f0fcc233 | |||
| 5180f52698 | |||
| ce7cf9435a | |||
|
|
ad2252f5e4 | ||
|
|
287dbcf4da | ||
|
|
f963b38339 | ||
|
|
55cb9038ad | ||
|
|
9d907068a6 | ||
|
|
ecb90c69aa | ||
|
|
070e56e1af | ||
|
|
3e460ae46c |
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,5 +1,35 @@
|
||||
# @warkypublic/zustandsyncstore
|
||||
|
||||
## 0.0.30
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 89fed20: fix: update GridlerStore setState type to accept full state values
|
||||
|
||||
## 0.0.29
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 5180f52: feat(Former): ✨ update layout to use buttonArea prop instead of buttonOnTop
|
||||
|
||||
## 0.0.28
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 287dbcf: 1
|
||||
|
||||
## 0.0.27
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 9d90706: feat(Gridler): ✨ add isValuesInPages method and update state handling
|
||||
|
||||
## 0.0.26
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3e460ae: fixed Gridler selectFirstRow
|
||||
|
||||
## 0.0.25
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -11,7 +11,7 @@ const config = defineConfig([
|
||||
{
|
||||
extends: ['js/recommended'],
|
||||
files: ['**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
|
||||
ignores: ['**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', '*stories.tsx','dist/**'],
|
||||
languageOptions: { globals: globals.browser },
|
||||
plugins: { js },
|
||||
},
|
||||
@@ -20,7 +20,7 @@ const config = defineConfig([
|
||||
tseslint.configs.recommended,
|
||||
{
|
||||
...pluginReact.configs.flat.recommended,
|
||||
ignores: ['**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', '*stories.tsx'],
|
||||
ignores: ['**/*.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}', '*stories.tsx','dist/**'],
|
||||
rules: {
|
||||
...pluginReact.configs.flat.recommended.rules,
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
@@ -34,6 +34,7 @@ const config = defineConfig([
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
},
|
||||
},
|
||||
{ignores: ['dist/**','node_modules/**','vite.config.*','eslint.config.*' ]},
|
||||
]);
|
||||
|
||||
export default config;
|
||||
|
||||
79
package.json
79
package.json
@@ -1,8 +1,26 @@
|
||||
{
|
||||
"name": "@warkypublic/oranguru",
|
||||
"author": "Warky Devs",
|
||||
"version": "0.0.25",
|
||||
"version": "0.0.30",
|
||||
"type": "module",
|
||||
"types": "./dist/lib.d.ts",
|
||||
"main": "./dist/lib.cjs.js",
|
||||
"module": "./dist/lib.es.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/lib.d.ts",
|
||||
"import": "./dist/lib.es.js",
|
||||
"require": "./dist/lib.cjs.js"
|
||||
},
|
||||
"./oranguru.css": "./dist/oranguru.css",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"dist/**",
|
||||
"assets/**",
|
||||
"public/**",
|
||||
"global.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc -b && vite build",
|
||||
@@ -17,71 +35,40 @@
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"build-storybook": "storybook build"
|
||||
},
|
||||
"files": [
|
||||
"dist/**",
|
||||
"assets/**",
|
||||
"public/**",
|
||||
"global.d.ts"
|
||||
],
|
||||
"module": "./src.lib.ts",
|
||||
"types": "./src/lib.ts",
|
||||
"publishConfig": {
|
||||
"main": "./dist/lib.cjs.js",
|
||||
"module": "./dist/lib.es.js",
|
||||
"require": "./dist/lib.cjs.js",
|
||||
"types": "./dist/lib.d.ts",
|
||||
"typings": "./dist/lib.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/lib.es.js",
|
||||
"types": "./dist/lib.d.ts",
|
||||
"default": "./dist/lib.cjs.js"
|
||||
},
|
||||
"./package.json": "./package.json",
|
||||
"./oranguru.css": "./dist/oranguru.css"
|
||||
}
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./src/lib.ts",
|
||||
"default": "./src/lib.ts"
|
||||
},
|
||||
"./oranguru.css": "./src/oranguru.css"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tanstack/react-virtual": "^3.13.18",
|
||||
"moment": "^2.30.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@changesets/cli": "^2.29.7",
|
||||
"@eslint/js": "^9.38.0",
|
||||
"@storybook/react-vite": "^9.1.15",
|
||||
"@changesets/cli": "^2.29.8",
|
||||
"@eslint/js": "^9.39.2",
|
||||
"@storybook/react-vite": "^10.2.1",
|
||||
"@testing-library/jest-dom": "^6.9.1",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@types/node": "^24.9.1",
|
||||
"@types/react": "^19.2.2",
|
||||
"@types/react-dom": "^19.2.2",
|
||||
"@typescript-eslint/parser": "^8.46.2",
|
||||
"@vitejs/plugin-react-swc": "^4.2.0",
|
||||
"@types/node": "^25.1.0",
|
||||
"@types/react": "^19.2.10",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@typescript-eslint/parser": "^8.54.0",
|
||||
"@vitejs/plugin-react-swc": "^4.2.2",
|
||||
"eslint": "^9.38.0",
|
||||
"eslint-config-mantine": "^4.0.3",
|
||||
"eslint-plugin-perfectionist": "^4.15.1",
|
||||
"eslint-plugin-perfectionist": "^5.4.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"eslint-plugin-storybook": "^9.1.15",
|
||||
"global": "^4.4.0",
|
||||
"globals": "^16.4.0",
|
||||
"globals": "^17.2.0",
|
||||
"jiti": "^2.6.1",
|
||||
"jsdom": "^27.0.1",
|
||||
"jsdom": "^27.4.0",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-preset-mantine": "^1.18.0",
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-eslint": "^16.4.2",
|
||||
"react": "^19.2.0",
|
||||
"react-dom": "^19.2.0",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4",
|
||||
"storybook": "^9.1.15",
|
||||
"typescript": "~5.9.3",
|
||||
"typescript-eslint": "^8.46.2",
|
||||
|
||||
1095
pnpm-lock.yaml
generated
1095
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
||||
//@ts-ignore
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { useState } from 'react';
|
||||
|
||||
@@ -23,8 +23,8 @@ export interface FormerProps<T extends FieldValues = any> {
|
||||
id?: string;
|
||||
keepOpen?: boolean;
|
||||
layout?: {
|
||||
buttonArea?: "bottom" | "none" | "top";
|
||||
buttonAreaGroupProps?: GroupProps;
|
||||
buttonOnTop?: boolean;
|
||||
closeButtonProps?: ButtonProps;
|
||||
closeButtonTitle?: React.ReactNode;
|
||||
renderBottom?: FormerSectionRender<T>;
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useFormerStore } from './Former.store';
|
||||
import { FormerButtonArea } from './FormerButtonArea';
|
||||
|
||||
export const FormerLayoutBottom = () => {
|
||||
const { buttonOnTop, getState, opened, renderBottom } = useFormerStore((state) => ({
|
||||
buttonOnTop: state.layout?.buttonOnTop,
|
||||
const { buttonArea, getState, opened, renderBottom } = useFormerStore((state) => ({
|
||||
buttonArea: state.layout?.buttonArea,
|
||||
getState: state.getState,
|
||||
opened: state.opened,
|
||||
renderBottom: state.layout?.renderBottom,
|
||||
@@ -19,5 +19,5 @@ export const FormerLayoutBottom = () => {
|
||||
);
|
||||
}
|
||||
|
||||
return buttonOnTop ? <></> : <FormerButtonArea />;
|
||||
return buttonArea === "bottom" ? <FormerButtonArea /> : <></>;
|
||||
};
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useFormerStore } from './Former.store';
|
||||
import { FormerButtonArea } from './FormerButtonArea';
|
||||
|
||||
export const FormerLayoutTop = () => {
|
||||
const { buttonOnTop, getState, opened, renderTop } = useFormerStore((state) => ({
|
||||
buttonOnTop: state.layout?.buttonOnTop,
|
||||
const { buttonArea, getState, opened, renderTop } = useFormerStore((state) => ({
|
||||
buttonArea: state.layout?.buttonArea,
|
||||
getState: state.getState,
|
||||
opened: state.opened,
|
||||
renderTop: state.layout?.renderTop,
|
||||
@@ -18,5 +18,5 @@ export const FormerLayoutTop = () => {
|
||||
getState
|
||||
);
|
||||
}
|
||||
return buttonOnTop ? <FormerButtonArea /> : <></>;
|
||||
return buttonArea === "top" ? <FormerButtonArea /> : <></>;
|
||||
};
|
||||
|
||||
@@ -35,8 +35,8 @@ export const FormTest = () => {
|
||||
url: '',
|
||||
});
|
||||
const [layout, setLayout] = useState({
|
||||
buttonArea: "bottom",
|
||||
buttonAreaGroupProps: { justify: 'center' },
|
||||
buttonOnTop: false,
|
||||
title: 'Custom Former Title',
|
||||
} as FormerProps['layout']);
|
||||
|
||||
@@ -63,11 +63,13 @@ export const FormTest = () => {
|
||||
label="Disable HTML Form"
|
||||
onChange={(event) => setDisableHTML(event.currentTarget.checked)}
|
||||
/>
|
||||
<Switch
|
||||
checked={layout?.buttonOnTop ?? false}
|
||||
label="Button On Top"
|
||||
onChange={(event) => setLayout({ ...layout, buttonOnTop: event.currentTarget.checked })}
|
||||
<Select
|
||||
data={['top', 'bottom', 'none']}
|
||||
|
||||
onChange={(value) => setLayout({ ...layout, buttonArea: value as 'bottom' | 'none' | 'top' })}
|
||||
value={layout?.buttonArea}
|
||||
/>
|
||||
|
||||
<Switch
|
||||
checked={apiOptions.type === 'api'}
|
||||
label="Use API"
|
||||
|
||||
@@ -162,6 +162,7 @@ export interface GridlerState {
|
||||
hasLocalData: boolean;
|
||||
isEmpty: boolean;
|
||||
|
||||
isValuesInPages: () => boolean
|
||||
loadingData?: boolean;
|
||||
loadPage: (page: number, clearMode?: 'all' | 'page') => Promise<void>;
|
||||
mounted: boolean;
|
||||
@@ -180,6 +181,7 @@ export interface GridlerState {
|
||||
onHeaderClicked: (colIndex: number, event: HeaderClickedEventArgs) => void;
|
||||
onHeaderMenuClick: (col: number, screenPosition: Rectangle) => void;
|
||||
onItemHovered: (args: GridMouseEventArgs) => void;
|
||||
|
||||
onVisibleRegionChanged: (
|
||||
r: Rectangle,
|
||||
tx: number,
|
||||
@@ -189,18 +191,18 @@ export interface GridlerState {
|
||||
freezeRegions?: readonly Rectangle[];
|
||||
selected?: Item;
|
||||
}
|
||||
|
||||
) => void;
|
||||
|
||||
pageSize: number;
|
||||
|
||||
ready: boolean;
|
||||
refreshCells: (fromRow?: number, toRow?: number, col?: number) => void;
|
||||
reload?: () => Promise<void>;
|
||||
|
||||
reload?: () => Promise<void>;
|
||||
renderColumns?: GridlerColumns;
|
||||
setState: <K extends keyof GridlerStoreState>(
|
||||
key: K,
|
||||
value: Partial<GridlerStoreState[K]>
|
||||
value: GridlerStoreState[K]
|
||||
) => void;
|
||||
setStateFN: <K extends keyof GridlerStoreState>(
|
||||
key: K,
|
||||
@@ -378,6 +380,31 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
},
|
||||
hasLocalData: false,
|
||||
isEmpty: true,
|
||||
isValuesInPages: () => {
|
||||
const state = get();
|
||||
if (state.values && Object.keys(state._page_data).length > 0) {
|
||||
let found = false;
|
||||
for (const page in state._page_data) {
|
||||
const pageData = state._page_data[Number(page)];
|
||||
for (const row of pageData) {
|
||||
const keyField = state.keyField ?? 'id';
|
||||
const rowKey = row?.[keyField];
|
||||
if (rowKey !== undefined) {
|
||||
const match = state.values.find((v) => String(v?.[keyField]) === String(rowKey));
|
||||
if (match) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
keyField: 'id',
|
||||
loadPage: async (pPage: number, clearMode?: 'all' | 'page') => {
|
||||
const state = get();
|
||||
@@ -511,6 +538,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
return { ...renderCols, [fromItem?.id]: to, [toItem?.id]: from };
|
||||
});
|
||||
},
|
||||
|
||||
onColumnProposeMove: (startIndex: number, endIndex: number) => {
|
||||
const s = get();
|
||||
const fromItem = s.renderColumns?.[startIndex];
|
||||
@@ -520,7 +548,6 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
onColumnResize: (
|
||||
column: GridColumn,
|
||||
newSize: number,
|
||||
@@ -922,7 +949,7 @@ const { Provider, useStore: useGridlerStore } = createSyncStore<GridlerStoreStat
|
||||
}
|
||||
},
|
||||
total_rows: 1000,
|
||||
uniqueid: getUUID(),
|
||||
uniqueid: getUUID()
|
||||
}),
|
||||
(props) => {
|
||||
const [setState, getState] = props.useStore((s) => [s.setState, s.getState]);
|
||||
|
||||
@@ -230,7 +230,7 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
||||
ops.push({
|
||||
name: 'sql_filter',
|
||||
type: 'custom-sql-w',
|
||||
value: props.filter,
|
||||
value: `(${props.filter})`,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -272,9 +272,13 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
||||
useEffect(() => {
|
||||
setState('useAPIQuery', useAPIQuery);
|
||||
setState('askAPIRowNumber', askAPIRowNumber);
|
||||
|
||||
const isValuesInPages = getState('isValuesInPages');
|
||||
|
||||
const _refresh = getState('_refresh');
|
||||
|
||||
if (!isValuesInPages) {
|
||||
setState('values', []);
|
||||
}
|
||||
|
||||
//Reset the loaded pages to new rules
|
||||
_refresh?.().then(() => {
|
||||
const onChange = getState('onChange');
|
||||
@@ -289,6 +293,8 @@ function _GlidlerAPIAdaptorForGoLangv2<T = unknown>(props: GlidlerAPIAdaptorForG
|
||||
return <></>;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//The computer component does not need to be recalculated on every render, so we use React.memo to prevent unnecessary re-renders.
|
||||
export const GlidlerAPIAdaptorForGoLangv2 = React.memo(_GlidlerAPIAdaptorForGoLangv2);
|
||||
|
||||
|
||||
@@ -59,8 +59,8 @@ export function GlidlerFormAdaptor(props: {
|
||||
storeState: GridlerState,
|
||||
row?: Record<string, unknown>,
|
||||
col?: GridlerColumn,
|
||||
defaultItems?: Array<unknown>
|
||||
) => {
|
||||
defaultItems?: MantineBetterMenuInstanceItem[]
|
||||
): MantineBetterMenuInstanceItem[] => {
|
||||
//console.log('GlidlerFormInterface getMenuItems', id);
|
||||
|
||||
if (id === 'header-menu') {
|
||||
|
||||
@@ -17,14 +17,14 @@ Object.defineProperty(window, 'matchMedia', {
|
||||
})
|
||||
|
||||
// Mock ResizeObserver
|
||||
global.ResizeObserver = vi.fn().mockImplementation(() => ({
|
||||
globalThis.ResizeObserver = vi.fn().mockImplementation(() => ({
|
||||
disconnect: vi.fn(),
|
||||
observe: vi.fn(),
|
||||
unobserve: vi.fn(),
|
||||
}))
|
||||
|
||||
// Mock IntersectionObserver
|
||||
global.IntersectionObserver = vi.fn().mockImplementation(() => ({
|
||||
globalThis.IntersectionObserver = vi.fn().mockImplementation(() => ({
|
||||
disconnect: vi.fn(),
|
||||
observe: vi.fn(),
|
||||
unobserve: vi.fn(),
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "Node",
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
@@ -37,5 +37,6 @@
|
||||
"src",
|
||||
"lib.ts",
|
||||
"*.d.ts",
|
||||
]
|
||||
],
|
||||
|
||||
}
|
||||
@@ -23,5 +23,5 @@
|
||||
},
|
||||
"include": [
|
||||
"vite.config.ts"
|
||||
]
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user