@shmidko61/lc-ui-kit 0.12.0 → 0.13.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.
Files changed (52) hide show
  1. package/README.md +11 -0
  2. package/dist/alert/alert.d.ts +5 -0
  3. package/dist/alert/helpers/alert.helpers.d.ts +27 -0
  4. package/dist/alert/helpers/index.d.ts +1 -0
  5. package/dist/alert/index.d.ts +2 -0
  6. package/dist/alert/types/alert.types.d.ts +25 -0
  7. package/dist/alert/types/index.d.ts +1 -0
  8. package/dist/alert-CTIWpkmD.js +128 -0
  9. package/dist/alert-DTc0Usg-.cjs +1 -0
  10. package/dist/alert.cjs +1 -0
  11. package/dist/alert.js +4 -0
  12. package/dist/box/box.d.ts +1 -1
  13. package/dist/box/box.types.d.ts +1 -1
  14. package/dist/box/index.d.ts +1 -0
  15. package/dist/button/button.helpers.d.ts +1 -1
  16. package/dist/button/index.d.ts +1 -0
  17. package/dist/flex/flex.d.ts +1 -1
  18. package/dist/flex/flex.types.d.ts +1 -1
  19. package/dist/flex/index.d.ts +1 -0
  20. package/dist/icons/icons.d.ts +8 -0
  21. package/dist/icons/index.d.ts +1 -0
  22. package/dist/icons.cjs +1 -1
  23. package/dist/icons.js +40 -36
  24. package/dist/index.cjs +1 -1
  25. package/dist/index.d.ts +4 -1
  26. package/dist/index.js +101 -90
  27. package/dist/input/input.types.d.ts +1 -1
  28. package/dist/notification-provider/helpers/index.d.ts +1 -0
  29. package/dist/notification-provider/helpers/notification-provider.helpers.d.ts +8 -0
  30. package/dist/notification-provider/hooks/index.d.ts +1 -0
  31. package/dist/notification-provider/hooks/notification-provider.hooks.d.ts +5 -0
  32. package/dist/notification-provider/index.d.ts +3 -0
  33. package/dist/notification-provider/notification-provider.d.ts +4 -0
  34. package/dist/notification-provider/types/index.d.ts +1 -0
  35. package/dist/notification-provider/types/notification-provider.types.d.ts +61 -0
  36. package/dist/notification-provider-C2ypXy2W.cjs +1 -0
  37. package/dist/notification-provider-WLUaZyMB.js +113 -0
  38. package/dist/notification-provider.cjs +1 -0
  39. package/dist/notification-provider.js +6 -0
  40. package/dist/shared/responsive-style/index.d.ts +1 -0
  41. package/dist/shared/responsive-style/responsive-style.types.d.ts +1 -1
  42. package/dist/toast/index.d.ts +2 -0
  43. package/dist/toast/toast.d.ts +5 -0
  44. package/dist/toast/types/index.d.ts +1 -0
  45. package/dist/toast/types/toast.types.d.ts +10 -0
  46. package/dist/toast-CH8VqvLC.cjs +1 -0
  47. package/dist/toast-DpjugQ8H.js +49 -0
  48. package/dist/toast.cjs +1 -0
  49. package/dist/toast.js +4 -0
  50. package/dist/typography/index.d.ts +1 -0
  51. package/dist/typography/typography.helpers.d.ts +1 -1
  52. package/package.json +28 -2
