@laser-ui/components 0.6.0 → 0.6.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
4
4
 
5
+ ## [0.6.1](https://github.com/laser-ui/laser-ui/compare/v0.6.0...v0.6.1) (2024-04-26)
6
+
7
+ **Note:** Version bump only for package @laser-ui/components
8
+
5
9
  # [0.6.0](https://github.com/laser-ui/laser-ui/compare/v0.5.0...v0.6.0) (2024-03-06)
6
10
 
7
11
  ### Bug Fixes
@@ -0,0 +1,17 @@
1
+ /// <reference types="react" />
2
+ export interface DialogInstance<P extends object> {
3
+ key: string | number;
4
+ node: React.FunctionComponentElement<P>;
5
+ close: () => void;
6
+ rerender: (props: P) => void;
7
+ }
8
+ export declare class DialogService {
9
+ private _key;
10
+ private _dialogs;
11
+ private _emitChange;
12
+ constructor(emitChange: (dialogs: DialogInstance<any>[]) => void);
13
+ open<P extends object>(type: React.FC<P>, props: Omit<P, 'visible'>, key?: string | number): DialogInstance<P>;
14
+ close(key: string | number): void;
15
+ rerender(key: string | number, props: any): void;
16
+ closeAll(animation?: boolean): void;
17
+ }
@@ -0,0 +1,85 @@
1
+ import { cloneElement, createElement } from 'react';
2
+ export class DialogService {
3
+ constructor(emitChange) {
4
+ Object.defineProperty(this, "_key", {
5
+ enumerable: true,
6
+ configurable: true,
7
+ writable: true,
8
+ value: -1
9
+ });
10
+ Object.defineProperty(this, "_dialogs", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: []
15
+ });
16
+ Object.defineProperty(this, "_emitChange", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: void 0
21
+ });
22
+ this._emitChange = () => {
23
+ emitChange([].concat(this._dialogs));
24
+ };
25
+ }
26
+ open(type, props, key) {
27
+ const dialogKey = key !== null && key !== void 0 ? key : `l_#${++this._key}`;
28
+ const dialogProps = Object.assign(Object.assign({}, props), { visible: true, skipFirstTransition: false, onClose: () => {
29
+ var _a, _b;
30
+ this.close(dialogKey);
31
+ (_b = (_a = props).onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
32
+ }, afterVisibleChange: (visible) => {
33
+ var _a, _b;
34
+ (_b = (_a = props).afterVisibleChange) === null || _b === void 0 ? void 0 : _b.call(_a, visible);
35
+ if (!visible) {
36
+ const index = this._dialogs.findIndex((dialog) => dialog.key === dialogKey);
37
+ if (index !== -1) {
38
+ this._dialogs.splice(index, 1);
39
+ this._emitChange();
40
+ }
41
+ }
42
+ } });
43
+ const node = createElement(type, Object.assign({ key: dialogKey }, dialogProps));
44
+ const instance = {
45
+ key: dialogKey,
46
+ node,
47
+ close: () => {
48
+ this.close(dialogKey);
49
+ },
50
+ rerender: (props) => {
51
+ this.rerender(dialogKey, props);
52
+ },
53
+ };
54
+ this._dialogs.push(instance);
55
+ this._emitChange();
56
+ return instance;
57
+ }
58
+ close(key) {
59
+ const index = this._dialogs.findIndex((dialog) => dialog.key === key);
60
+ if (index !== -1) {
61
+ const instance = this._dialogs[index];
62
+ instance.node = cloneElement(instance.node, { visible: false });
63
+ this._emitChange();
64
+ }
65
+ }
66
+ rerender(key, props) {
67
+ const index = this._dialogs.findIndex((dialog) => dialog.key === key);
68
+ if (index !== -1) {
69
+ const instance = this._dialogs[index];
70
+ instance.node = cloneElement(instance.node, props);
71
+ this._emitChange();
72
+ }
73
+ }
74
+ closeAll(animation = true) {
75
+ if (animation) {
76
+ this._dialogs.forEach((dialog) => {
77
+ dialog.node = cloneElement(dialog.node, { visible: false });
78
+ });
79
+ }
80
+ else {
81
+ this._dialogs = [];
82
+ }
83
+ this._emitChange();
84
+ }
85
+ }
package/drawer/Drawer.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { __rest } from "tslib";
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { isString, isUndefined } from 'lodash';
4
- import { cloneElement, useContext, useEffect, useId, useMemo, useRef } from 'react';
4
+ import { cloneElement, useCallback, useContext, useEffect, useId, useRef } from 'react';
5
5
  import { DrawerFooter } from './DrawerFooter';
