@homecode/ui 5.13.0 → 5.15.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.
package/dist/esm/index.js CHANGED
@@ -20,6 +20,8 @@ export { Draggable } from './src/components/Draggable/Draggable.js';
20
20
  export { DropZone } from './src/components/DropZone/DropZone.js';
21
21
  export { Expand } from './src/components/Expand/Expand.js';
22
22
  export { Flex } from './src/components/Flex/Flex.js';
23
+ export { FoldedLine } from './src/components/FoldedLine/FoldedLine.js';
24
+ export { FoldedLineAction, FoldedLineActionsProvider, useFoldedLineActionsRegister } from './src/components/FoldedLine/FoldedLineActionsContext.js';
23
25
  export { Form } from './src/components/Form/Form.js';
24
26
  export { FormattedText } from './src/components/FormattedText/FormattedText.js';
25
27
  export { Gap } from './src/components/Gap/Gap.js';
@@ -49,10 +49,12 @@ import '../../tools/queryParams.js';
49
49
  import '../Draggable/Draggable.styl.js';
50
50
  import '../DropZone/DropZone.styl.js';
51
51
  import '../Flex/Flex.styl.js';
52
+ import '../Gap/Gap.styl.js';
53
+ import '../FoldedLine/FoldedLine.styl.js';
54
+ import '../FoldedLine/FoldedLineActionsContext.js';
52
55
  import '../Form/Form.styl.js';
53
56
  import '../Form/Validator.js';
54
57
  import '../Form/SubmitButtons/SubmitButtons.styl.js';
55
- import '../Gap/Gap.styl.js';
56
58
  import '../ProgressCircular/ProgressCircular.styl.js';
57
59
  import '../Slider/Slider.styl.js';
58
60
  import '../VideoPlayer/VideoPlayer.styl.js';
@@ -1,9 +1,9 @@
1
1
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
2
2
  import cn from 'classnames';
3
3
  import { useState, useRef, useId, useEffect } from 'react';
4
- import { createPortal } from 'react-dom';
5
4
  import { Card, CardHeader, CardContent, CardFooter } from '../Card/Card.js';
6
5
  import { Icon } from '../Icon/Icon.js';
6
+ import { Portal } from '../Portal/Portal.js';
7
7
  import { isBrowser } from '../../tools/env.js';
8
8
  import S from './Dialogue.styl.js';
9
9
 
@@ -99,11 +99,7 @@ function Dialogue({ open, onOpenChange, disabled, trigger, title, subtitle, icon
99
99
  ? `min(${String(maxHeight)}, calc(100% - var(--p-5)))`
100
100
  : undefined,
101
101
  }, children: [(title || subtitle || icon) && (jsx(CardHeader, { icon: icon, title: title, description: subtitle, titleId: titleId, descriptionId: descriptionId })), jsx("button", { className: S.dialogClose, onClick: handleCloseClick, "aria-label": "Close dialog", type: "button", children: jsx(Icon, { type: "close", size: "m" }) }), content && (jsx(CardContent, { className: contentClassName, noScroll: noScroll, autoScrollBottom: autoScrollBottom, children: content })), footer && (jsx(CardFooter, { className: FOOTER_ALIGN_CLASS[footerAlignment], children: footer }))] })] }));
102
- return (jsxs(Fragment, { children: [trigger && jsx("div", { onClick: onTriggerClick, children: trigger }), open &&
103
- !disabled &&
104
- isMounted &&
105
- isBrowser &&
106
- createPortal(dialogueContent, document.body)] }));
102
+ return (jsxs(Fragment, { children: [trigger && jsx("div", { onClick: onTriggerClick, children: trigger }), open && !disabled && isMounted && isBrowser && (jsx(Portal, { children: dialogueContent }))] }));
107
103
  }
108
104
 
109
105
  export { Dialogue, S as DialogueStyles };