@@ -0,0 +1,61 @@
1
+ import { ReactNode } from 'react';
2
+ import { AlertProps } from '../../alert/index';
3
+ import { FlexBreakpointProps, FlexProps } from '../../flex/index';
4
+ import { ToastProps } from '../../toast/index';
5
+ /** Позиции стека. top/bottom — синонимы top-middle/bottom-middle; center — центр экрана. */
6
+ export type NotificationPlacement = 'top-left' | 'top' | 'top-middle' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-middle' | 'bottom-right' | 'center';
7
+ /** Настройки положения на одном брейкпоинте; null сбрасывает placement к top-right.
8
+ * position/transform из Flex имеют приоритет над пресетом и допускают auto/none для сброса.
9
+ */
10
+ export type NotificationViewportBreakpoint = Pick<FlexBreakpointProps, 'position' | 'transform' | 'width' | 'maxWidth' | 'maxHeight' | 'gap' | 'p' | 'align'> & {
11
+ /** Пресет положения; пропущенный наследуется, null возвращает top-right. */
12
+ placement?: NotificationPlacement | null;
13
+ };
14
+ /** Стек на base/md/lg/xl: пропущенные значения наследуются от меньшего экрана.
15
+ * Явный style приоритетнее пресетов и responsive props; className передаётся в Flex.
16
+ */
17
+ export type NotificationViewportProps = NotificationViewportBreakpoint & Pick<FlexProps, 'style' | 'className'> & {
18
+ /** Переопределения от 768 px. */
19
+ md?: NotificationViewportBreakpoint;
20
+ /** Переопределения от 1024 px. */
21
+ lg?: NotificationViewportBreakpoint;
22
+ /** Переопределения от 1440 px. */
23
+ xl?: NotificationViewportBreakpoint;
24
+ };
25
+ /** Дополнительные параметры вызова уведомления. */
26
+ export type NotificationOptions = {
27
+ /** Необязательный стабильный ID; повторный вызов заменяет уведомление с тем же ID. */
28
+ id?: string;
29
+ /** Локальное положение стека поверх настроек провайдера, со слиянием md/lg/xl. */
30
+ viewport?: NotificationViewportProps;
31
+ };
32
+ /** Все ReactNode-слоты и style props Alert доступны при вызове. */
33
+ export type ShowAlertOptions = AlertProps & NotificationOptions;
34
+ /** Все ReactNode-слоты и style props Toast доступны при вызове; duration по умолчанию 0. */
35
+ export type ShowToastOptions = Omit<ToastProps, 'open'> & NotificationOptions;
36
+ /** API ближайшего провайдера; методы стабильны между рендерами. */
37
+ export type NotificationsApi = {
38
+ /** Показывает Alert и возвращает ID для закрытия или обновления. */
39
+ showAlert: (options: ShowAlertOptions) => string;
40
+ /** Показывает Toast и возвращает ID; duration включает автозакрытие. */
41
+ showToast: (options: ShowToastOptions) => string;
42
+ /** Закрывает уведомление; неизвестный ID игнорируется. */
43
+ dismiss: (id: string) => void;
44
+ /** Закрывает все уведомления текущего провайдера. */
45
+ dismissAll: () => void;
46
+ /** Обновляет props и положение существующего уведомления без изменения его вида. */
47
+ update: (id: string, options: Omit<ShowToastOptions, 'id'>) => void;
48
+ };
49
+ /** Провайдер вызовов и стеков; без портала, сохраняет CSS-токены окружающей темы. */
50
+ export type NotificationProviderProps = {
51
+ /** Приложение, использующее useNotifications. */
52
+ children?: ReactNode;
53
+ /** Общие настройки стеков; по умолчанию top-right, отступ 16 px, gap 12 px, z-index 1000. */
54
+ viewport?: NotificationViewportProps;
55
+ };
56
+ /** Внутренняя запись уведомления; kind определяет компонент при рендере. */
57
+ export type NotificationEntry = {
58
+ id: string;
59
+ kind: 'alert' | 'toast';
60
+ options: ShowToastOptions;
61
+ };
@@ -0,0 +1 @@
1
+ "use client";"use strict";const l=require("react/jsx-runtime"),u=require("react"),j=require("./alert-DTc0Usg-.cjs"),y=require("./toast-CH8VqvLC.cjs"),k=require("./responsive-style.config-B2m9jVlX.cjs"),N=require("./flex.cjs"),P=u.createContext(null);function C(){const t=u.useContext(P);if(!t)throw new Error("useNotifications requires NotificationProvider");return t}function w(t){const e=t==="top"||t==="top-middle"||t==="bottom"||t==="bottom-middle"||t==="center",p=t.startsWith("bottom");return{position:{type:"fixed",zIndex:1e3,top:t==="center"?"50%":p?"auto":16,bottom:p?16:"auto",left:t==="center"||e?"50%":t.endsWith("left")?16:"auto",right:e||t.endsWith("left")?"auto":16},transform:t==="center"?"translate(-50%, -50%)":e?"translateX(-50%)":"none",align:e?"center":t.endsWith("left")?"start":"end"}}function q(t={},e={}){const p={...t,...e,style:{...t.style,...e.style},position:{...t.position,...e.position}};for(const r of k.responsiveBreakpoints)p[r]={...t[r],...e[r],position:{...t[r]?.position,...e[r]?.position}};return p}function W(t){const{placement:e,md:p,lg:r,xl:v,...x}=t,a={flexDirection:"column",gap:12,width:"fit-content",maxWidth:"calc(100vw - 32px)",maxHeight:"calc(100dvh - 32px)",overflowY:"auto",pointerEvents:"none",...w(e??"top-right"),...x,position:{...w(e??"top-right").position,...x.position}},f={md:p,lg:r,xl:v};for(const c of k.responsiveBreakpoints){const o=f[c];if(!o)continue;const{placement:i,...s}=o,n=i!==void 0?w(i??"top-right"):{};a[c]={...n,...s,position:{...n.position,...s.position}}}return a}function b({children:t,viewport:e}){const[p,r]=u.useState([]),v=u.useId(),x=u.useRef(0),a=u.useMemo(()=>{const c=(o,i)=>{const s=i.id??v+"-"+String(++x.current);return r(n=>{const h={id:s,kind:o,options:i};return n.some(d=>d.id===s)?n.map(d=>d.id===s?h:d):[...n,h]}),s};return{showAlert:o=>c("alert",o),showToast:o=>c("toast",o),dismiss:o=>r(i=>i.filter(s=>s.id!==o)),dismissAll:()=>r([]),update:(o,i)=>r(s=>s.map(n=>n.id===o?{...n,options:{...n.options,...i,viewport:q(n.options.viewport,i.viewport)}}:n))}},[v]),f=new Map;for(const c of p){const o=q(e,c.options.viewport),i=JSON.stringify(o),s=f.get(i);s?s.entries.push(c):f.set(i,{viewport:o,entries:[c]})}return l.jsxs(P.Provider,{value:a,children:[t,[...f.entries()].map(([c,o])=>l.jsx(N.Flex,{...W(o.viewport),children:o.entries.map(i=>{const{id:s,viewport:n,duration:h,onClose:d,...g}=i.options,m=()=>{a.dismiss(i.id),d?.()};return l.jsx(N.Flex,{pointerEvents:"auto",shrink:0,maxWidth:"100%",children:i.kind==="toast"?l.jsx(y.Toast,{...g,duration:h,onClose:m}):l.jsx(j.Alert,{...g,onClose:m})},i.id)})},c))]})}exports.NotificationProvider=b;exports.useNotifications=C;
@@ -0,0 +1,113 @@
1
+ "use client";
2
+ import { jsxs as P, jsx as h } from "react/jsx-runtime";
3
+ import { useContext as W, createContext as b, useState as y, useId as A, useRef as E, useMemo as S } from "react";
4
+ import { A as T } from "./alert-CTIWpkmD.js";
5
+ import { T as j } from "./toast-DpjugQ8H.js";
6
+ import { a as k } from "./responsive-style.config-DFuATrIM.js";
7
+ import { Flex as g } from "./flex.js";
8
+ const C = b(null);
9
+ function D() {
10
+ const t = W(C);
11
+ if (!t) throw new Error("useNotifications requires NotificationProvider");
12
+ return t;
13
+ }
14
+ function v(t) {
15
+ const e = t === "top" || t === "top-middle" || t === "bottom" || t === "bottom-middle" || t === "center", c = t.startsWith("bottom");
16
+ return {
17
+ position: {
18
+ type: "fixed",
19
+ zIndex: 1e3,
20
+ top: t === "center" ? "50%" : c ? "auto" : 16,
21
+ bottom: c ? 16 : "auto",
22
+ left: t === "center" || e ? "50%" : t.endsWith("left") ? 16 : "auto",
23
+ right: e || t.endsWith("left") ? "auto" : 16
24
+ },
25
+ transform: t === "center" ? "translate(-50%, -50%)" : e ? "translateX(-50%)" : "none",
26
+ align: e ? "center" : t.endsWith("left") ? "start" : "end"
27
+ };
28
+ }
29
+ function N(t = {}, e = {}) {
30
+ const c = {
31
+ ...t,
32
+ ...e,
33
+ style: { ...t.style, ...e.style },
34
+ position: { ...t.position, ...e.position }
35
+ };
36
+ for (const r of k)
37
+ c[r] = {
38
+ ...t[r],
39
+ ...e[r],
40
+ position: { ...t[r]?.position, ...e[r]?.position }
41
+ };
42
+ return c;
43
+ }
44
+ function q(t) {
45
+ const { placement: e, md: c, lg: r, xl: a, ...m } = t, f = {
46
+ flexDirection: "column",
47
+ gap: 12,
48
+ width: "fit-content",
49
+ maxWidth: "calc(100vw - 32px)",
50
+ maxHeight: "calc(100dvh - 32px)",
51
+ overflowY: "auto",
52
+ pointerEvents: "none",
53
+ ...v(e ?? "top-right"),
54
+ ...m,
55
+ position: { ...v(e ?? "top-right").position, ...m.position }
56
+ }, u = { md: c, lg: r, xl: a };
57
+ for (const p of k) {
58
+ const o = u[p];
59
+ if (!o) continue;
60
+ const { placement: i, ...n } = o, s = i !== void 0 ? v(i ?? "top-right") : {};
61
+ f[p] = { ...s, ...n, position: { ...s.position, ...n.position } };
62
+ }
63
+ return f;
64
+ }
65
+ function F({
66
+ children: t,
67
+ viewport: e
68
+ }) {
69
+ const [c, r] = y([]), a = A(), m = E(0), f = S(() => {
70
+ const p = (o, i) => {
71
+ const n = i.id ?? a + "-" + String(++m.current);
72
+ return r((s) => {
73
+ const l = { id: n, kind: o, options: i };
74
+ return s.some((d) => d.id === n) ? s.map((d) => d.id === n ? l : d) : [...s, l];
75
+ }), n;
76
+ };
77
+ return {
78
+ showAlert: (o) => p("alert", o),
79
+ showToast: (o) => p("toast", o),
80
+ dismiss: (o) => r((i) => i.filter((n) => n.id !== o)),
81
+ dismissAll: () => r([]),
82
+ update: (o, i) => r(
83
+ (n) => n.map(
84
+ (s) => s.id === o ? {
85
+ ...s,
86
+ options: {
87
+ ...s.options,
88
+ ...i,
89
+ viewport: N(s.options.viewport, i.viewport)
90
+ }
91
+ } : s
92
+ )
93
+ )
94
+ };
95
+ }, [a]), u = /* @__PURE__ */ new Map();
96
+ for (const p of c) {
97
+ const o = N(e, p.options.viewport), i = JSON.stringify(o), n = u.get(i);
98
+ n ? n.entries.push(p) : u.set(i, { viewport: o, entries: [p] });
99
+ }
100
+ return /* @__PURE__ */ P(C.Provider, { value: f, children: [
101
+ t,
102
+ [...u.entries()].map(([p, o]) => /* @__PURE__ */ h(g, { ...q(o.viewport), children: o.entries.map((i) => {
103
+ const { id: n, viewport: s, duration: l, onClose: d, ...w } = i.options, x = () => {
104
+ f.dismiss(i.id), d?.();
105
+ };
106
+ return /* @__PURE__ */ h(g, { pointerEvents: "auto", shrink: 0, maxWidth: "100%", children: i.kind === "toast" ? /* @__PURE__ */ h(j, { ...w, duration: l, onClose: x }) : /* @__PURE__ */ h(T, { ...w, onClose: x }) }, i.id);
107
+ }) }, p))
108
+ ] });
109
+ }
110
+ export {
111
+ F as N,
112
+ D as u
113
+ };
@@ -0,0 +1 @@
1
+ "use client";"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const i=require("./notification-provider-C2ypXy2W.cjs");exports.NotificationProvider=i.NotificationProvider;exports.useNotifications=i.useNotifications;
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ import { N as t, u as e } from "./notification-provider-WLUaZyMB.js";
3
+ export {
4
+ t as NotificationProvider,
5
+ e as useNotifications
6
+ };
@@ -0,0 +1 @@
1
+ export { responsiveBreakpointMinWidth, responsiveBreakpoints } from './responsive-style.config';
@@ -1,6 +1,6 @@
1
1
  import { CSSProperties } from 'react';
