@laser-ui/components 0.0.5 → 0.1.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.
@@ -3,8 +3,8 @@ import { useEventCallback } from '@laser-ui/hooks';
3
3
  import { checkNodeExist } from '@laser-ui/utils';
4
4
  import { ReactComponent as KeyboardArrowRightOutlined } from '@material-design-icons/svg/outlined/keyboard_arrow_right.svg';
5
5
  import { isUndefined } from 'lodash';
6
- import { forwardRef, useImperativeHandle, useRef, useState } from 'react';
7
- import { useTranslation } from '../../hooks';
6
+ import { forwardRef, useImperativeHandle, useRef } from 'react';
7
+ import { useJSS, useTranslation } from '../../hooks';
8
8
  import { Icon } from '../../icon';
9
9
  import { Popup } from '../../internal/popup';
10
10
  import { Portal } from '../../internal/portal';
@@ -12,28 +12,29 @@ import { Transition } from '../../internal/transition';
12
12
  import { getHorizontalSidePosition, mergeCS } from '../../utils';
13
13
  import { TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../vars';
14
14
  export const DropdownSub = forwardRef((props, ref) => {
15
- const { children, namespace, styled, dropdownRef, id, level, icon, list, popupState, trigger, empty, focus, disabled, zIndex, onVisibleChange, } = props;
15
+ const { children, namespace, styled, id, level, icon, list, popupState, trigger, empty, focus, disabled, zIndex, onVisibleChange } = props;
16
+ const sheet = useJSS();
16
17
  const triggerRef = useRef(null);
17
18
  const popupRef = useRef(null);
18
19
  const { t } = useTranslation();
19
20
  const visible = !isUndefined(popupState);
20
- const [transformOrigin, setTransformOrigin] = useState();
21
- const [popupPositionStyle, setPopupPositionStyle] = useState({
22
- top: '-200vh',
23
- left: '-200vw',
24
- });
21
+ const transformOrigin = useRef();
25
22
  const updatePosition = useEventCallback(() => {
26
23
  if (visible && popupRef.current && triggerRef.current) {
27
24
  const [width, height] = [popupRef.current.offsetWidth, popupRef.current.offsetHeight];
28
- const { top, left, transformOrigin } = getHorizontalSidePosition(triggerRef.current, { width, height }, {
25
+ const position = getHorizontalSidePosition(triggerRef.current, { width, height }, {
29
26
  placement: 'right',
30
27
  inWindow: WINDOW_SPACE,
31
28
  });
32
- setPopupPositionStyle({
33
- top,
34
- left,
29
+ transformOrigin.current = position.transformOrigin;
30
+ if (sheet.classes.position) {
31
+ popupRef.current.classList.toggle(sheet.classes.position, false);
32
+ }
33
+ sheet.replaceRule('position', {
34
+ top: position.top,
35
+ left: position.left,
35
36
  });
36
- setTransformOrigin(transformOrigin);
37
+ popupRef.current.classList.toggle(sheet.classes.position, true);
37
38
  }
38
39
  });
39
40
  useImperativeHandle(ref, () => updatePosition, [updatePosition]);
@@ -45,7 +46,15 @@ export const DropdownSub = forwardRef((props, ref) => {
45
46
  }, onVisibleChange: onVisibleChange, children: ({ renderTrigger, renderPopup }) => (_jsxs(_Fragment, { children: [renderTrigger(_jsxs("li", Object.assign({}, mergeCS(styled('dropdown__item', 'dropdown__item--sub', {
46
47
  'dropdown__item.is-expand': visible,
47
48
  'dropdown__item.is-disabled': disabled,
48
- }), { style: { paddingLeft: 12 + level * 16 } }), { ref: triggerRef, id: id, role: "menuitem", "aria-haspopup": true, "aria-expanded": visible, "aria-disabled": disabled, children: [focus && _jsx("div", { className: `${namespace}-focus-outline` }), checkNodeExist(icon) && _jsx("div", Object.assign({}, styled('dropdown__item-icon'), { children: icon })), _jsx("div", Object.assign({}, styled('dropdown__item-content'), { children: children })), _jsx("div", Object.assign({}, styled('dropdown__sub-arrow'), { children: _jsx(Icon, { children: _jsx(KeyboardArrowRightOutlined, {}) }) }))] }))), _jsx(Portal, { selector: () => dropdownRef.current, children: _jsx(Transition, { enter: visible, during: TTANSITION_DURING_POPUP, afterRender: updatePosition, children: (state) => {
49
+ }), { style: { paddingLeft: 12 + level * 16 } }), { ref: triggerRef, id: id, role: "menuitem", "aria-haspopup": true, "aria-expanded": visible, "aria-disabled": disabled, children: [focus && _jsx("div", { className: `${namespace}-focus-outline` }), checkNodeExist(icon) && _jsx("div", Object.assign({}, styled('dropdown__item-icon'), { children: icon })), _jsx("div", Object.assign({}, styled('dropdown__item-content'), { children: children })), _jsx("div", Object.assign({}, styled('dropdown__sub-arrow'), { children: _jsx(Icon, { children: _jsx(KeyboardArrowRightOutlined, {}) }) }))] }))), _jsx(Portal, { selector: () => {
50
+ let el = document.getElementById(`${namespace}-dropdown-root`);
51
+ if (!el) {
52
+ el = document.createElement('div');
53
+ el.id = `${namespace}-dropdown-root`;
54
+ document.body.appendChild(el);
55
+ }
56
+ return el;
57
+ }, children: _jsx(Transition, { enter: visible, during: TTANSITION_DURING_POPUP, afterRender: updatePosition, children: (state) => {
49
58
  let transitionStyle = {};
50
59
  switch (state) {
51
60
  case 'enter':
@@ -54,7 +63,7 @@ export const DropdownSub = forwardRef((props, ref) => {
54
63
  case 'entering':
55
64
  transitionStyle = {
56
65
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
57
- transformOrigin,
66
+ transformOrigin: transformOrigin.current,
58
67
  };
59
68
  break;
60
69
  case 'leaving':
@@ -62,7 +71,7 @@ export const DropdownSub = forwardRef((props, ref) => {
62
71
  transform: 'scale(0)',
63
72
  opacity: 0,
64
73
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
65
- transformOrigin,
74
+ transformOrigin: transformOrigin.current,
66
75
  };
67
76
  break;
68
77
  case 'leaved':
@@ -72,7 +81,7 @@ export const DropdownSub = forwardRef((props, ref) => {
72
81
  break;
73
82
  }
74
83
  return renderPopup(_jsx("div", Object.assign({}, mergeCS(styled('dropdown-popup'), {
75
- style: Object.assign(Object.assign({ zIndex }, popupPositionStyle), transitionStyle),
84
+ style: Object.assign({ zIndex }, transitionStyle),
76
85
  }), { ref: popupRef, children: _jsx("ul", Object.assign({}, styled('dropdown__list'), { role: "menu", "aria-labelledby": id, children: empty ? (_jsx("div", Object.assign({}, mergeCS(styled('dropdown__empty'), { style: { paddingLeft: 12 + level * 16 } }), { children: t('No Data') }))) : (list) })) })));
77
86
  } }) })] })) }));
78
87
  });
package/hooks/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { useComponentProps } from './useComponentProps';
2
2
  export { useControlled } from './useControlled';
3
3
  export { useDesign } from './useDesign';
4
4
  export { useFocusVisible } from './useFocusVisible';
5
+ export { useJSS } from './useJSS';
5
6
  export { useLayout } from './useLayout';
6
7
  export { useListenGlobalScrolling } from './useListenGlobalScrolling';
7
8
  export { useLockScroll } from './useLockScroll';
package/hooks/index.js CHANGED
@@ -2,6 +2,7 @@ export { useComponentProps } from './useComponentProps';
2
2
  export { useControlled } from './useControlled';
3
3
  export { useDesign } from './useDesign';
4
4
  export { useFocusVisible } from './useFocusVisible';
5
+ export { useJSS } from './useJSS';
5
6
  export { useLayout } from './useLayout';
6
7
  export { useListenGlobalScrolling } from './useListenGlobalScrolling';
7
8
  export { useLockScroll } from './useLockScroll';
@@ -0,0 +1 @@
1
+ export declare function useJSS<T extends string | number | symbol>(): import("jss").StyleSheet<T>;
@@ -0,0 +1,15 @@
1
+ import { create } from 'jss';
2
+ import preset from 'jss-preset-default';
3
+ import { useEffect, useMemo } from 'react';
4
+ const jss = create();
5
+ jss.setup(preset());
6
+ export function useJSS() {
7
+ const sheet = useMemo(() => jss.createStyleSheet({}), []);
8
+ useEffect(() => {
9
+ sheet.attach();
10
+ return () => {
11
+ sheet.detach();
12
+ };
13
+ }, [sheet]);
14
+ return sheet;
15
+ }
package/menu/Menu.js CHANGED
@@ -116,7 +116,7 @@ function MenuFC(props, ref) {
116
116
  setFocusIds(ids.length === 0 ? (isUndefined(firstId) ? [] : [firstId]) : ids);
117
117
  };
118
118
  let handleKeyDown;
119
- const nodes = (menuRef) => {
119
+ const nodes = (() => {
120
120
  const getNodes = (arr, level, subParents, inNav = false) => {
121
121
  const posinset = new Map();
122
122
  let noGroup = [];
@@ -295,7 +295,7 @@ function MenuFC(props, ref) {
295
295
  else {
296
296
  dataRef.current.updatePosition.set(itemId, fn);
297
297
  }
298
- }, namespace: namespace, styled: styled, menuRef: menuRef, id: id, level: level, space: space, step: step, icon: itemIcon, list: children && getNodes(children, mode === 'vertical' ? level + 1 : 0, nextSubParents), popupState: popupState === null || popupState === void 0 ? void 0 : popupState.visible, trigger: expandTrigger !== null && expandTrigger !== void 0 ? expandTrigger : (mode === 'vertical' ? 'click' : 'hover'),
298
+ }, namespace: namespace, styled: styled, id: id, level: level, space: space, step: step, icon: itemIcon, list: children && getNodes(children, mode === 'vertical' ? level + 1 : 0, nextSubParents), popupState: popupState === null || popupState === void 0 ? void 0 : popupState.visible, trigger: expandTrigger !== null && expandTrigger !== void 0 ? expandTrigger : (mode === 'vertical' ? 'click' : 'hover'),
299
299
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
300
300
  posinset: posinset.get(itemId), mode: mode, inNav: inNav, active: (mode === 'vertical' ? !isExpand : isUndefined(popupState)) && actives.includes(itemId), includeActive: actives.includes(itemId), expand: isExpand, empty: isEmpty, focus: focusVisible && isFocus, disabled: itemDisabled, onVisibleChange: (visible) => {
301
301
  if (visible) {
@@ -322,7 +322,7 @@ function MenuFC(props, ref) {
322
322
  });
323
323
  };
324
324
  return getNodes(list, 0, [], true);
325
- };
325
+ })();
326
326
  useImperativeHandle(ref, () => ({
327
327
  updatePosition: () => {
328
328
  for (const fn of dataRef.current.updatePosition.values()) {
@@ -380,7 +380,7 @@ function MenuFC(props, ref) {
380
380
  var _a;
381
381
  (_a = restProps.onMouseUp) === null || _a === void 0 ? void 0 : _a.call(restProps, e);
382
382
  preventBlur(e);
383
- }, children: nodes(menuRef) })));
383
+ }, children: nodes })));
384
384
  } }));