@@ -1,6 +1,6 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = ".Dialogue_dialogOverlay__jjBIa{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:var(--decent-color-alpha-900);inset:0;opacity:0;position:fixed;transition:opacity .2s ease-out;z-index:50}.Dialogue_dialogOverlay__jjBIa.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_fadeIn__RSEB2;animation-timing-function:ease-out;opacity:1}.Dialogue_dialogContent__-Lxde{border-radius:var(--border-radius-l);box-shadow:0 10px 20px rgba(0,0,0,.3),0 0 0 2px var(--decent-color-alpha-800);display:flex;flex-direction:column;left:50%;max-height:calc(100% - var(--p-5));opacity:0;position:fixed;top:50%;transform:translateX(-50%) translateY(-50%) scale(.95);transition:opacity .2s ease-out,transform .2s ease-out;width:-moz-fit-content;width:fit-content;z-index:50}.Dialogue_dialogContent__-Lxde.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueIn__M0tLL;animation-timing-function:ease-out;opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}.Dialogue_dialogContent__-Lxde.Dialogue_isClosed__lHYyZ{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueOut__6bLTY;animation-timing-function:ease-in;opacity:0;pointer-events:none;transform:translateX(-50%) translateY(-50%) scale(.95)}@media (max-width:700px){.Dialogue_dialogContent__-Lxde{max-width:calc(100% - var(--p-5));width:calc(100% - var(--p-5))}}.Dialogue_dialogContent__-Lxde:has(.Dialogue_dialogClose__5q12n) [data-slot=card-header]{padding-right:calc(2rem + var(--p-3))}.Dialogue_size-default__X1sdB{max-width:40rem}.Dialogue_size-login__GyixB{max-width:24rem}.Dialogue_size-wide__HQbiX{max-width:calc(100% - var(--p-5))}@media (min-width:700px){.Dialogue_size-wide__HQbiX{max-width:80rem}}.Dialogue_dialogClose__5q12n{align-items:center;background-color:transparent;border:none;border-radius:var(--border-radius-s);box-shadow:inset 0 0 0 2px none;color:var(--accent-color);cursor:pointer;display:flex;height:2rem;justify-content:center;opacity:.3;position:absolute;right:var(--p-3);top:var(--p-3);transform-origin:center;transition:opacity .2s ease,transform .2s ease;width:2rem;z-index:10}.Dialogue_dialogClose__5q12n:focus-visible,.Dialogue_dialogClose__5q12n:hover{opacity:1;transform:scale(1.1)}.Dialogue_dialogClose__5q12n:focus-visible{box-shadow:0 0 0 2px var(--active-color)}.Dialogue_dialogClose__5q12n:disabled{pointer-events:none}.Dialogue_footerAlignLeft__xQUD8{justify-content:flex-start}.Dialogue_footerAlignCenter__yq9Mu{justify-content:center}.Dialogue_footerAlignRight__Yo7hG{justify-content:flex-end}@keyframes Dialogue_fadeIn__RSEB2{0%{opacity:0}to{opacity:1}}@keyframes Dialogue_dialogueIn__M0tLL{0%{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}to{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}}@keyframes Dialogue_dialogueOut__6bLTY{0%{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}to{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}}";
3
+ var css_248z = ".Dialogue_dialogOverlay__jjBIa{-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);background-color:var(--decent-color-alpha-900);inset:0;opacity:0;position:fixed;transition:opacity .2s ease-out;z-index:10}.Dialogue_dialogOverlay__jjBIa.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_fadeIn__RSEB2;animation-timing-function:ease-out;opacity:1}.Dialogue_dialogContent__-Lxde{border-radius:var(--border-radius-l);box-shadow:0 10px 20px rgba(0,0,0,.3),0 0 0 2px var(--decent-color-alpha-800);display:flex;flex-direction:column;left:50%;max-height:calc(100% - var(--p-5));opacity:0;position:fixed;top:50%;transform:translateX(-50%) translateY(-50%) scale(.95);transition:opacity .2s ease-out,transform .2s ease-out;width:-moz-fit-content;width:fit-content;z-index:10}.Dialogue_dialogContent__-Lxde.Dialogue_isOpen__gISMb{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueIn__M0tLL;animation-timing-function:ease-out;opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}.Dialogue_dialogContent__-Lxde.Dialogue_isClosed__lHYyZ{animation-duration:.2s;animation-fill-mode:forwards;animation-name:Dialogue_dialogueOut__6bLTY;animation-timing-function:ease-in;opacity:0;pointer-events:none;transform:translateX(-50%) translateY(-50%) scale(.95)}@media (max-width:700px){.Dialogue_dialogContent__-Lxde{max-width:calc(100% - var(--p-5));width:calc(100% - var(--p-5))}}.Dialogue_dialogContent__-Lxde:has(.Dialogue_dialogClose__5q12n) [data-slot=card-header]{padding-right:calc(2rem + var(--p-3))}.Dialogue_size-default__X1sdB{max-width:40rem}.Dialogue_size-login__GyixB{max-width:24rem}.Dialogue_size-wide__HQbiX{max-width:calc(100% - var(--p-5))}@media (min-width:700px){.Dialogue_size-wide__HQbiX{max-width:80rem}}.Dialogue_dialogClose__5q12n{align-items:center;background-color:transparent;border:none;border-radius:var(--border-radius-s);box-shadow:inset 0 0 0 2px none;color:var(--accent-color);cursor:pointer;display:flex;height:2rem;justify-content:center;opacity:.3;position:absolute;right:var(--p-3);top:var(--p-3);transform-origin:center;transition:opacity .2s ease,transform .2s ease;width:2rem;z-index:10}.Dialogue_dialogClose__5q12n:focus-visible,.Dialogue_dialogClose__5q12n:hover{opacity:1;transform:scale(1.1)}.Dialogue_dialogClose__5q12n:focus-visible{box-shadow:0 0 0 2px var(--active-color)}.Dialogue_dialogClose__5q12n:disabled{pointer-events:none}.Dialogue_footerAlignLeft__xQUD8{justify-content:flex-start}.Dialogue_footerAlignCenter__yq9Mu{justify-content:center}.Dialogue_footerAlignRight__Yo7hG{justify-content:flex-end}@keyframes Dialogue_fadeIn__RSEB2{0%{opacity:0}to{opacity:1}}@keyframes Dialogue_dialogueIn__M0tLL{0%{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}to{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}}@keyframes Dialogue_dialogueOut__6bLTY{0%{opacity:1;transform:translateX(-50%) translateY(-50%) scale(1)}to{opacity:0;transform:translateX(-50%) translateY(-50%) scale(.95)}}";
4
4
  var S = {"dialogOverlay":"Dialogue_dialogOverlay__jjBIa","isOpen":"Dialogue_isOpen__gISMb","fadeIn":"Dialogue_fadeIn__RSEB2","dialogContent":"Dialogue_dialogContent__-Lxde","dialogueIn":"Dialogue_dialogueIn__M0tLL","isClosed":"Dialogue_isClosed__lHYyZ","dialogueOut":"Dialogue_dialogueOut__6bLTY","dialogClose":"Dialogue_dialogClose__5q12n","size-default":"Dialogue_size-default__X1sdB","size-login":"Dialogue_size-login__GyixB","size-wide":"Dialogue_size-wide__HQbiX","footerAlignLeft":"Dialogue_footerAlignLeft__xQUD8","footerAlignCenter":"Dialogue_footerAlignCenter__yq9Mu","footerAlignRight":"Dialogue_footerAlignRight__Yo7hG"};