2
2
  import { UiKitTypography } from '../../design-tokens/typography.tokens';
3
- import { UiKitColors } from '../../types';
3
+ import { UiKitColors } from '../../types/index';
4
4
  /**
5
5
  * Поддерживаемые responsive breakpoints.
6
6
  *
@@ -0,0 +1,2 @@
1
+ export { Toast } from './toast';
2
+ export type { ToastProps } from './types/index';
@@ -0,0 +1,5 @@
1
+ import { JSX } from 'react';
2
+ import { ToastProps } from './types/index';
3
+ /** Управляемый тост без портала: расположение и очередь задаёт приложение. */
4
+ export declare function Toast({ open, duration, onClose, onMouseEnter, onMouseLeave, onFocus, onBlur, ...props }: ToastProps): JSX.Element | null;
5
+ export type { ToastProps } from './types/index';
@@ -0,0 +1 @@
1
+ export type { ToastProps } from './toast.types';
@@ -0,0 +1,10 @@
1
+ import { AlertProps } from '../../alert/index';
2
+ /** Toast наследует все слоты и responsive style props Alert. */
3
+ export type ToastProps = AlertProps & {
4
+ /** Видимость, по умолчанию true. Закрытие управляется родителем через onClose. */
5
+ open?: boolean;
6
+ /** Автозакрытие в мс; 0 (по умолчанию) отключает таймер.
7
+ * Наведение и фокус приостанавливают отсчёт с сохранением остатка.
8
+ */
9
+ duration?: number;
10
+ };
@@ -0,0 +1 @@
1
+ "use client";"use strict";const q=require("react/jsx-runtime"),t=require("react"),x=require("./alert-DTc0Usg-.cjs");function M({open:u=!0,duration:s=0,onClose:r,onMouseEnter:l,onMouseLeave:m,onFocus:T,onBlur:E,...R}){const[n,a]=t.useState(!1),[f,i]=t.useState(!1),c=t.useRef(s),o=t.useRef(r);return t.useEffect(()=>{o.current=r},[r]),t.useEffect(()=>{c.current=s},[s,u]),t.useEffect(()=>{if(!u||s<=0||!r||n||f)return;const e=Date.now(),g=setTimeout(()=>o.current?.(),c.current);return()=>{clearTimeout(g),c.current=Math.max(0,c.current-(Date.now()-e))}},[u,s,r,n,f]),u?q.jsx(x.Alert,{variant:"soft",...R,onClose:r,onMouseEnter:e=>{a(!0),l?.(e)},onMouseLeave:e=>{a(!1),m?.(e)},onFocus:e=>{i(!0),T?.(e)},onBlur:e=>{e.currentTarget.contains(e.relatedTarget)||i(!1),E?.(e)}}):null}exports.Toast=M;
@@ -0,0 +1,49 @@
1
+ "use client";
2
+ import { jsx as v } from "react/jsx-runtime";
3
+ import { useState as m, useRef as l, useEffect as c } from "react";
4
+ import { A as w } from "./alert-CTIWpkmD.js";
5
+ function F({
6
+ open: s = !0,
7
+ duration: r = 0,
8
+ onClose: t,
9
+ onMouseEnter: T,
10
+ onMouseLeave: g,
11
+ onFocus: x,
12
+ onBlur: M,
13
+ ...d
14
+ }) {
15
+ const [n, a] = m(!1), [f, o] = m(!1), u = l(r), i = l(t);
16
+ return c(() => {
17
+ i.current = t;
18
+ }, [t]), c(() => {
19
+ u.current = r;
20
+ }, [r, s]), c(() => {
21
+ if (!s || r <= 0 || !t || n || f) return;
22
+ const e = Date.now(), h = setTimeout(() => i.current?.(), u.current);
23
+ return () => {
24
+ clearTimeout(h), u.current = Math.max(0, u.current - (Date.now() - e));
25
+ };
26
+ }, [s, r, t, n, f]), s ? /* @__PURE__ */ v(
27
+ w,
28
+ {
29
+ variant: "soft",
30
+ ...d,
31
+ onClose: t,
32
+ onMouseEnter: (e) => {
33
+ a(!0), T?.(e);
34
+ },
35
+ onMouseLeave: (e) => {
36
+ a(!1), g?.(e);
37
+ },
38
+ onFocus: (e) => {
39
+ o(!0), x?.(e);
40
+ },
41
+ onBlur: (e) => {
42
+ e.currentTarget.contains(e.relatedTarget) || o(!1), M?.(e);
43
+ }
44
+ }
45
+ ) : null;
46
+ }
47
+ export {
48
+ F as T
49
+ };
package/dist/toast.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./toast-CH8VqvLC.cjs");exports.Toast=t.Toast;
package/dist/toast.js ADDED
@@ -0,0 +1,4 @@
1
+ import { T as r } from "./toast-DpjugQ8H.js";
2
+ export {
3
+ r as Toast
4
+ };
@@ -0,0 +1 @@
1
+ export * from './typography';
@@ -1,7 +1,7 @@
1
1
  import { CSSProperties } from 'react';
