@beautinique/frontend-components 1.0.2 → 1.0.4

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 (42) hide show
  1. package/README.md +48 -1
  2. package/dist/lib/button.d.cts +4 -1
  3. package/dist/lib/button.d.cts.map +1 -1
  4. package/dist/lib/button.d.ts +4 -1
  5. package/dist/lib/button.d.ts.map +1 -1
  6. package/dist/lib/constants.d.cts +4 -0
  7. package/dist/lib/constants.d.cts.map +1 -1
  8. package/dist/lib/constants.d.ts +4 -0
  9. package/dist/lib/constants.d.ts.map +1 -1
  10. package/dist/lib/tooltip.d.cts +36 -4
  11. package/dist/lib/tooltip.d.cts.map +1 -1
  12. package/dist/lib/tooltip.d.ts +36 -4
  13. package/dist/lib/tooltip.d.ts.map +1 -1
  14. package/dist/toast/ToastContainer.d.cts +1 -1
  15. package/dist/toast/ToastContainer.d.cts.map +1 -1
  16. package/dist/toast/ToastContainer.d.ts +1 -1
  17. package/dist/toast/ToastContainer.d.ts.map +1 -1
  18. package/dist/toast/index.cjs +36 -43
  19. package/dist/toast/index.cjs.map +1 -1
  20. package/dist/toast/index.js +23 -30
  21. package/dist/toast/index.js.map +1 -1
  22. package/dist/toast/types.d.cts +2 -2
  23. package/dist/toast/types.d.cts.map +1 -1
  24. package/dist/toast/types.d.ts +2 -2
  25. package/dist/toast/types.d.ts.map +1 -1
  26. package/dist/types/component.d.cts +22 -4
  27. package/dist/types/component.d.cts.map +1 -1
  28. package/dist/types/component.d.ts +22 -4
  29. package/dist/types/component.d.ts.map +1 -1
  30. package/dist/ui/Button.d.cts +1 -1
  31. package/dist/ui/Button.d.cts.map +1 -1
  32. package/dist/ui/Button.d.ts +1 -1
  33. package/dist/ui/Button.d.ts.map +1 -1
  34. package/dist/ui/Tooltip.d.cts +1 -1
  35. package/dist/ui/Tooltip.d.cts.map +1 -1
  36. package/dist/ui/Tooltip.d.ts +1 -1
  37. package/dist/ui/Tooltip.d.ts.map +1 -1
  38. package/dist/ui/index.cjs +143 -62
  39. package/dist/ui/index.cjs.map +1 -1
  40. package/dist/ui/index.js +143 -62
  41. package/dist/ui/index.js.map +1 -1
  42. package/package.json +1 -1
package/README.md CHANGED
@@ -57,15 +57,62 @@ const App = () => (
57
57
  );