6
6
  import { DrawerHeader } from './DrawerHeader';
7
7
  import { CLASSES, DrawerContext } from './vars';
@@ -17,6 +17,7 @@ export const Drawer = (props) => {
17
17
  const namespace = useNamespace();
18
18
  const styled = useStyled(CLASSES, { drawer: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.drawer }, styleOverrides);
19
19
  const drawerRef = useRef(null);
20
+ const drawerContentRef = useRef(null);
20
21
  const dataRef = useRef({
21
22
  prevActiveEl: null,
22
23
  });
@@ -24,21 +25,8 @@ export const Drawer = (props) => {
24
25
  const titleId = `${namespace}-drawer-title-${uniqueId}`;
25
26
  const bodyId = `${namespace}-drawer-content-${uniqueId}`;
26
27
  const drawerContext = useContext(DrawerContext);
27
- const ancestryIds = [];
28
- if (visible) {
29
- drawerContext.forEach((ancestry) => {
30
- if (ancestry.placement === placement) {
31
- ancestryIds.push(ancestry.uniqueId);
32
- }
33
- });
34
- }
35
- const drawerContextValue = useMemo(() => drawerContext.concat({ uniqueId, placement }), [drawerContext, placement, uniqueId]);
36
- useEffect(() => {
37
- let offset = 0;
38
- document.querySelectorAll(`[data-l-drawer-ancestry~="${uniqueId}"]`).forEach((el) => {
39
- offset += placement === 'top' || placement === 'bottom' ? el.offsetHeight : el.offsetWidth;
40
- });
41
- offset = (offset / 3) * 2;
28
+ const drawerContextValue = useCallback((offsets) => {
29
+ const offset = (offsets[placement].reduce((v, r) => v + r, 0) / 3) * 2;
42
30
  if (drawerRef.current) {
43
31
  drawerRef.current.style.transform =
44
32
  placement === 'top'
@@ -49,7 +37,31 @@ export const Drawer = (props) => {
49
37
  ? `translateY(-${offset}px)`
50
38
  : `translateX(${offset}px)`;
51
39
  }
52
- });
40
+ if (drawerContentRef.current) {
41
+ drawerContext(Object.assign(Object.assign({}, offsets), { [placement]: [
42
+ placement === 'top' || placement === 'bottom' ? drawerContentRef.current.offsetHeight : drawerContentRef.current.offsetWidth,
43
+ ].concat(offsets[placement]) }));
44
+ }
45
+ }, [drawerContext, placement]);
46
+ const handleVisibleChange = (visible) => {
47
+ if (drawerContentRef.current) {
48
+ drawerContext(Object.assign({ top: [], right: [], bottom: [], left: [] }, {
49
+ [placement]: visible
50
+ ? [
51
+ placement === 'top' || placement === 'bottom'
52
+ ? drawerContentRef.current.offsetHeight
53
+ : drawerContentRef.current.offsetWidth,
54
+ ]
55
+ : [],
56
+ }));
57
+ }
58
+ };
59
+ useEffect(() => {
60
+ if (!visible) {
61
+ handleVisibleChange(false);
62
+ }
63
+ // eslint-disable-next-line react-hooks/exhaustive-deps
64
+ }, [visible]);
53
65
  const maxZIndex = useMaxIndex(visible);
54
66
  const zIndex = !isUndefined(zIndexProp)
55
67
  ? zIndexProp
@@ -98,7 +110,9 @@ export const Drawer = (props) => {
98
110
  }
99
111
  return el;
100
112
  }
101
- : container, children: _jsx(Transition, { enter: visible, during: TTANSITION_DURING_BASE, skipFirstTransition: skipFirstTransition, destroyWhenLeaved: destroyAfterClose, afterEnter: () => {
113
+ : container, children: _jsx(Transition, { enter: visible, during: TTANSITION_DURING_BASE, skipFirstTransition: skipFirstTransition, destroyWhenLeaved: destroyAfterClose, afterRender: () => {
114
+ handleVisibleChange(true);
115
+ }, afterEnter: () => {
102
116
  afterVisibleChange === null || afterVisibleChange === void 0 ? void 0 : afterVisibleChange(true);
103
117
  dataRef.current.prevActiveEl = document.activeElement;
104
118
  if (drawerRef.current) {
@@ -129,7 +143,7 @@ export const Drawer = (props) => {
129
143
  }
130
144
  } })), _jsxs("div", Object.assign({}, mergeCS(styled('drawer__content'), {
131
145
  style: Object.assign({ width: placement === 'left' || placement === 'right' ? width : undefined, height: placement === 'bottom' || placement === 'top' ? height : undefined }, transitionStyles[state]),
132
- }), { "data-l-drawer-ancestry": ancestryIds.join(' '), children: [headerNode, _jsx("div", Object.assign({}, styled('drawer__body'), { id: bodyId, children: _jsx(DrawerContext.Provider, { value: drawerContextValue, children: children }) })), footer &&
146
+ }), { ref: drawerContentRef, children: [headerNode, _jsx("div", Object.assign({}, styled('drawer__body'), { id: bodyId, children: _jsx(DrawerContext.Provider, { value: drawerContextValue, children: children }) })), footer &&
133
147
  cloneElement(footer, {
134
148
  _onClose: () => {
135
149
  onClose === null || onClose === void 0 ? void 0 : onClose();
package/drawer/types.d.ts CHANGED
@@ -34,3 +34,9 @@ export interface DrawerFooterProps extends BaseProps<'drawer', typeof CLASSES>,
34
34
  onCancelClick?: () => any | Promise<any>;
35
35
  onOkClick?: () => any | Promise<any>;
36
36
  }
37
+ export interface Offsets {
38
+ top: number[];
39
+ right: number[];
40
+ bottom: number[];
41
+ left: number[];
42
+ }
package/drawer/vars.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  /// <reference types="react" />
2
+ import type { Offsets } from './types';
2
3
  export declare const CLASSES: {
3
4
  drawer: string;
4
5
  'drawer--top': string;
@@ -15,7 +16,4 @@ export declare const CLASSES: {
15
16
  'drawer__footer--center': string;
16
17
  'drawer__footer--right': string;
17
18
  };
18
- export declare const DrawerContext: import("react").Context<{
19
- uniqueId: string;
20
- placement: 'top' | 'right' | 'bottom' | 'left';
21
- }[]>;
19
+ export declare const DrawerContext: import("react").Context<(offsets: Offsets) => void>;
package/drawer/vars.js CHANGED
@@ -15,4 +15,4 @@ export const CLASSES = {
15
15
  'drawer__footer--center': '^drawer__footer--center',
16
16
  'drawer__footer--right': '^drawer__footer--right',
17
17
  };
18
- export const DrawerContext = createContext([]);
18
+ export const DrawerContext = createContext(() => { });
package/hooks/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { useComponentProps } from './useComponentProps';
2
2
  export { useControlled } from './useControlled';
3
3
  export { useDesign } from './useDesign';
4
+ export { useDialogService } from './useDialogService';
4
5
  export { useFocusVisible } from './useFocusVisible';
5
6
  export { useJSS } from './useJSS';
6
7
  export { useLayout } from './useLayout';
package/hooks/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { useComponentProps } from './useComponentProps';
2
2
  export { useControlled } from './useControlled';
3
3
  export { useDesign } from './useDesign';
4
+ export { useDialogService } from './useDialogService';
4
5
  export { useFocusVisible } from './useFocusVisible';
5
6
  export { useJSS } from './useJSS';
6
7
  export { useLayout } from './useLayout';
@@ -8,5 +8,5 @@ export declare function useDesign(opts: {
8
8
  }): {
9
9
  'data-l-compose-active': boolean | undefined;
10
10
  'data-l-compose-disabled': boolean | undefined;
11
- 'data-l-form-invalid': false | "error" | "warning" | undefined;
11
+ 'data-l-form-invalid': false | "warning" | "error" | undefined;
12
12
  };
@@ -0,0 +1,3 @@
1
+ import type { DialogInstance } from '../dialog-service';
2
+ import { DialogService } from '../dialog-service';
3
+ export declare function useDialogService(): readonly [DialogService, DialogInstance<any>[]];
@@ -0,0 +1,10 @@
1
+ import { useImmer } from '@laser-ui/hooks';
2
+ import { useMemo } from 'react';
3
+ import { DialogService } from '../dialog-service';
4
+ export function useDialogService() {
5
+ const [dialogs, setDialogs] = useImmer([]);
6
+ const service = useMemo(() => new DialogService((dialogs) => {
7
+ setDialogs(dialogs);
8
+ }), [setDialogs]);
9
+ return [service, dialogs];
10
+ }
package/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { useDialogService } from './hooks';
1
2
  export { Root, DialogService } from './root';
2
3
  export { ConfigProvider } from './config-provider';
3
4
  export { Accordion } from './accordion';
package/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { useDialogService } from './hooks';
1
2
  export { Root, DialogService } from './root';
2
3
  export { ConfigProvider } from './config-provider';
3
4
  export { Accordion } from './accordion';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laser-ui/components",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "React components.",
5
5
  "keywords": [
6
6
  "ui",
@@ -26,8 +26,8 @@
26
26
  "module": "./index.js",
27
27
  "types": "./index.d.ts",
28
28
  "dependencies": {
29
- "@laser-ui/hooks": "0.6.0",
30
- "@laser-ui/utils": "0.6.0",
29
+ "@laser-ui/hooks": "0.6.1",
30
+ "@laser-ui/utils": "0.6.1",
31
31
  "@material-design-icons/svg": "^0.14.12",
32
32
  "jss": "^10.10.0",
33
33
  "jss-preset-default": "^10.10.0",
@@ -42,5 +42,5 @@
42
42
  "access": "public",
43
43
  "directory": "../../dist/libs/components"
44
44
  },
45
- "gitHead": "b131bc22712979a5de35f237d1b0ef2d490ae62e"
45
+ "gitHead": "156633eb28f7306ce633cea5bf5a094045aa4ad8"
46
46
  }
package/root/Root.js CHANGED
@@ -2,7 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useEvent, useRefExtra } from '@laser-ui/hooks';
3
3
  import { isString, set } from 'lodash';
4
4
  import { useStore } from 'rcl-store';
5
- import { createElement, useEffect, useMemo, useRef } from 'react';
5
+ import { useEffect, useMemo, useRef } from 'react';
6
6
  import { ROOT_DATA, RootContext, Store } from './vars';
7
7
  import dayjs from '../dayjs';
8
8
  import { Portal } from '../internal/portal';
@@ -84,5 +84,5 @@ export function Root(props) {
84
84
  default:
85
85
  break;
86
86
  }
87
- return (_jsxs(_Fragment, { children: [_jsxs(RootContext.Provider, { value: context, children: [children, dialogs.map(({ type, key, props }) => createElement(type, Object.assign({ key }, props)))] }), _jsx(Portal, { selector: () => document.body, children: _jsx(WindowSize, {}) })] }));
87
+ return (_jsxs(_Fragment, { children: [_jsxs(RootContext.Provider, { value: context, children: [children, dialogs.map(({ node }) => node)] }), _jsx(Portal, { selector: () => document.body, children: _jsx(WindowSize, {}) })] }));
88
88
  }
@@ -1,12 +1,2 @@
1
- /// <reference types="react" />
2
- export interface DialogInstance<P extends object> {
3
- key: string | number;
4
- close: () => void;
5
- rerender: (props: P) => void;
6
- }
7
- export declare class DialogService {
8
- static open<P extends object>(type: React.FC<P>, props: Omit<P, 'visible'>, key?: string | number): DialogInstance<P>;
9
- static close(key: string | number): void;
10
- static rerender(key: string | number, type: any, props: any): void;
11
- static closeAll(animation?: boolean): void;
12
- }
1
+ import { DialogService as InternalDialogService } from '../dialog-service';
2
+ export declare const DialogService: InternalDialogService;
@@ -1,66 +1,5 @@
1
1
  import { Store } from './vars';
2
- let _key = 0;
3
- export class DialogService {
4
- static open(type, props, key) {
5
- const dialogKey = key !== null && key !== void 0 ? key : ++_key;
6
- Store.set('dialogs', (draft) => {
7
- draft.push({
8
- key: dialogKey,
9
- type,
10
- props: Object.assign(Object.assign({}, props), { visible: true, skipFirstTransition: false, onClose: () => {
11
- var _a, _b;
12
- (_b = (_a = props).onClose) === null || _b === void 0 ? void 0 : _b.call(_a);
13
- DialogService.close(dialogKey);
14
- }, afterVisibleChange: (visible) => {
15
- var _a, _b;
16
- (_b = (_a = props).afterVisibleChange) === null || _b === void 0 ? void 0 : _b.call(_a, visible);
17
- if (!visible) {
18
- const index = Store.get('dialogs').findIndex((dialog) => dialog.key === dialogKey);
19
- if (index !== -1) {
20
- Store.set('dialogs', (draft) => {
21
- draft.splice(index, 1);
22
- });
23
- }
24
- }
25
- } }),
26
- });
27
- });
28
- return {
29
- key: dialogKey,
30
- close: () => {
31
- DialogService.close(dialogKey);
32
- },
33
- rerender: (props) => {
34
- DialogService.rerender(dialogKey, type, props);
35
- },
36
- };
37
- }
38
- static close(key) {
39
- const index = Store.get('dialogs').findIndex((dialog) => dialog.key === key);
40
- if (index !== -1) {
41
- Store.set('dialogs', (draft) => {
42
- draft[index].props.visible = false;
43
- });
44
- }
45
- }
46
- static rerender(key, type, props) {
47
- const index = Store.get('dialogs').findIndex((dialog) => dialog.key === key);
48
- if (index !== -1) {
49
- Store.set('dialogs', (draft) => {
50
- draft.splice(index, 1, { key, type, props: Object.assign(draft[index].props, props) });
51
- });
52
- }
53
- }
54
- static closeAll(animation = true) {
55
- if (animation) {
56
- Store.set('dialogs', (draft) => {
57
- draft.forEach((dialog) => {
58
- dialog.props.visible = false;
59
- });
60
- });
61
- }
62
- else {
63
- Store.set('dialogs', []);
64
- }
65
- }
66
- }
2
+ import { DialogService as InternalDialogService } from '../dialog-service';
3
+ export const DialogService = new InternalDialogService((dialogs) => {
4
+ Store.set('dialogs', dialogs);
5
+ });
package/root/vars.d.ts CHANGED
@@ -1,12 +1,9 @@
1
1
  /// <reference types="react" />
2
+ import type { DialogInstance } from '../dialog-service';
2
3
  import type { Lang } from '../types';
3
4
  import resources from '../resources.json';
4
5
  export declare const Store: import("rcl-store").Store<{
5
- dialogs: {
6
- type: any;
7
- key: string | number;
8
- props: any;
9
- }[];
6
+ dialogs: DialogInstance<any>[];
10
7
  }, "dialogs">;
11
8
  export declare const ROOT_DATA: {
12
9
  clickEvent?: {