2
2
  import { UiKitTypographyToken } from '../design-tokens/typography.tokens';
3
3
  import { CssVariableMap, ResponsiveStyleBreakpoint, ResponsiveUiKitStyleProps } from '../shared/responsive-style/responsive-style.types';
4
- import { UiKitTypographyProps } from '../types';
4
+ import { UiKitTypographyProps } from '../types/index';
5
5
  /**
6
6
  * Токены размера шрифта, которые Typography может подключить к внутренним CSS-переменным.
7
7
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shmidko61/lc-ui-kit",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist"
@@ -69,6 +69,15 @@
69
69
  ],
70
70
  "ui-kit-provider": [
71
71
  "dist/ui-kit-provider/ui-kit-provider.d.ts"
72
+ ],
73
+ "alert": [
74
+ "dist/alert/index.d.ts"
75
+ ],
76
+ "toast": [
77
+ "dist/toast/index.d.ts"
78
+ ],
79
+ "notification-provider": [
80
+ "dist/notification-provider/index.d.ts"
72
81
  ]
73
82
  }
74
83
  },
@@ -173,6 +182,21 @@
173
182
  "types": "./dist/ui-kit-provider/ui-kit-provider.d.ts",
174
183
  "import": "./dist/ui-kit-provider.js",
175
184
  "require": "./dist/ui-kit-provider.cjs"
185
+ },
186
+ "./alert": {
187
+ "types": "./dist/alert/index.d.ts",
188
+ "import": "./dist/alert.js",
189
+ "require": "./dist/alert.cjs"
190
+ },
191
+ "./toast": {
192
+ "types": "./dist/toast/index.d.ts",
193
+ "import": "./dist/toast.js",
194
+ "require": "./dist/toast.cjs"
195
+ },
196
+ "./notification-provider": {
197
+ "types": "./dist/notification-provider/index.d.ts",
198
+ "import": "./dist/notification-provider.js",
199
+ "require": "./dist/notification-provider.cjs"
176
200
  }
177
201
  },
178
202
  "sideEffects": [
@@ -221,6 +245,8 @@
221
245
  "test:package": "node scripts/check-package.mjs",
222
246
  "test:checks": "node --test scripts/package-checks.test.mjs",
223
247
  "pack:check": "node scripts/check-tarball.mjs",
224
- "typecheck:package": "tsc -p tsconfig.package-test.json"
248
+ "typecheck:package": "tsc -p tsconfig.package-test.json",
249
+ "test:notifications": "node scripts/check-notifications-browser.mjs",
250
+ "test:compatibility": "node scripts/check-compatibility.mjs"
225
251
  }
226
252
  }