58
58
  ```
59
59
 
60
+ ### Button
61
+
62
+ ```tsx
63
+ const save = <Button pattern="primary" content="Save" buttonProps={{ type: 'submit' }} />;
64
+
65
+ // only an icon: it has to be given a name, a screen reader reads it (`aria-labelledby` works too)
66
+ const edit = (
67
+ <Button
68
+ pattern="outline"
69
+ content={{ icon: 'solar:pen-linear' }}
70
+ buttonProps={{ 'aria-label': 'Edit category' }}
71
+ />
72
+ );
73
+ ```
74
+
75
+ - **Classes you give are added after the button's own and none of its own is removed.** To win over
76
+ one of them make it important with `!`: `className="rounded-md! px-2! lg:px-2!"`. The button has
77
+ classes for large screens (`lg:px-5`, `lg:py-4`, `xl:text-base`), they are other classes than
78
+ `px-4` and so on, so to change the padding on every screen give the `lg:` one too.
79
+ - **`ref`** is the `<button>` itself: `<Button ref={buttonRef} ... />`.
80
+ - A button with only an icon does not compile without `aria-label` or `aria-labelledby` in
81
+ `buttonProps`.
82
+
83
+ ### Tooltip
84
+
85
+ ```tsx
86
+ const hint = (
87
+ <Tooltip title="Save" description="Ctrl + S" placement="right">
88
+ <Button pattern="primary" content="Save" />
89
+ </Tooltip>
90
+ );
91
+ ```
92
+
93
+ - It opens on hover and on focus, and closes on mouse leave, blur or **Escape**.
94
+ - **It stays inside the window**: with no room on the side asked for (`placement`) it opens on the
95
+ opposite side, and it is pushed along the edge to keep 8px from it, the arrow still pointing at
96
+ the content.
97
+ - **For a screen reader** it is `role="tooltip"` and, while it is open, the content is described by it
98
+ (`aria-describedby` is put on the child element, next to what it already has).
99
+ - **`required={false}` shows only the content.** The wrapper stays (as `display: contents`, it takes
100
+ no room), so `required` can change while the page is open (a locked field, the size of the
101
+ screen) without the content being created again and losing its state. One difference to a tooltip
102
+ that is not there at all: the content is one level deeper in the DOM, so a css rule that looks at
103
+ the parent of the content (`space-y-*` on a parent, `> :first-child`) sees the wrapper.
104
+
60
105
  ### Toasts
61
106
 
62
107
  `toaster` works from anywhere (an API client, a store), not only from components:
63
108
 
64
- ```ts
109
+ ```tsx
65
110
  toaster.success({ title: 'Saved', description: 'Your changes were saved.' });
66
111
  toaster.error({ title: 'Failed' });
67
112
  toaster.warning({ title: 'Careful' });
113
+ toaster.default({ title: 'Heads up' });
68
114
  toaster.loading({ title: 'Working' });
115
+ toaster.custom({ type: 'custom', children: <p>Any React content</p> });
69
116
  ```
70
117
 