385
385
  }
386
386
  export const Menu = forwardRef(MenuFC);
@@ -6,7 +6,6 @@ interface MenuSubProps {
6
6
  children: React.ReactNode;
7
7
  namespace: string;
8
8
  styled: Styled<typeof CLASSES>;
9
- menuRef: React.RefObject<HTMLElement>;
10
9
  id: string;
11
10
  level: number;
12
11
  space: number;
@@ -2,15 +2,16 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
2
2
  import { useEventCallback } from '@laser-ui/hooks';
3
3
  import { checkNodeExist } from '@laser-ui/utils';
4
4
  import { isUndefined } from 'lodash';
5
- import { cloneElement, forwardRef, useImperativeHandle, useRef, useState } from 'react';
6
- import { useMaxIndex, useTranslation } from '../../hooks';
5
+ import { cloneElement, forwardRef, useImperativeHandle, useRef } from 'react';
6
+ import { useJSS, useMaxIndex, useTranslation } from '../../hooks';
7
7
  import { Popup } from '../../internal/popup';
8
8
  import { Portal } from '../../internal/portal';
9
9
  import { CollapseTransition, Transition } from '../../internal/transition';
10
10
  import { getHorizontalSidePosition, getVerticalSidePosition, mergeCS } from '../../utils';
11
11
  import { TTANSITION_DURING_BASE, TTANSITION_DURING_POPUP, WINDOW_SPACE } from '../../vars';
12
12
  export const MenuSub = forwardRef((props, ref) => {
13
- const { children, namespace, styled, menuRef, id, level, space, step, icon, list, popupState, trigger, posinset, mode, inNav, active, includeActive, expand, empty, focus, disabled, onVisibleChange, onClick, } = props;
13
+ const { children, namespace, styled, id, level, space, step, icon, list, popupState, trigger, posinset, mode, inNav, active, includeActive, expand, empty, focus, disabled, onVisibleChange, onClick, } = props;
14
+ const sheet = useJSS();
14
15
  const triggerRef = useRef(null);
15
16
  const popupRef = useRef(null);
16
17
  const dataRef = useRef({});
@@ -18,11 +19,7 @@ export const MenuSub = forwardRef((props, ref) => {
18
19
  const visible = !isUndefined(popupState);
19
20
  const inHorizontalNav = mode === 'horizontal' && inNav;
20
21
  const iconMode = mode === 'icon' && inNav;
21
- const [popupPositionStyle, setPopupPositionStyle] = useState({
22
- top: '-200vh',
23
- left: '-200vw',
24
- });
25
- const [transformOrigin, setTransformOrigin] = useState();
22
+ const transformOrigin = useRef();
26
23
  const updatePosition = useEventCallback(() => {
27
24
  if (visible && popupRef.current && triggerRef.current) {
28
25
  const height = popupRef.current.offsetHeight;
@@ -30,7 +27,7 @@ export const MenuSub = forwardRef((props, ref) => {
30
27
  if (inHorizontalNav) {
31
28
  width = triggerRef.current.offsetWidth - 32;
32
29
  }
33
- const { top, left, transformOrigin } = inHorizontalNav
30
+ const position = inHorizontalNav
34
31
  ? getVerticalSidePosition(triggerRef.current, { width, height }, {
35
32
  placement: 'bottom',
36
33
  gap: 12,
@@ -41,12 +38,16 @@ export const MenuSub = forwardRef((props, ref) => {
41
38
  gap: inNav ? 10 : 14,
42
39
  inWindow: WINDOW_SPACE,
43
40
  });
44
- setPopupPositionStyle({
45
- top,
46
- left,
41
+ transformOrigin.current = position.transformOrigin;
42
+ if (sheet.classes.position) {
43
+ popupRef.current.classList.toggle(sheet.classes.position, false);
44
+ }
45
+ sheet.replaceRule('position', {
46
+ top: position.top,
47
+ left: position.left,
47
48
  width: inHorizontalNav ? width : undefined,
48
49
  });
49
- setTransformOrigin(transformOrigin);
50
+ popupRef.current.classList.toggle(sheet.classes.position, true);
50
51
  }
51
52
  });
52
53
  const maxZIndex = useMaxIndex(visible);
@@ -70,7 +71,15 @@ export const MenuSub = forwardRef((props, ref) => {
70
71
  }), { children: [_jsx("div", Object.assign({}, styled('menu__indicator-track', { 'menu__indicator-track--hidden': level === 0 }))), _jsx("div", Object.assign({}, styled('menu__indicator-thumb')))] })), checkNodeExist(icon) && _jsx("div", Object.assign({}, styled('menu__item-icon'), { children: icon })), _jsx("div", Object.assign({}, styled('menu__item-content'), { children: children })), !inHorizontalNav && (_jsxs("div", Object.assign({}, styled('menu__sub-arrow', {
71
72
  'menu__sub-arrow--horizontal': mode !== 'vertical' && !inHorizontalNav,
72
73
  'menu__sub-arrow.is-expand': mode === 'vertical' && expand,
73
- }), { "aria-hidden": true, children: [_jsx("div", {}), _jsx("div", {})] })))] }))), mode !== 'vertical' && (_jsx(Portal, { selector: () => menuRef.current, children: _jsx(Transition, { enter: visible, during: TTANSITION_DURING_POPUP, afterRender: updatePosition, children: (state) => {
74
+ }), { "aria-hidden": true, children: [_jsx("div", {}), _jsx("div", {})] })))] }))), mode !== 'vertical' && (_jsx(Portal, { selector: () => {
75
+ let el = document.getElementById(`${namespace}-menu-root`);
76
+ if (!el) {
77
+ el = document.createElement('div');
78
+ el.id = `${namespace}-menu-root`;
79
+ document.body.appendChild(el);
80
+ }
81
+ return el;
82
+ }, children: _jsx(Transition, { enter: visible, during: TTANSITION_DURING_POPUP, afterRender: updatePosition, children: (state) => {
74
83
  let transitionStyle = {};
75
84
  switch (state) {
76
85
  case 'enter':
@@ -79,7 +88,7 @@ export const MenuSub = forwardRef((props, ref) => {
79
88
  case 'entering':
80
89
  transitionStyle = {
81
90
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
82
- transformOrigin,
91
+ transformOrigin: transformOrigin.current,
83
92
  };
84
93
  break;
85
94
  case 'leaving':
@@ -87,7 +96,7 @@ export const MenuSub = forwardRef((props, ref) => {
87
96
  transform: inHorizontalNav ? 'scaleY(0.7)' : 'scale(0)',
88
97
  opacity: 0,
89
98
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
90
- transformOrigin,
99
+ transformOrigin: transformOrigin.current,
91
100
  };
92
101
  break;
93
102
  case 'leaved':
@@ -97,7 +106,7 @@ export const MenuSub = forwardRef((props, ref) => {
97
106
  break;
98
107
  }
99
108
  return renderPopup(_jsx("div", Object.assign({}, mergeCS(styled('menu-popup'), {
100
- style: Object.assign(Object.assign({ minWidth: inHorizontalNav ? undefined : 160, zIndex: `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})` }, popupPositionStyle), transitionStyle),
109
+ style: Object.assign({ minWidth: inHorizontalNav ? undefined : 160, zIndex: `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})` }, transitionStyle),
101
110
  }), { ref: popupRef, children: _jsx("ul", Object.assign({}, styled('menu__sub-list'), { role: "menu", "aria-labelledby": id, children: empty ? (_jsx("div", Object.assign({}, mergeCS(styled('menu__empty'), { style: { paddingLeft: space + level * step } }), { children: t('No Data') }))) : (list) })) })));
102
111
  } }) }))] })) }), _jsx(CollapseTransition, { originalSize: {
103
112
  height: 'auto',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laser-ui/components",
3
- "version": "0.0.5",
3
+ "version": "0.1.1",
4
4
  "description": "React components.",
5
5
  "keywords": [
6
6
  "ui",
@@ -23,12 +23,14 @@
23
23
  "sideEffects": false,
24
24
  "type": "module",
25
25
  "main": "./index.js",
26
- "module": "./index.js",
26
+ "module": "./src/index.js",
27
27
  "types": "./index.d.ts",
28
28
  "dependencies": {
29
- "@laser-ui/hooks": "0.0.5",
30
- "@laser-ui/utils": "0.0.5",
31
- "@material-design-icons/svg": "^0.14.9",
29
+ "@laser-ui/hooks": "0.1.1",
30
+ "@laser-ui/utils": "0.1.1",
31
+ "@material-design-icons/svg": "^0.14.12",
32
+ "jss": "^10.10.0",
33
+ "jss-preset-default": "^10.10.0",
32
34
  "lodash": "^4.17.21",
33
35
  "rcl-store": "^2.1.0",
34
36
  "rxjs": "^7.8.1"
@@ -43,5 +45,5 @@
43
45
  "access": "public",
44
46
  "directory": "../../dist/libs/components"
45
47
  },
46
- "gitHead": "224e60913f28d29e6b7f6a62df7d4d4b345219ea"
48
+ "gitHead": "701d67d95868809a4cbff486b04d1a685e9d66ea"
47
49
  }
@@ -2,11 +2,11 @@ import { __rest } from "tslib";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useEventCallback, useRefExtra } from '@laser-ui/hooks';
4
4
  import { isFunction, isString, isUndefined } from 'lodash';
5
- import { cloneElement, forwardRef, useId, useImperativeHandle, useRef, useState } from 'react';
5
+ import { cloneElement, forwardRef, useId, useImperativeHandle, useRef } from 'react';
6
6
  import { PopoverFooter } from './PopoverFooter';
7
7
  import { PopoverHeader } from './PopoverHeader';
8
8
  import { CLASSES, TTANSITION_DURING } from './vars';
9
- import { useComponentProps, useControlled, useLockScroll, useMaxIndex, useNamespace, useStyled } from '../hooks';
9
+ import { useComponentProps, useControlled, useJSS, useLockScroll, useMaxIndex, useNamespace, useStyled } from '../hooks';
10
10
  import { Popup } from '../internal/popup';
11
11
  import { Portal } from '../internal/portal';
12
12
  import { Transition } from '../internal/transition';
@@ -16,6 +16,7 @@ function PopoverFC(props, ref) {
16
16
  const trigger = modal ? 'click' : triggerProp;
17
17
  const namespace = useNamespace();
18
18
  const styled = useStyled(CLASSES, { popover: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.popover }, styleOverrides);
19
+ const sheet = useJSS();
19
20
  const uniqueId = useId();
20
21
  let triggerId;
21
22
  const titleId = `${namespace}-popover-title-${uniqueId}`;
@@ -30,27 +31,29 @@ function PopoverFC(props, ref) {
30
31
  const [visible, changeVisible] = useControlled(defaultVisible !== null && defaultVisible !== void 0 ? defaultVisible : false, visibleProp, onVisibleChange);
31
32
  const maxZIndex = useMaxIndex(visible);
32
33
  const zIndex = !isUndefined(zIndexProp) ? zIndexProp : `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
33
- const [popupPositionStyle, setPopupPositionStyle] = useState({
34
- top: '-200vh',
35
- left: '-200vw',
36
- });
37
- const [transformOrigin, setTransformOrigin] = useState();
38
- const [placement, setPlacement] = useState(placementProp);
34
+ const transformOrigin = useRef();
35
+ const placement = useRef(placementProp);
39
36
  const updatePosition = useEventCallback(() => {
40
- if (visible && triggerRef.current && popupRef.current) {
37
+ if (visible && triggerRef.current && popoverRef.current && popupRef.current) {
41
38
  const position = getPopupPosition(triggerRef.current, { width: popupRef.current.offsetWidth, height: popupRef.current.offsetHeight }, {
42
39
  placement: placementProp,
43
- placementFallback: placement,
40
+ placementFallback: placement.current,
44
41
  placementFixed,
45
42
  gap,
46
43
  inWindow,
47
44
  });
48
- setPopupPositionStyle({
45
+ transformOrigin.current = position.transformOrigin;
46
+ popoverRef.current.classList.toggle(`${namespace}-popover--${placement.current}`, false);
47
+ placement.current = position.placement;
48
+ popoverRef.current.classList.toggle(`${namespace}-popover--${placement.current}`, true);
49
+ if (sheet.classes.position) {
50
+ popupRef.current.classList.toggle(sheet.classes.position, false);
51
+ }
52
+ sheet.replaceRule('position', {
49
53
  top: position.top,
50
54
  left: position.left,
51
55
  });
52
- setTransformOrigin(position.transformOrigin);
53
- setPlacement(position.placement);
56
+ popupRef.current.classList.toggle(sheet.classes.position, true);
54
57
  }
55
58
  });
56
59
  useLockScroll(modal && visible);
@@ -125,7 +128,7 @@ function PopoverFC(props, ref) {
125
128
  case 'entering':
126
129
  transitionStyle = {
127
130
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING.enter}ms ease-out`).join(', '),
128
- transformOrigin,
131
+ transformOrigin: transformOrigin.current,
129
132
  };
130
133
  break;
131
134
  case 'leaving':
@@ -133,13 +136,13 @@ function PopoverFC(props, ref) {
133
136
  transform: 'scale(0.3)',
134
137
  opacity: 0,
135
138
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING.leave}ms ease-in`).join(', '),
136
- transformOrigin,
139
+ transformOrigin: transformOrigin.current,
137
140
  };
138
141
  break;
139
142
  default:
140
143
  break;
141
144
  }
142
- return (_jsxs("div", Object.assign({}, restProps, mergeCS(styled('popover', `popover--${placement}`), {
145
+ return (_jsxs("div", Object.assign({}, restProps, mergeCS(styled('popover'), {
143
146
  className: restProps.className,
144
147
  style: Object.assign(Object.assign({}, restProps.style), { zIndex, display: state === 'leaved' ? 'none' : undefined }),
145
148
  }), { ref: popoverRef, tabIndex: -1, role: ((_a = restProps.role) !== null && _a !== void 0 ? _a : modal) ? 'alertdialog' : 'dialog', "aria-modal": modal, "aria-labelledby": headerNode ? titleId : undefined, "aria-describedby": bodyId, onKeyDown: (e) => {
@@ -158,7 +161,7 @@ function PopoverFC(props, ref) {
158
161
  }, children: [modal && (_jsx("div", Object.assign({}, styled('popover__mask'), { onClick: () => {
159
162
  changeVisible(false);
160
163
  } }))), renderPopup(_jsxs("div", Object.assign({ ref: popupRef }, mergeCS(styled('popover__content'), {
161
- style: Object.assign(Object.assign({}, popupPositionStyle), transitionStyle),
164
+ style: transitionStyle,
162
165
  }), { children: [arrow && _jsx("div", Object.assign({}, styled('popover__arrow'))), headerNode, _jsx("div", Object.assign({}, styled('popover__body'), { id: bodyId, children: content })), footer &&
163
166
  cloneElement(footer, {
164
167
  _onClose: () => {
package/select/Select.js CHANGED
@@ -14,7 +14,7 @@ import { CLASSES, IS_CREATED } from './vars';
14
14
  import { Checkbox } from '../checkbox';
15
15
  import { Dropdown } from '../dropdown';
16
16
  import { Empty } from '../empty';
17
- import { useComponentProps, useControlled, useDesign, useFocusVisible, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
17
+ import { useComponentProps, useControlled, useDesign, useFocusVisible, useJSS, useLayout, useListenGlobalScrolling, useMaxIndex, useNamespace, useScopedProps, useStyled, useTranslation, } from '../hooks';
18
18
  import { Icon } from '../icon';
19
19
  import { CircularProgress } from '../internal/circular-progress';
20
20
  import { Portal } from '../internal/portal';
@@ -28,6 +28,7 @@ function SelectFC(props, ref) {
28
28
  const _a = useComponentProps('Select', props), { styleOverrides, styleProvider, formControl, list: listProp, model, defaultModel, visible: visibleProp, defaultVisible, placeholder, multiple = false, searchable = false, searchValue: searchValueProp, defaultSearchValue, clearable: clearableProp = false, loading = false, size: sizeProp, disabled: disabledProp = false, monospaced = true, virtual = false, escClosable = true, customItem, customSelected, customSearch, createItem, inputRef: inputRefProp, inputRender, onModelChange, onVisibleChange, onSearch, onClear, onCreateItem, onScrollBottom, afterVisibleChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "list", "model", "defaultModel", "visible", "defaultVisible", "placeholder", "multiple", "searchable", "searchValue", "defaultSearchValue", "clearable", "loading", "size", "disabled", "monospaced", "virtual", "escClosable", "customItem", "customSelected", "customSearch", "createItem", "inputRef", "inputRender", "onModelChange", "onVisibleChange", "onSearch", "onClear", "onCreateItem", "onScrollBottom", "afterVisibleChange"]);
29
29
  const namespace = useNamespace();
30
30
  const styled = useStyled(CLASSES, { select: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.select, 'select-popup': styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider['select-popup'] }, styleOverrides);
31
+ const sheet = useJSS();
31
32
  const { t } = useTranslation();
32
33
  const uniqueId = useId();
33
34
  const listId = `${namespace}-select-list-${uniqueId}`;
@@ -171,11 +172,7 @@ function SelectFC(props, ref) {
171
172
  };
172
173
  const maxZIndex = useMaxIndex(visible);
173
174
  const zIndex = `calc(var(--${namespace}-zindex-fixed) + ${maxZIndex})`;
174
- const [transformOrigin, setTransformOrigin] = useState();
175
- const [popupPositionStyle, setPopupPositionStyle] = useState({
176
- top: '-200vh',
177
- left: '-200vw',
178
- });
175
+ const transformOrigin = useRef();
179
176
  const updatePosition = useEventCallback(() => {
180
177
  if (visible && boxRef.current && popupRef.current) {
181
178
  if (monospaced) {
@@ -185,12 +182,16 @@ function SelectFC(props, ref) {
185
182
  placement: 'bottom',
186
183
  inWindow: WINDOW_SPACE,
187
184
  });
188
- setTransformOrigin(position.transformOrigin);
189
- setPopupPositionStyle({
185
+ transformOrigin.current = position.transformOrigin;
186
+ if (sheet.classes.position) {
187
+ popupRef.current.classList.toggle(sheet.classes.position, false);
188
+ }
189
+ sheet.replaceRule('position', {
190
190
  top: position.top,
191
191
  left: position.left,
192
192
  width,
193
193
  });
194
+ popupRef.current.classList.toggle(sheet.classes.position, true);
194
195
  }
195
196
  else {
196
197
  const boxWidth = boxRef.current.offsetWidth;
@@ -201,13 +202,17 @@ function SelectFC(props, ref) {
201
202
  placement: 'bottom-left',
202
203
  inWindow: WINDOW_SPACE,
203
204
  });
204
- setTransformOrigin(position.transformOrigin);
205
- setPopupPositionStyle({
205
+ transformOrigin.current = position.transformOrigin;
206
+ if (sheet.classes.position) {
207
+ popupRef.current.classList.toggle(sheet.classes.position, false);
208
+ }
209
+ sheet.replaceRule('position', {
206
210
  top: position.top,
207
211
  left: position.left,
208
212
  minWidth: Math.min(boxWidth, maxWidth),
209
213
  maxWidth,
210
214
  });
215
+ popupRef.current.classList.toggle(sheet.classes.position, true);
211
216
  }
212
217
  }
213
218
  });
@@ -468,7 +473,7 @@ function SelectFC(props, ref) {
468
473
  case 'entering':
469
474
  transitionStyle = {
470
475
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-out`).join(', '),
471
- transformOrigin,
476
+ transformOrigin: transformOrigin.current,
472
477
  };