5
5
  styleInject(css_248z);
6
6
 
@@ -0,0 +1,60 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import cn from 'classnames';
3
+ import { useState, useRef, useCallback, useEffect } from 'react';
4
+ import { Button } from '../Button/Button.js';
5
+ import { Gap } from '../Gap/Gap.js';
6
+ import { Icon } from '../Icon/Icon.js';
7
+ import { Scroll } from '../Scroll/Scroll.js';
8
+ import S from './FoldedLine.styl.js';
9
+ import { FoldedLineActionsProvider } from './FoldedLineActionsContext.js';
10
+
11
+ function FoldedLine({ trigger, children, defaultFolded = true, className, folded: foldedProp, onFoldedChange, onScrollInnerRef, hideFoldButton = false, showChevron = true, onScrollInner, contentScrolling = true, variant = 'default', }) {
12
+ const [uncontrolledFolded, setUncontrolledFolded] = useState(defaultFolded);
13
+ const isControlled = foldedProp !== undefined;
14
+ const isFolded = isControlled ? foldedProp : uncontrolledFolded;
15
+ const setFolded = (next) => {
16
+ if (isControlled)
17
+ onFoldedChange?.(next);
18
+ else
19
+ setUncontrolledFolded(next);
20
+ };
21
+ const [actions, setActions] = useState(new Map());
22
+ const triggerRef = useRef(null);
23
+ const isClear = variant === 'clear';
24
+ const registerAction = useCallback((id, node) => {
25
+ setActions(prev => {
26
+ const next = new Map(prev);
27
+ if (node == null)
28
+ next.delete(id);
29
+ else
30
+ next.set(id, node);
31
+ return next;
32
+ });
33
+ }, []);
34
+ useEffect(() => {
35
+ if (isFolded)
36
+ setActions(new Map());
37
+ }, [isFolded]);
38
+ const isInteractiveTarget = (target) => {
39
+ if (!(target instanceof Element))
40
+ return false;
41
+ return Boolean(target.closest('a[href], button, [role="button"], input, textarea, select, label'));
42
+ };
43
+ const handleClick = (e) => {
44
+ if (!children || isInteractiveTarget(e.target))
45
+ return;
46
+ if (isClear || isFolded) {
47
+ setFolded(!isFolded);
48
+ return;
49
+ }
50
+ if (triggerRef.current?.contains(e.target)) {
51
+ setFolded(true);
52
+ }
53
+ };
54
+ return (jsxs("div", { className: cn(S.root, isFolded && S.folded, Boolean(children) && S.hasChildren, isClear && S.clear, className), onClick: handleClick, children: [jsxs("div", { ref: triggerRef, className: cn(Boolean(children) && S.triggerInteractive), children: [typeof trigger === 'function' ? trigger(isFolded) : trigger, jsx(Gap, {}), showChevron && jsx(Icon, { type: "chevronDown", className: S.chevron })] }), !isFolded && children && (jsx("div", { className: S.content, children: jsxs(FoldedLineActionsProvider, { registerAction: registerAction, children: [contentScrolling ? (jsx(Scroll, { y: true, size: "s", autoHide: true, className: S.scroll, innerClassName: S.scrollInner, offset: { y: { before: 4, after: 14 } }, onInnerRef: onScrollInnerRef, onScroll: onScrollInner, children: children })) : (jsx("div", { className: S.scrollInner, children: children })), jsxs("div", { className: S.actions, children: [Array.from(actions.values()), !hideFoldButton && (jsxs(Button, { size: "xs", onClick: e => {
55
+ e.stopPropagation();
56
+ setFolded(true);
57
+ }, children: [jsx(Icon, { type: "chevronUp", size: "s" }), "Fold"] }))] })] }) }))] }));
58
+ }
59
+
60
+ export { FoldedLine };
@@ -0,0 +1,7 @@
1
+ import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
+
3
+ var css_248z = ".FoldedLine_root__lhi-1{border-radius:12px;display:flex;flex-direction:column;min-height:1rem;padding-left:calc(4px + var(--p-2));position:relative;transition:.1s ease-out;transition-property:border-radius,margin,background-color}.FoldedLine_root__lhi-1:before{background:var(--accent-color);border-radius:2px;bottom:2px;content:\"\";height:calc(100% - 4px);left:6px;opacity:.1;pointer-events:none;position:absolute;top:2px;width:4px}.FoldedLine_root__lhi-1:hover:before,.FoldedLine_root__lhi-1:not(.FoldedLine_folded__6zX8d):before{opacity:.7}.FoldedLine_root__lhi-1.FoldedLine_folded__6zX8d{border-radius:0;margin:0}.FoldedLine_root__lhi-1.FoldedLine_folded__6zX8d .FoldedLine_scroll__X7T5v{height:1em}.FoldedLine_root__lhi-1.FoldedLine_hasChildren__8hCZA.FoldedLine_folded__6zX8d{cursor:pointer}.FoldedLine_root__lhi-1.FoldedLine_hasChildren__8hCZA:not(.FoldedLine_folded__6zX8d) .FoldedLine_triggerInteractive__sCLnl{border-top-left-radius:inherit;border-top-right-radius:inherit}.FoldedLine_root__lhi-1.FoldedLine_clear__t47RA{border-radius:inherit;min-height:0;padding:0}.FoldedLine_root__lhi-1.FoldedLine_clear__t47RA:before{content:none}.FoldedLine_root__lhi-1.FoldedLine_clear__t47RA.FoldedLine_hasChildren__8hCZA{cursor:pointer}.FoldedLine_root__lhi-1.FoldedLine_clear__t47RA.FoldedLine_folded__6zX8d{-webkit-line-clamp:unset;-webkit-box-orient:unset;line-clamp:none;display:flex;overflow:visible;text-overflow:clip}.FoldedLine_root__lhi-1.FoldedLine_clear__t47RA .FoldedLine_triggerInteractive__sCLnl{opacity:1}.FoldedLine_chevron__zxu20{margin-right:var(--p-2);opacity:.3;transition:transform .1s ease-out,opacity .1s ease-out}.FoldedLine_root__lhi-1:hover .FoldedLine_chevron__zxu20{opacity:1}.FoldedLine_folded__6zX8d .FoldedLine_chevron__zxu20{transform:rotate(-90deg)}.FoldedLine_lineCompleted__sEfzm:before{background:var(--active-color)}.FoldedLine_lineInProgress__VcwjJ:before{animation:FoldedLine_foldedLinePulse__y-Dle 1.4s ease-in-out infinite}.FoldedLine_triggerInteractive__sCLnl{align-items:center;cursor:pointer;display:flex;gap:var(--p-1);opacity:.8;transition:background-color .1s ease-out}.FoldedLine_triggerInteractive__sCLnl:hover{opacity:1}.FoldedLine_triggerInteractive__sCLnl:hover:before{background-color:var(--accent-color-alpha-900)}.FoldedLine_header__gyQpI{cursor:pointer;height:100%;position:absolute;transition:opacity .1s ease-out;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%;z-index:1}.FoldedLine_folded__6zX8d{-webkit-line-clamp:1;-webkit-box-orient:vertical;line-clamp:1;display:-webkit-box;overflow:hidden;text-overflow:ellipsis;transition:opacity .1s ease-out}.FoldedLine_folded__6zX8d:before{opacity:.4}.FoldedLine_folded__6zX8d .FoldedLine_scroll__X7T5v{max-height:1.5em}.FoldedLine_content__POIox{position:relative}.FoldedLine_scroll__X7T5v{max-height:50vh}.FoldedLine_scrollInner__1BGOP>div{-webkit-user-select:text;-moz-user-select:text;user-select:text}.FoldedLine_actions__SmF3b{align-items:center;bottom:0;display:flex;flex-shrink:0;flex-wrap:wrap;gap:var(--p-1);justify-content:flex-end;padding:0 var(--p-5) var(--p-3) var(--p-2);position:absolute;right:0}.FoldedLine_actions__SmF3b>button{-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}@keyframes FoldedLine_foldedLinePulse__y-Dle{0%,to{background-color:var(--accent-color-alpha-400)}50%{background-color:var(--active-color)}}";
4
+ var S = {"root":"FoldedLine_root__lhi-1","folded":"FoldedLine_folded__6zX8d","scroll":"FoldedLine_scroll__X7T5v","hasChildren":"FoldedLine_hasChildren__8hCZA","triggerInteractive":"FoldedLine_triggerInteractive__sCLnl","clear":"FoldedLine_clear__t47RA","chevron":"FoldedLine_chevron__zxu20","lineCompleted":"FoldedLine_lineCompleted__sEfzm","lineInProgress":"FoldedLine_lineInProgress__VcwjJ","foldedLinePulse":"FoldedLine_foldedLinePulse__y-Dle","header":"FoldedLine_header__gyQpI","content":"FoldedLine_content__POIox","scrollInner":"FoldedLine_scrollInner__1BGOP","actions":"FoldedLine_actions__SmF3b"};
5
+ styleInject(css_248z);
6
+
7
+ export { S as default };
@@ -0,0 +1,25 @@
1
+ import { jsx, Fragment } from 'react/jsx-runtime';
2
+ import { createContext, useContext, useId, useEffect } from 'react';
3
+
4
+ const FoldedLineActionsContext = createContext(null);
5
+ function useFoldedLineActionsRegister() {
6
+ return useContext(FoldedLineActionsContext);
7
+ }
8
+ function FoldedLineActionsProvider({ registerAction, children, }) {
9
+ return (jsx(FoldedLineActionsContext.Provider, { value: registerAction, children: children }));
10
+ }
11
+ function FoldedLineAction({ children }) {
12
+ const register = useFoldedLineActionsRegister();
13
+ const id = useId();
14
+ useEffect(() => {
15
+ if (!register)
16
+ return undefined;
17
+ register(id, children);
18
+ return () => register(id, null);
19
+ }, [register, id, children]);
20
+ if (!register)
21
+ return jsx(Fragment, { children: children });
22
+ return null;
23
+ }
24
+
25
+ export { FoldedLineAction, FoldedLineActionsProvider, useFoldedLineActionsRegister };
@@ -51,10 +51,12 @@ import '../Dialogue/Dialogue.js';
51
51
  import { Draggable } from '../Draggable/Draggable.js';