71
118
  Toasts that follow uploads (`withProgressToast` for one request, `createUploadsToast`,
@@ -1,3 +1,6 @@
1
1
  import type { IButton } from '../types/component.js';
2
- export declare const getButtonCss: (pattern: IButton["pattern"]) => "text-white bg-sky-blue-burst shadow-primary-btn hover:shadow-primary-btn-hover" | "text-secondary-invert bg-secondary shadow-secondary-btn hover:shadow-secondary-btn-hover" | "text-tertiary-invert bg-tertiary shadow-tertiary-btn hover:shadow-tertiary-btn-hover" | "text-primary border border-primary shadow-outline-btn hover:shadow-outline-btn-hover" | "bg-transparent border border-primary/30 text-secondary";
2
+ type TPattern = IButton['pattern'];
3
+ /** The look of a pattern; a pattern nobody knows (from code that is not type checked) is transparent. */
4
+ export declare const getButtonCss: (pattern: TPattern) => string;
5
+ export {};
3
6
  //# sourceMappingURL=button.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.cts","sourceRoot":"","sources":["../../src/lib/button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,eAAO,MAAM,YAAY,GAAI,SAAS,OAAO,CAAC,SAAS,CAAC,+ZAcvD,CAAC"}
1
+ {"version":3,"file":"button.d.cts","sourceRoot":"","sources":["../../src/lib/button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,KAAK,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAYnC,yGAAyG;AACzG,eAAO,MAAM,YAAY,GAAI,SAAS,QAAQ,WACwC,CAAC"}
@@ -1,3 +1,6 @@
1
1
  import type { IButton } from '../types/component.js';
2
- export declare const getButtonCss: (pattern: IButton["pattern"]) => "text-white bg-sky-blue-burst shadow-primary-btn hover:shadow-primary-btn-hover" | "text-secondary-invert bg-secondary shadow-secondary-btn hover:shadow-secondary-btn-hover" | "text-tertiary-invert bg-tertiary shadow-tertiary-btn hover:shadow-tertiary-btn-hover" | "text-primary border border-primary shadow-outline-btn hover:shadow-outline-btn-hover" | "bg-transparent border border-primary/30 text-secondary";
2
+ type TPattern = IButton['pattern'];
3
+ /** The look of a pattern; a pattern nobody knows (from code that is not type checked) is transparent. */
4
+ export declare const getButtonCss: (pattern: TPattern) => string;
5
+ export {};
3
6
  //# sourceMappingURL=button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/lib/button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,eAAO,MAAM,YAAY,GAAI,SAAS,OAAO,CAAC,SAAS,CAAC,+ZAcvD,CAAC"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../src/lib/button.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,KAAK,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;AAYnC,yGAAyG;AACzG,eAAO,MAAM,YAAY,GAAI,SAAS,QAAQ,WACwC,CAAC"}
@@ -1,5 +1,9 @@
1
1
  export declare const TOOLTIP_GAP: 15;
2
2
  export declare const TOOLTIP_ANIMATION_DURATION: 400;
3
+ /** The least space a tooltip keeps between itself and the edge of the window. */
4
+ export declare const TOOLTIP_VIEWPORT_MARGIN: 8;
5
+ /** The arrow stays at least this far from the ends of the tooltip (its own size and the rounded corner). */
6
+ export declare const TOOLTIP_ARROW_INSET: 16;
3
7
  export declare const TOAST_TYPES: readonly ["success", "error", "warning", "progress", "uploads", "loading", "default", "custom"];
4
8
  export declare const TOAST_TYPE: { [K in (typeof TOAST_TYPES)[number]]: K; };
5
9
  //# sourceMappingURL=constants.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,EAAG,EAAW,CAAC;AACvC,eAAO,MAAM,0BAA0B,EAAG,GAAY,CAAC;AAEvD,eAAO,MAAM,WAAW,iGASd,CAAC;AAEX,eAAO,MAAM,UAAU,EAAkE,GACtF,CAAC,IAAI,CAAC,OAAO,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,GACvC,CAAC"}
1
+ {"version":3,"file":"constants.d.cts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,EAAG,EAAW,CAAC;AACvC,eAAO,MAAM,0BAA0B,EAAG,GAAY,CAAC;AACvD,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,EAAG,CAAU,CAAC;AAClD,4GAA4G;AAC5G,eAAO,MAAM,mBAAmB,EAAG,EAAW,CAAC;AAE/C,eAAO,MAAM,WAAW,iGASd,CAAC;AAEX,eAAO,MAAM,UAAU,EAAkE,GACtF,CAAC,IAAI,CAAC,OAAO,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,GACvC,CAAC"}
@@ -1,5 +1,9 @@
1
1
  export declare const TOOLTIP_GAP: 15;
2
2
  export declare const TOOLTIP_ANIMATION_DURATION: 400;
3
+ /** The least space a tooltip keeps between itself and the edge of the window. */
4
+ export declare const TOOLTIP_VIEWPORT_MARGIN: 8;
5
+ /** The arrow stays at least this far from the ends of the tooltip (its own size and the rounded corner). */
6
+ export declare const TOOLTIP_ARROW_INSET: 16;
3
7
  export declare const TOAST_TYPES: readonly ["success", "error", "warning", "progress", "uploads", "loading", "default", "custom"];
4
8
  export declare const TOAST_TYPE: { [K in (typeof TOAST_TYPES)[number]]: K; };
5
9
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,EAAG,EAAW,CAAC;AACvC,eAAO,MAAM,0BAA0B,EAAG,GAAY,CAAC;AAEvD,eAAO,MAAM,WAAW,iGASd,CAAC;AAEX,eAAO,MAAM,UAAU,EAAkE,GACtF,CAAC,IAAI,CAAC,OAAO,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,GACvC,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,EAAG,EAAW,CAAC;AACvC,eAAO,MAAM,0BAA0B,EAAG,GAAY,CAAC;AACvD,iFAAiF;AACjF,eAAO,MAAM,uBAAuB,EAAG,CAAU,CAAC;AAClD,4GAA4G;AAC5G,eAAO,MAAM,mBAAmB,EAAG,EAAW,CAAC;AAE/C,eAAO,MAAM,WAAW,iGASd,CAAC;AAEX,eAAO,MAAM,UAAU,EAAkE,GACtF,CAAC,IAAI,CAAC,OAAO,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,GACvC,CAAC"}
@@ -1,6 +1,38 @@
1
- import type { CSSProperties } from 'react';
2
1
  import type { ITooltip } from '../types/component.js';
3
- export declare const getTooltipPosition: (rect: DOMRect, placement: NonNullable<ITooltip["placement"]>) => CSSProperties;
4
- export declare const getTooltipTransform: (placement: NonNullable<ITooltip["placement"]>, isVisible: boolean) => string;
5
- export declare const getTooltipArrowCss: (placement: NonNullable<ITooltip["placement"]>) => "after:bottom-full after:left-1/2 after:-translate-x-1/2 after:border-b-silver-jet-2" | "after:top-1/2 after:right-full after:-translate-y-1/2 after:border-r-silver-jet-2" | "after:top-1/2 after:left-full after:-translate-y-1/2 after:border-l-silver-jet-2" | "after:top-full after:left-1/2 after:-translate-x-1/2 after:border-t-silver-jet-2";
2
+ type TPlacement = NonNullable<ITooltip['placement']>;
3
+ export interface ISize {
4
+ width: number;
5
+ height: number;
6
+ }
7
+ export interface ITooltipLayout {
8
+ /** The side the tooltip really opens on: the opposite one when there is no room on the asked one. */
9
+ placement: TPlacement;
10
+ /** Where the tooltip points to, in the window (it is moved away from it by `getTooltipTransform`). */
11
+ position: {
12
+ top: number;
13
+ left: number;
14
+ };
15
+ /** How far the arrow moves along the tooltip to keep pointing at the content when the tooltip is pushed in. */
16
+ arrowShift: number;
17
+ }
18
+ export declare const getTooltipPosition: (rect: DOMRect, placement: TPlacement) => {
19
+ top: number;
20
+ left: number;
21
+ };
22
+ /**
23
+ * Where the tooltip goes. Without its `size` (it is not on the page yet) it goes where it was asked
24
+ * to. With it, it opens on the opposite side when the asked one has no room and the other has, and
25
+ * it is pushed along that side to stay inside the window; the arrow keeps pointing at the content.
26
+ */
27
+ export declare const getTooltipLayout: ({ rect, placement, size, viewport, }: {
28
+ rect: DOMRect;
29
+ placement: TPlacement;
30
+ size?: ISize;
31
+ viewport: ISize;
32
+ }) => ITooltipLayout;
33
+ /** Whether two layouts put the tooltip in the same place (so there is nothing to change). */
34
+ export declare const isSameTooltipLayout: (a: ITooltipLayout, b: ITooltipLayout) => boolean;
35
+ export declare const getTooltipTransform: (placement: TPlacement, isVisible: boolean) => string;
36
+ export declare const getTooltipArrowCss: (placement: TPlacement) => "after:bottom-full after:left-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:-translate-x-1/2 after:border-b-silver-jet-2" | "after:top-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:right-full after:-translate-y-1/2 after:border-r-silver-jet-2" | "after:top-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:left-full after:-translate-y-1/2 after:border-l-silver-jet-2" | "after:top-full after:left-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:-translate-x-1/2 after:border-t-silver-jet-2";
37
+ export {};
6
38
  //# sourceMappingURL=tooltip.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.cts","sourceRoot":"","sources":["../../src/lib/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,EACb,WAAW,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,KAC5C,aAYF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,WAAW,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,EAC7C,WAAW,OAAO,WAenB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,WAAW,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,0VAY/E,CAAC"}
1
+ {"version":3,"file":"tooltip.d.cts","sourceRoot":"","sources":["../../src/lib/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,KAAK,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;AAErD,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,qGAAqG;IACrG,SAAS,EAAE,UAAU,CAAC;IACtB,sGAAsG;IACtG,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,+GAA+G;IAC/G,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,EACb,WAAW,UAAU,KACpB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAY7B,CAAC;AAiBF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,sCAK9B;IACD,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,UAAU,CAAC;IACtB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;CACjB,KAAG,cA2BH,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,GAAI,GAAG,cAAc,EAAE,GAAG,cAAc,YAInC,CAAC;AAEtC,eAAO,MAAM,mBAAmB,GAAI,WAAW,UAAU,EAAE,WAAW,OAAO,WAc5E,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,WAAW,UAAU,8fAYvD,CAAC"}
@@ -1,6 +1,38 @@
1
- import type { CSSProperties } from 'react';
2
1
  import type { ITooltip } from '../types/component.js';
3
- export declare const getTooltipPosition: (rect: DOMRect, placement: NonNullable<ITooltip["placement"]>) => CSSProperties;
4
- export declare const getTooltipTransform: (placement: NonNullable<ITooltip["placement"]>, isVisible: boolean) => string;
5
- export declare const getTooltipArrowCss: (placement: NonNullable<ITooltip["placement"]>) => "after:bottom-full after:left-1/2 after:-translate-x-1/2 after:border-b-silver-jet-2" | "after:top-1/2 after:right-full after:-translate-y-1/2 after:border-r-silver-jet-2" | "after:top-1/2 after:left-full after:-translate-y-1/2 after:border-l-silver-jet-2" | "after:top-full after:left-1/2 after:-translate-x-1/2 after:border-t-silver-jet-2";
2
+ type TPlacement = NonNullable<ITooltip['placement']>;
3
+ export interface ISize {
4
+ width: number;
5
+ height: number;
6
+ }
7
+ export interface ITooltipLayout {
8
+ /** The side the tooltip really opens on: the opposite one when there is no room on the asked one. */
9
+ placement: TPlacement;
10
+ /** Where the tooltip points to, in the window (it is moved away from it by `getTooltipTransform`). */
11
+ position: {
12
+ top: number;
13
+ left: number;
14
+ };
15
+ /** How far the arrow moves along the tooltip to keep pointing at the content when the tooltip is pushed in. */
16
+ arrowShift: number;
17
+ }
18
+ export declare const getTooltipPosition: (rect: DOMRect, placement: TPlacement) => {
19
+ top: number;
20
+ left: number;
21
+ };
22
+ /**
23
+ * Where the tooltip goes. Without its `size` (it is not on the page yet) it goes where it was asked
24
+ * to. With it, it opens on the opposite side when the asked one has no room and the other has, and
25
+ * it is pushed along that side to stay inside the window; the arrow keeps pointing at the content.
26
+ */
27
+ export declare const getTooltipLayout: ({ rect, placement, size, viewport, }: {
28
+ rect: DOMRect;
29
+ placement: TPlacement;
30
+ size?: ISize;
31
+ viewport: ISize;
32
+ }) => ITooltipLayout;
33
+ /** Whether two layouts put the tooltip in the same place (so there is nothing to change). */
34
+ export declare const isSameTooltipLayout: (a: ITooltipLayout, b: ITooltipLayout) => boolean;
35
+ export declare const getTooltipTransform: (placement: TPlacement, isVisible: boolean) => string;
36
+ export declare const getTooltipArrowCss: (placement: TPlacement) => "after:bottom-full after:left-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:-translate-x-1/2 after:border-b-silver-jet-2" | "after:top-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:right-full after:-translate-y-1/2 after:border-r-silver-jet-2" | "after:top-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:left-full after:-translate-y-1/2 after:border-l-silver-jet-2" | "after:top-full after:left-[calc(50%_+_var(--tooltip-arrow-shift,0px))] after:-translate-x-1/2 after:border-t-silver-jet-2";
37
+ export {};
6
38
  //# sourceMappingURL=tooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/lib/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,EACb,WAAW,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,KAC5C,aAYF,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC9B,WAAW,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,EAC7C,WAAW,OAAO,WAenB,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,WAAW,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,0VAY/E,CAAC"}
1
+ {"version":3,"file":"tooltip.d.ts","sourceRoot":"","sources":["../../src/lib/tooltip.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGtD,KAAK,UAAU,GAAG,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;AAErD,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,qGAAqG;IACrG,SAAS,EAAE,UAAU,CAAC;IACtB,sGAAsG;IACtG,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,+GAA+G;IAC/G,UAAU,EAAE,MAAM,CAAC;CACpB;AAWD,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,EACb,WAAW,UAAU,KACpB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAY7B,CAAC;AAiBF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,sCAK9B;IACD,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,UAAU,CAAC;IACtB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,KAAK,CAAC;CACjB,KAAG,cA2BH,CAAC;AAEF,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,GAAI,GAAG,cAAc,EAAE,GAAG,cAAc,YAInC,CAAC;AAEtC,eAAO,MAAM,mBAAmB,GAAI,WAAW,UAAU,EAAE,WAAW,OAAO,WAc5E,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAAI,WAAW,UAAU,8fAYvD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { IClassName } from '../types/component.js';
2
2
  import type { TToastItem } from './types.js';
3
- export declare const Toaster: (props: TToastItem & IClassName) => import("react").JSX.Element | null;
3
+ export declare const Toaster: import("react").MemoExoticComponent<(props: TToastItem & IClassName) => import("react").JSX.Element | null>;
4
4
  export declare const ToastContainer: () => import("react").JSX.Element | null;
5
5
  //# sourceMappingURL=ToastContainer.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToastContainer.d.cts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,KAAK,EAAuB,UAAU,EAAqB,MAAM,YAAY,CAAC;AAkLrF,eAAO,MAAM,OAAO,GAAI,OAAO,UAAU,GAAG,UAAU,uCAmJrD,CAAC;AAEF,eAAO,MAAM,cAAc,0CAY1B,CAAC"}
1
+ {"version":3,"file":"ToastContainer.d.cts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,KAAK,EAAuB,UAAU,EAAqB,MAAM,YAAY,CAAC;AA4UrF,eAAO,MAAM,OAAO,8CA1JQ,UAAU,GAAG,UAAU,wCA0JX,CAAC;AAEzC,eAAO,MAAM,cAAc,0CAY1B,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { IClassName } from '../types/component.js';
2
2
  import type { TToastItem } from './types.js';
3
- export declare const Toaster: (props: TToastItem & IClassName) => import("react").JSX.Element | null;
3
+ export declare const Toaster: import("react").MemoExoticComponent<(props: TToastItem & IClassName) => import("react").JSX.Element | null>;
4
4
  export declare const ToastContainer: () => import("react").JSX.Element | null;
5
5
  //# sourceMappingURL=ToastContainer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToastContainer.d.ts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,KAAK,EAAuB,UAAU,EAAqB,MAAM,YAAY,CAAC;AAkLrF,eAAO,MAAM,OAAO,GAAI,OAAO,UAAU,GAAG,UAAU,uCAmJrD,CAAC;AAEF,eAAO,MAAM,cAAc,0CAY1B,CAAC"}
1
+ {"version":3,"file":"ToastContainer.d.ts","sourceRoot":"","sources":["../../src/toast/ToastContainer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAIxD,OAAO,KAAK,EAAuB,UAAU,EAAqB,MAAM,YAAY,CAAC;AA4UrF,eAAO,MAAM,OAAO,8CA1JQ,UAAU,GAAG,UAAU,wCA0JX,CAAC;AAEzC,eAAO,MAAM,cAAc,0CAY1B,CAAC"}
@@ -2,8 +2,8 @@
2
2
 
3
3
  var nanoid = require('nanoid');
4
4
  var zustand = require('zustand');
5
- var react = require('@iconify/react');
6
- var react$1 = require('react');
5
+ var react$1 = require('@iconify/react');
6
+ var react = require('react');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
 
9
9
  var __defProp = Object.defineProperty;
@@ -108,56 +108,48 @@ var TOAST_ICON_SETS = [
108
108
  }
109
109
  ];
110
110
  var registerToastIcons = /* @__PURE__ */ __name(() => {
111
- for (const iconSet of TOAST_ICON_SETS) react.addCollection(iconSet);
111
+ for (const iconSet of TOAST_ICON_SETS) react$1.addCollection(iconSet);
112
112
  }, "registerToastIcons");
113
113
  var TOAST_ICON_NAMES = TOAST_ICON_SETS.flatMap(
114
114
  ({ prefix, icons }) => Object.keys(icons).map((name) => `${prefix}:${name}`)
115
115
  );
116
116
 
117
117
  // src/lib/button.ts
118
- var getButtonCss = /* @__PURE__ */ __name((pattern) => {
119
- switch (pattern) {
120
- case "primary":
121
- return "text-white bg-sky-blue-burst shadow-primary-btn hover:shadow-primary-btn-hover";
122
- case "secondary":
123
- return "text-secondary-invert bg-secondary shadow-secondary-btn hover:shadow-secondary-btn-hover";
124
- case "tertiary":
125
- return "text-tertiary-invert bg-tertiary shadow-tertiary-btn hover:shadow-tertiary-btn-hover";
126
- case "outline":
127
- return "text-primary border border-primary shadow-outline-btn hover:shadow-outline-btn-hover";
128
- case "transparent":
129
- default:
130
- return "bg-transparent border border-primary/30 text-secondary";
131
- }
132
- }, "getButtonCss");
118
+ var PATTERN_CSS = {
119
+ primary: "text-white bg-sky-blue-burst shadow-primary-btn hover:shadow-primary-btn-hover",
120
+ secondary: "text-secondary-invert bg-secondary shadow-secondary-btn hover:shadow-secondary-btn-hover",
121
+ tertiary: "text-tertiary-invert bg-tertiary shadow-tertiary-btn hover:shadow-tertiary-btn-hover",
122
+ outline: "text-primary border border-primary shadow-outline-btn hover:shadow-outline-btn-hover",
123
+ transparent: "bg-transparent border border-primary/30 text-secondary"
124
+ };
125
+ var getButtonCss = /* @__PURE__ */ __name((pattern) => Object.hasOwn(PATTERN_CSS, pattern) ? PATTERN_CSS[pattern] : PATTERN_CSS.transparent, "getButtonCss");
126
+ var BASE_CSS = "group flex w-full cursor-pointer items-center justify-center gap-1 rounded-lg px-4 py-3 text-sm leading-4 transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-85 lg:px-5 lg:py-4 xl:text-base";
133
127
  var Button = /* @__PURE__ */ __name(({
134
128
  pattern,
135
129
  content,
136
130
  className = "",
137
131
  leftIcon,
138
132
  rightIcon,
139
- buttonProps
140
- }) => {
141
- const btnCSS = getButtonCss(pattern);
142
- const handleClick = /* @__PURE__ */ __name((e) => {
143
- if (buttonProps?.disabled) return;
144
- buttonProps?.onClick?.(e);
145
- }, "handleClick");
146
- return /* @__PURE__ */ jsxRuntime.jsxs(
133
+ buttonProps,
134
+ ref
135
+ }) => (
136
+ // The classes that are given come last but do not remove the button's own: to win over one of
137
+ // them give it with `!` (`rounded-md!`), the way the toast's button does.
138
+ /* @__PURE__ */ jsxRuntime.jsxs(
147
139
  "button",
148
140
  {
149
141
  ...buttonProps,
150
- className: `group flex w-full cursor-pointer items-center justify-center gap-1 rounded-lg px-4 py-3 text-sm leading-4 transition-all duration-300 disabled:cursor-not-allowed disabled:opacity-85 lg:px-5 lg:py-4 xl:text-base ${btnCSS} ${className} ${buttonProps?.className ?? ""}`,
142
+ ref,
143
+ className: `${BASE_CSS} ${getButtonCss(pattern)} ${className} ${buttonProps?.className ?? ""}`,
151
144
  type: buttonProps?.type ?? "button",
152
- onClick: handleClick,
153
145
  children: [
154
- leftIcon && /* @__PURE__ */ jsxRuntime.jsx(react.Icon, { ...leftIcon }),
155
- typeof content === "object" ? /* @__PURE__ */ jsxRuntime.jsx(react.Icon, { ...content }) : content,
156
- rightIcon && /* @__PURE__ */ jsxRuntime.jsx(react.Icon, { ...rightIcon })
146
+ leftIcon && /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { ...leftIcon }),
147
+ typeof content === "object" ? /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { ...content }) : content,
148
+ rightIcon && /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { ...rightIcon })
157
149
  ]
158
150
  }
159
- );
160
- }, "Button");
151
+ )
152
+ ), "Button");
161
153
 