473
478
  break;
474
479
  case 'leaving':
@@ -476,7 +481,7 @@ function SelectFC(props, ref) {
476
481
  transform: 'scaleY(0.7)',
477
482
  opacity: 0,
478
483
  transition: ['transform', 'opacity'].map((attr) => `${attr} ${TTANSITION_DURING_POPUP}ms ease-in`).join(', '),
479
- transformOrigin,
484
+ transformOrigin: transformOrigin.current,
480
485
  };
481
486
  break;
482
487
  case 'leaved':
@@ -486,7 +491,7 @@ function SelectFC(props, ref) {
486
491
  break;
487
492
  }
488
493
  return (_jsxs("div", Object.assign({}, mergeCS(styled('select-popup'), {
489
- style: Object.assign(Object.assign({ zIndex }, popupPositionStyle), transitionStyle),
494
+ style: Object.assign({ zIndex }, transitionStyle),
490
495
  }), { ref: popupRef, onMouseDown: (e) => {
491
496
  preventBlur(e);
492
497
  }, onMouseUp: (e) => {
@@ -4,11 +4,12 @@ import { useForkRef } from '@laser-ui/hooks';
4
4
  import { isFunction, isNumber, isUndefined } from 'lodash';
5
5
  import { forwardRef, useEffect, useRef } from 'react';
6
6
  import { CLASSES } from './vars';
7
- import { useComponentProps, useControlled, useDesign, useScopedProps, useStyled } from '../hooks';
7
+ import { useComponentProps, useControlled, useDesign, useJSS, useScopedProps, useStyled } from '../hooks';
8
8
  import { mergeCS } from '../utils';
9
9
  export const Textarea = forwardRef((props, ref) => {
10
10
  const _a = useComponentProps('Textarea', props), { styleOverrides, styleProvider, formControl, model, defaultModel, autoRows = false, resizable = true, showCount = false, size: sizeProp, onModelChange } = _a, restProps = __rest(_a, ["styleOverrides", "styleProvider", "formControl", "model", "defaultModel", "autoRows", "resizable", "showCount", "size", "onModelChange"]);
11
11
  const styled = useStyled(CLASSES, { textarea: styleProvider === null || styleProvider === void 0 ? void 0 : styleProvider.textarea }, styleOverrides);
12
+ const sheet = useJSS();
12
13
  const textareaRef = useRef(null);
13
14
  const combineTextareaRef = useForkRef(textareaRef, ref);
14
15
  const [value, changeValue] = useControlled(defaultModel !== null && defaultModel !== void 0 ? defaultModel : '', model, onModelChange, undefined, formControl === null || formControl === void 0 ? void 0 : formControl.control);
@@ -50,10 +51,16 @@ export const Textarea = forwardRef((props, ref) => {
50
51
  }
51
52
  }
52
53
  }
53
- textareaRef.current.style.height = isUndefined(height) ? '' : height + outerSize + 'px';
54
- textareaRef.current.style.overflow = isUndefined(overflow) ? '' : 'hidden';
55
- textareaRef.current.style.minHeight = isUndefined(minHeight) ? '' : minHeight + outerSize + 'px';
56
- textareaRef.current.style.maxHeight = isUndefined(maxHeight) ? '' : maxHeight + outerSize + 'px';
54
+ if (sheet.classes.rows) {
55
+ textareaRef.current.classList.toggle(sheet.classes.rows, false);
56
+ }
57
+ sheet.replaceRule('rows', {
58
+ height: isUndefined(height) ? undefined : height + outerSize,
59
+ overflow: isUndefined(overflow) ? undefined : 'hidden',
60
+ minHeight: isUndefined(minHeight) ? undefined : minHeight + outerSize,
61
+ maxHeight: isUndefined(maxHeight) ? undefined : maxHeight + outerSize,
62
+ });
63
+ textareaRef.current.classList.toggle(sheet.classes.rows, true);
57
64
  }
58
65
  });
59
66
  const designProps = useDesign({ form: formControl });