52
52
  import '../DropZone/DropZone.styl.js';
53
53
  import '../Flex/Flex.styl.js';
54
+ import '../Gap/Gap.styl.js';
55
+ import '../FoldedLine/FoldedLine.styl.js';
56
+ import '../FoldedLine/FoldedLineActionsContext.js';
54
57
  import '../Form/Form.styl.js';
55
58
  import '../Form/Validator.js';
56
59
  import '../Form/SubmitButtons/SubmitButtons.styl.js';
57
- import '../Gap/Gap.styl.js';
58
60
  import '../ProgressCircular/ProgressCircular.styl.js';
59
61
  import '../Slider/Slider.styl.js';
60
62
  import '../VideoPlayer/VideoPlayer.styl.js';
@@ -1,6 +1,7 @@
1
1
  import { jsx, Fragment } from 'react/jsx-runtime';
2
2
  import { useContext, useEffect, useMemo } from 'react';
3
3
  import { useStore } from 'justorm/react';
4
+ import { parseQueryParams } from '../../tools/queryParams.js';
4
5
  import STORE from './store.js';
5
6
  import Context from './context.js';
6
7
  import { parsePath, replaceParamsInPath } from './Router.helpers.js';
@@ -17,7 +18,9 @@ const Router = (props) => {
17
18
  const fullPath = ctx.basePath + basePath;
18
19
  useEffect(() => {
19
20
  const onPopState = () => {
20
- STORE.go(window.location.pathname, STORE.query, { replace: true });
21
+ STORE.go(window.location.pathname, parseQueryParams(), {
22
+ replace: true,
23
+ });
21
24
  };
22
25
  window.addEventListener('popstate', onPopState);
23
26
  return () => window.removeEventListener('popstate', onPopState);
@@ -1,14 +1,14 @@
1
1
  import { useState, useEffect, useCallback, createElement } from 'react';
2
2
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
- import cn from 'classnames';
4
- import { Scroll } from '../Scroll/Scroll.js';
5
3
  import { Button } from '../Button/Button.js';
6
4
  import { ButtonGroup } from '../ButtonGroup/ButtonGroup.js';
7
5
  import S from './Tabs.styl.js';
6
+ import { Scroll } from '../Scroll/Scroll.js';
7
+ import cn from 'classnames';
8
8
 
9
9
  const isId = id => ['string', 'number'].includes(typeof id);
10
10
  function Tabs(props) {
11
- const { size = 'm', className, tabsWrapperClassName, tabsClassName, contentClassName, items, hideTabsIfSingle = false, allowEmpty = false, onChange, renderAll, activeId: initialId, children, ...rest } = props;
11
+ const { size = 'm', variant = 'default', className, tabsWrapperClassName, tabsInnerClassName, tabsClassName, contentClassName, items, hideTabsIfSingle = false, allowEmpty = false, onChange, renderAll, activeId: initialId, children, ...rest } = props;
12
12
  const [activeId, setActiveId] = useState(isId(initialId) ? initialId : allowEmpty ? null : items[0].id);
13
13
  useEffect(() => {
14
14
  if (isId(initialId)) {
@@ -35,9 +35,9 @@ function Tabs(props) {
35
35
  if (renderAll || forceRender || isActive) {
36
36
  tabsContent.push(jsx("div", { className: cn(contentClassName, currContentClassName, !isActive && S.inactive), children: tabContent }, id));
37
37
  }
38
- return (createElement(Button, { ...rest, className: cn(S.tab, rest.className), size: size, key: id, onClick: e => onTabClick(e, params), checked: isActive }, label));
38
+ return (createElement(Button, { ...rest, className: cn(S.tab, isActive && S.active, rest.className), size: size, key: id, onClick: e => onTabClick(e, params), checked: isActive }, label));
39
39
  });
40
- const tabs = tabsButtons.length === 1 && hideTabsIfSingle ? null : (jsx(Scroll, { x: true, offset: { x: { before: 10, after: 10 } }, className: tabsWrapperClassName, innerClassName: cn(S.tabsScroll, S[`size-${size}`]), autoHide: true, fadeSize: size, size: size, children: jsx(ButtonGroup, { className: tabsClassName, ...rest, children: tabsButtons }) }));
40
+ const tabs = tabsButtons.length === 1 && hideTabsIfSingle ? null : (jsx(Scroll, { x: true, offset: { x: { before: 10, after: 10 } }, className: tabsWrapperClassName, innerClassName: cn(S.tabsScroll, S[`size-${size}`], tabsInnerClassName), autoHide: true, fadeSize: size, size: size, children: jsx(ButtonGroup, { className: cn(variant === 'links' && S['variant-links'], tabsClassName), ...rest, children: tabsButtons }) }));
41
41
  if (typeof children === 'function') {
42
42
  return children({
43
43
  tabs,
@@ -1,7 +1,7 @@
1
1
  import styleInject from '../../../node_modules/style-inject/dist/style-inject.es.js';
2
2
 
3
- var css_248z = "div .Tabs_inactive__H0mPh{display:none}.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-5)}.Tabs_size-xs__J0-xo.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-3)}.Tabs_size-s__bz7NO.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-4)}.Tabs_size-l__emJzX.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.2)}.Tabs_size-xl__Kqzt-.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.35)}.Tabs_tab__-oN-g{flex-shrink:0;white-space:nowrap}";
4
- var S = {"inactive":"Tabs_inactive__H0mPh","tabsScroll":"Tabs_tabsScroll__7Dj0S","size-xs":"Tabs_size-xs__J0-xo","size-s":"Tabs_size-s__bz7NO","size-l":"Tabs_size-l__emJzX","size-xl":"Tabs_size-xl__Kqzt-","tab":"Tabs_tab__-oN-g"};
3
+ var css_248z = "div .Tabs_inactive__H0mPh{display:none}.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-5)}.Tabs_size-xs__J0-xo.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-3)}.Tabs_size-s__bz7NO.Tabs_tabsScroll__7Dj0S{padding-bottom:var(--p-4)}.Tabs_size-l__emJzX.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.2)}.Tabs_size-xl__Kqzt-.Tabs_tabsScroll__7Dj0S{padding-bottom:calc(var(--p-5)*1.35)}.Tabs_tab__-oN-g{flex-shrink:0;white-space:nowrap}.Tabs_variant-links__-N1Ym>button:not(:first-child){border-radius:inherit;margin-left:0}.Tabs_variant-links__-N1Ym>button:not(:last-child){border-radius:inherit}.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g{background-color:transparent!important;box-shadow:none;padding:var(--p-3) var(--p-5)}.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g:focus,.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g:hover{background-color:transparent!important;box-shadow:0 2px 0 0 var(--active-color-alpha-100)}.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g.Tabs_active__nOA5N,.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g.Tabs_active__nOA5N:focus,.Tabs_variant-links__-N1Ym .Tabs_tab__-oN-g.Tabs_active__nOA5N:hover{background-color:transparent!important;box-shadow:0 2px 0 0 var(--active-color);color:inherit}";
4
+ var S = {"inactive":"Tabs_inactive__H0mPh","tabsScroll":"Tabs_tabsScroll__7Dj0S","size-xs":"Tabs_size-xs__J0-xo","size-s":"Tabs_size-s__bz7NO","size-l":"Tabs_size-l__emJzX","size-xl":"Tabs_size-xl__Kqzt-","tab":"Tabs_tab__-oN-g","variant-links":"Tabs_variant-links__-N1Ym","active":"Tabs_active__nOA5N"};
5
5
  styleInject(css_248z);
6
6
 
7
7
  export { S as default };
@@ -0,0 +1,3 @@
1
+ import * as T from './FoldedLine.types';
2
+ export type FoldedLineProps = T.Props;
3
+ export declare function FoldedLine({ trigger, children, defaultFolded, className, folded: foldedProp, onFoldedChange, onScrollInnerRef, hideFoldButton, showChevron, onScrollInner, contentScrolling, variant, }: FoldedLineProps): import("react").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { ReactNode, UIEvent } from 'react';
2
+ export type Props = {
3
+ trigger: ReactNode | ((isFolded: boolean) => ReactNode);
4
+ children?: ReactNode;
5
+ defaultFolded?: boolean;
6
+ className?: string;
7
+ folded?: boolean;
8
+ hideFoldButton?: boolean;
9
+ onFoldedChange?: (folded: boolean) => void;
10
+ onScrollInnerRef?: (el: HTMLDivElement | null) => void;
11
+ onScrollInner?: (e: UIEvent<HTMLDivElement>) => void;
12
+ contentScrolling?: boolean;
13
+ variant?: 'default' | 'clear';
14
+ showChevron?: boolean;
15
+ };
@@ -0,0 +1,11 @@
1
+ import { ReactNode } from 'react';
2
+ type RegisterAction = (id: string, node: ReactNode | null) => void;
3
+ export declare function useFoldedLineActionsRegister(): RegisterAction | null;
4
+ export declare function FoldedLineActionsProvider({ registerAction, children, }: {
5
+ registerAction: RegisterAction;
6
+ children: ReactNode;
7
+ }): import("react").JSX.Element;
8
+ export declare function FoldedLineAction({ children }: {
9
+ children: ReactNode;
10
+ }): import("react").JSX.Element;
11
+ export {};
@@ -0,0 +1,3 @@
1
+ export { FoldedLine } from './FoldedLine';
2
+ export type { FoldedLineProps } from './FoldedLine';
3
+ export { FoldedLineAction, FoldedLineActionsProvider, useFoldedLineActionsRegister, } from './FoldedLineActionsContext';
@@ -1,6 +1,6 @@
1
- import { Size } from 'uilib/types';
2
1
  import { ButtonProps } from '../Button/Button';
3
2
  import { ReactNode } from 'react';
3
+ import { Size } from 'uilib/types';
4
4
  type ID = string | number;
5
5
  export type Item = Omit<ButtonProps, 'children'> & {
6
6
  id: ID;
@@ -17,8 +17,10 @@ export type RenderProps = {
17
17
  };
18
18
  export type Props = {
19
19
  size?: Size;
20
+ variant?: 'default' | 'links';
20
21
  className?: string;
21
22
  tabsWrapperClassName?: string;
23
+ tabsInnerClassName?: string;
22
24
  tabsClassName?: string;
23
25
  contentClassName?: string;
24
26
  items: Item[];
@@ -16,6 +16,7 @@ export * from './Draggable/Draggable';
16
16
  export * from './DropZone/DropZone';
17
17
  export * from './Expand/Expand';
18
18
  export * from './Flex/Flex';
19
+ export * from './FoldedLine';
19
20
  export * from './Form/Form';
20
21
  export * from './FormattedText';
21
22
  export * from './Gap/Gap';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homecode/ui",
3
- "version": "5.13.0",
3
+ "version": "5.15.0",
4
4
  "description": "React UI components library",
5
5
  "scripts": {
6
6
  "tests": "jest",