162
154
  // src/toast/toaster.ts
163
155
  var { add, update, remove } = useToastStore.getState();
@@ -418,7 +410,7 @@ var UploadRow = /* @__PURE__ */ __name(({ item }) => {
418
410
  const { icon, rgb } = UPLOAD_ITEM_ICON[item.status];
419
411
  return /* @__PURE__ */ jsxRuntime.jsxs("li", { "data-status": item.status, className: "flex items-center gap-1.5 md:gap-2", children: [
420
412
  /* @__PURE__ */ jsxRuntime.jsx(
421
- react.Icon,
413
+ react$1.Icon,
422
414
  {
423
415
  icon,
424
416
  className: "size-3.5 shrink-0 md:size-4",
@@ -478,7 +470,7 @@ var cardConfig = /* @__PURE__ */ __name((type) => {
478
470
  return { iconName: "solar:info-circle-outline", rgb: "var(--primary-rgb)" };
479
471
  }
480
472
  }, "cardConfig");
481
- var Toaster = /* @__PURE__ */ __name((props) => {
473
+ var ToasterItem = /* @__PURE__ */ __name((props) => {
482
474
  const {
483
475
  className = "",
484
476
  type,
@@ -489,9 +481,9 @@ var Toaster = /* @__PURE__ */ __name((props) => {
489
481
  closeTimer = 5e3
490
482
  } = props;
491
483
  const remove2 = useToastStore((s) => s.remove);
492
- const [visible, setVisible] = react$1.useState(false);
493
- const [mounted, setMounted] = react$1.useState(true);
494
- const timeoutRef = react$1.useRef(null);
484
+ const [visible, setVisible] = react.useState(false);
485
+ const [mounted, setMounted] = react.useState(true);
486
+ const timeoutRef = react.useRef(null);
495
487
  const uploadsSummary = props.type === TOAST_TYPE.uploads ? getUploadsSummary(props.items) : null;
496
488
  const isUploadsSettled = uploadsSummary?.isSettled ?? false;
497
489
  let resolvedAutoClose = autoClose;
@@ -506,14 +498,14 @@ var Toaster = /* @__PURE__ */ __name((props) => {
506
498
  resolvedCloseTimer = uploadsSummary.failed > 0 ? 8e3 : 2500;
507
499
  }
508
500
  const config = uploadsSummary ? { iconName: "", rgb: uploadsRgb(uploadsSummary) } : cardConfig(type);
509
- const handleClose = react$1.useCallback(() => {
501
+ const handleClose = react.useCallback(() => {
510
502
  setVisible(false);
511
503
  timeoutRef.current = setTimeout(() => {
512
504
  setMounted(false);
513
505
  remove2(props.id);
514
506
  }, 300);
515
507
  }, [remove2, props.id]);
516
- react$1.useEffect(() => {
508
+ react.useEffect(() => {
517
509
  const enterTimer = setTimeout(() => {
518
510
  setVisible(true);
519
511
  }, 50);
@@ -552,7 +544,7 @@ var Toaster = /* @__PURE__ */ __name((props) => {
552
544
  progress: uploadsSummary.percent,
553
545
  style: { color: `rgb(${config.rgb})` }
554
546
  }
555
- ) : /* @__PURE__ */ jsxRuntime.jsx(react.Icon, { icon: config.iconName, style: { color: `rgb(${config.rgb})` } })),
547
+ ) : /* @__PURE__ */ jsxRuntime.jsx(react$1.Icon, { icon: config.iconName, style: { color: `rgb(${config.rgb})` } })),
556
548
  props.type === TOAST_TYPE.uploads && uploadsSummary ? /* @__PURE__ */ jsxRuntime.jsx(
557
549
  UploadsBody,
558
550
  {
@@ -586,7 +578,7 @@ var Toaster = /* @__PURE__ */ __name((props) => {
586
578
  )
587
579
  ] }),
588
580
  resolvedIsClosable && /* @__PURE__ */ jsxRuntime.jsx(
589
- react.Icon,
581
+ react$1.Icon,
590
582
  {
591
583
  icon: "lucide:x",
592
584
  className: "text-primary cursor-pointer md:size-5",
@@ -596,7 +588,8 @@ var Toaster = /* @__PURE__ */ __name((props) => {
596
588
  ] })
597
589
  }
598
590
  );
599
- }, "Toaster");
591
+ }, "ToasterItem");
592
+ var Toaster = react.memo(ToasterItem);
600
593
  var ToastContainer = /* @__PURE__ */ __name(() => {
601
594
  const toasts = useToastStore((s) => s.toasts);
602
595
  if (toasts.length === 0) return null;