@lindle/linoardo 1.0.23 → 1.0.25

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 (70) hide show
  1. package/dist/alert.cjs +18 -0
  2. package/dist/alert.cjs.map +1 -0
  3. package/dist/alert.d.cts +9 -0
  4. package/dist/alert.d.ts +9 -0
  5. package/dist/alert.js +3 -0
  6. package/dist/alert.js.map +1 -0
  7. package/dist/app-bar.cjs +168 -0
  8. package/dist/app-bar.cjs.map +1 -0
  9. package/dist/app-bar.d.cts +25 -0
  10. package/dist/app-bar.d.ts +25 -0
  11. package/dist/app-bar.js +3 -0
  12. package/dist/app-bar.js.map +1 -0
  13. package/dist/badge.cjs +205 -0
  14. package/dist/badge.cjs.map +1 -0
  15. package/dist/badge.d.cts +71 -0
  16. package/dist/badge.d.ts +71 -0
  17. package/dist/badge.js +3 -0
  18. package/dist/badge.js.map +1 -0
  19. package/dist/block.cjs +70 -0
  20. package/dist/block.cjs.map +1 -0
  21. package/dist/block.d.cts +32 -0
  22. package/dist/block.d.ts +32 -0
  23. package/dist/block.js +3 -0
  24. package/dist/block.js.map +1 -0
  25. package/dist/chunk-5GT6L4BE.js +48 -0
  26. package/dist/chunk-5GT6L4BE.js.map +1 -0
  27. package/dist/chunk-67BAO35I.js +146 -0
  28. package/dist/chunk-67BAO35I.js.map +1 -0
  29. package/dist/chunk-6SKW43XI.js +14 -0
  30. package/dist/chunk-6SKW43XI.js.map +1 -0
  31. package/dist/{chunk-JGEXEDKS.js → chunk-AUFMBVXA.js} +5 -5
  32. package/dist/{chunk-JGEXEDKS.js.map → chunk-AUFMBVXA.js.map} +1 -1
  33. package/dist/{chunk-SAGQYMS3.js → chunk-BZVDAMMY.js} +13 -16
  34. package/dist/chunk-BZVDAMMY.js.map +1 -0
  35. package/dist/chunk-HIRPMCQJ.js +183 -0
  36. package/dist/chunk-HIRPMCQJ.js.map +1 -0
  37. package/dist/{chunk-67USTSXI.js → chunk-KI4DBZ2V.js} +5 -3
  38. package/dist/chunk-KI4DBZ2V.js.map +1 -0
  39. package/dist/chunk-KQOR3C7E.js +16 -0
  40. package/dist/chunk-KQOR3C7E.js.map +1 -0
  41. package/dist/chunk-SCJMH5VE.js +469 -0
  42. package/dist/chunk-SCJMH5VE.js.map +1 -0
  43. package/dist/index.cjs +731 -72
  44. package/dist/index.cjs.map +1 -1
  45. package/dist/index.d.cts +8 -55
  46. package/dist/index.d.ts +8 -55
  47. package/dist/index.js +14 -190
  48. package/dist/index.js.map +1 -1
  49. package/dist/input.cjs +3 -3
  50. package/dist/input.cjs.map +1 -1
  51. package/dist/input.js +1 -1
  52. package/dist/notification.cjs +3 -1
  53. package/dist/notification.cjs.map +1 -1
  54. package/dist/notification.d.cts +1 -0
  55. package/dist/notification.d.ts +1 -0
  56. package/dist/notification.js +1 -1
  57. package/dist/select.cjs +10 -2
  58. package/dist/select.cjs.map +1 -1
  59. package/dist/select.js +2 -1
  60. package/dist/styles.css +13 -0
  61. package/dist/textarea.cjs +486 -0
  62. package/dist/textarea.cjs.map +1 -0
  63. package/dist/textarea.d.cts +29 -0
  64. package/dist/textarea.d.ts +29 -0
  65. package/dist/textarea.js +4 -0
  66. package/dist/textarea.js.map +1 -0
  67. package/package.json +36 -1
  68. package/readme.md +46 -0
  69. package/dist/chunk-67USTSXI.js.map +0 -1
  70. package/dist/chunk-SAGQYMS3.js.map +0 -1
@@ -0,0 +1,71 @@
1
+ import * as react from 'react';
2
+ import { P as Palette } from './global.types-E2uVLemv.js';
3
+
4
+ type BadgePlacement = 'top-end' | 'top-start' | 'bottom-end' | 'bottom-start' | 'center';
5
+ type IconDefinition = string | [library: string, icon: string];
6
+ type BaseSpanProps = Omit<React.HTMLAttributes<HTMLSpanElement>, 'content'>;
7
+ interface BadgeProps extends BaseSpanProps {
8
+ /**
9
+ * Content displayed inside the badge. Ignored when dot mode is enabled.
10
+ */
11
+ content?: React.ReactNode;
12
+ /**
13
+ * Caps numeric content and adds a "+" suffix when overflowed.
14
+ */
15
+ max?: number;
16
+ /**
17
+ * Controls whether zero numeric values should be rendered.
18
+ */
19
+ showZero?: boolean;
20
+ /**
21
+ * Renders the badge as a small dot without inner content.
22
+ */
23
+ dot?: boolean;
24
+ /**
25
+ * Optional icon name. Supports Material Design Icons by default.
26
+ */
27
+ icon?: IconDefinition;
28
+ /**
29
+ * Visual palette used for the badge background and text.
30
+ */
31
+ color?: Palette;
32
+ /**
33
+ * Defines the anchor point relative to the wrapped content.
34
+ */
35
+ placement?: BadgePlacement;
36
+ /**
37
+ * Fine-grained positional adjustment in pixels [x, y].
38
+ */
39
+ offset?: [x?: number, y?: number];
40
+ /**
41
+ * Controls whether the badge overlaps its anchor element.
42
+ */
43
+ overlap?: boolean;
44
+ /**
45
+ * Adds a subtle border around the badge for contrast.
46
+ */
47
+ bordered?: boolean;
48
+ /**
49
+ * Switches to inline rendering so the badge is not absolutely positioned.
50
+ */
51
+ floating?: boolean;
52
+ /**
53
+ * Toggles display regardless of whether content is provided.
54
+ */
55
+ visible?: boolean;
56
+ /**
57
+ * Additional class name applied to the badge itself.
58
+ */
59
+ badgeClassName?: string;
60
+ /**
61
+ * Chooses between inline-flex and block-level layout for the root wrapper.
62
+ */
63
+ inline?: boolean;
64
+ }
65
+
66
+ /**
67
+ * Notification badge that can render numbers, dots or icons with flexible positioning.
68
+ */
69
+ declare const Badge: react.FC<BadgeProps>;
70
+
71
+ export { Badge as default };
package/dist/badge.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Badge_default as default } from './chunk-HIRPMCQJ.js';
2
+ //# sourceMappingURL=badge.js.map
3
+ //# sourceMappingURL=badge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"badge.js"}
package/dist/block.cjs ADDED
@@ -0,0 +1,70 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var tailwindMerge = require('tailwind-merge');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
26
+
27
+ // src/Blocks/Block/index.tsx
28
+ var blockBase = "block-base relative overflow-hidden text-gray-900 dark:text-slate-100";
29
+ var blurClasses = {
30
+ none: "backdrop-blur-none",
31
+ sm: "backdrop-blur-sm",
32
+ base: "backdrop-blur",
33
+ md: "backdrop-blur-md",
34
+ lg: "backdrop-blur-lg",
35
+ xl: "backdrop-blur-xl",
36
+ "2xl": "backdrop-blur-2xl",
37
+ "3xl": "backdrop-blur-3xl"
38
+ };
39
+ var variantClasses = {
40
+ solid: "rounded-xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10",
41
+ outline: "rounded-xl bg-white/10 backdrop-opacity-5 border border-white/60 dark:bg-slate-900/30 dark:border-white/20",
42
+ text: "rounded-xl bg-transparent border border-transparent",
43
+ ghost: "rounded-xl bg-white/20 backdrop-opacity-5 border border-white/20 dark:bg-slate-900/30 dark:border-white/10",
44
+ filled: "rounded-xl bg-white/60 backdrop-opacity-5 border border-white/40 dark:bg-slate-900/70 dark:border-white/15",
45
+ underlined: "rounded-xl bg-white/20 backdrop-opacity-5 border-b border-white/40 dark:bg-slate-900/30 dark:border-white/20",
46
+ rounded: "rounded-3xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10",
47
+ sharp: "rounded-none bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10"
48
+ };
49
+ var Block = React__namespace.forwardRef(function Block2({ className, variant = "solid", blur = "sm", interactive = false, children, ...rest }, ref) {
50
+ const variantClass = variantClasses[variant] ?? variantClasses.solid;
51
+ const blurClass = blurClasses[blur] ?? blurClasses.sm;
52
+ const interactiveClass = interactive ? "transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900" : void 0;
53
+ const tabIndexValue = interactive && rest.tabIndex === void 0 ? 0 : rest.tabIndex;
54
+ return /* @__PURE__ */ jsxRuntime.jsx(
55
+ "div",
56
+ {
57
+ ...rest,
58
+ ref,
59
+ tabIndex: tabIndexValue,
60
+ className: tailwindMerge.twMerge(blockBase, variantClass, blurClass, "p-2", interactiveClass, className),
61
+ children
62
+ }
63
+ );
64
+ });
65
+ Block.displayName = "Block";
66
+ var Block_default = Block;
67
+
68
+ module.exports = Block_default;
69
+ //# sourceMappingURL=block.cjs.map
70
+ //# sourceMappingURL=block.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Blocks/Block/index.tsx"],"names":["React","Block","jsx","twMerge"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAM,SAAA,GAAY,uEAAA;AAElB,IAAM,WAAA,GAAyC;AAAA,EAC7C,IAAA,EAAM,oBAAA;AAAA,EACN,EAAA,EAAI,kBAAA;AAAA,EACJ,IAAA,EAAM,eAAA;AAAA,EACN,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI,kBAAA;AAAA,EACJ,KAAA,EAAO,mBAAA;AAAA,EACP,KAAA,EAAO;AACT,CAAA;AAEA,IAAM,cAAA,GAAgD;AAAA,EACpD,KAAA,EACE,4GAAA;AAAA,EACF,OAAA,EACE,4GAAA;AAAA,EACF,IAAA,EAAM,qDAAA;AAAA,EACN,KAAA,EACE,4GAAA;AAAA,EACF,MAAA,EACE,4GAAA;AAAA,EACF,UAAA,EACE,8GAAA;AAAA,EACF,OAAA,EACE,6GAAA;AAAA,EACF,KAAA,EACE;AACJ,CAAA;AAKA,IAAM,QAAcA,gBAAA,CAAA,UAAA,CAAuC,SAASC,MAAAA,CAClE,EAAE,WAAW,OAAA,GAAU,OAAA,EAAS,IAAA,GAAO,IAAA,EAAM,cAAc,KAAA,EAAO,QAAA,EAAU,GAAG,IAAA,IAC/E,GAAA,EACA;AACA,EAAA,MAAM,YAAA,GAAe,cAAA,CAAe,OAAO,CAAA,IAAK,cAAA,CAAe,KAAA;AAC/D,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAI,CAAA,IAAK,WAAA,CAAY,EAAA;AACnD,EAAA,MAAM,gBAAA,GAAmB,cACrB,uPAAA,GACA,MAAA;AACJ,EAAA,MAAM,gBAAgB,WAAA,IAAe,IAAA,CAAK,QAAA,KAAa,MAAA,GAAY,IAAI,IAAA,CAAK,QAAA;AAE5E,EAAA,uBACEC,cAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MACA,QAAA,EAAU,aAAA;AAAA,MACV,WAAWC,qBAAA,CAAQ,SAAA,EAAW,cAAc,SAAA,EAAW,KAAA,EAAO,kBAAkB,SAAS,CAAA;AAAA,MAExF;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,KAAA,CAAM,WAAA,GAAc,OAAA;AAIpB,IAAO,aAAA,GAAQ","file":"block.cjs","sourcesContent":["import * as React from 'react';\nimport type { GlobalVariant } from '@lindle/linoardo/global.types';\nimport { twMerge } from 'tailwind-merge';\nimport type { BlockBlur, BlockProps } from './types.block';\n\nconst blockBase = 'block-base relative overflow-hidden text-gray-900 dark:text-slate-100';\n\nconst blurClasses: Record<BlockBlur, string> = {\n none: 'backdrop-blur-none',\n sm: 'backdrop-blur-sm',\n base: 'backdrop-blur',\n md: 'backdrop-blur-md',\n lg: 'backdrop-blur-lg',\n xl: 'backdrop-blur-xl',\n '2xl': 'backdrop-blur-2xl',\n '3xl': 'backdrop-blur-3xl'\n};\n\nconst variantClasses: Record<GlobalVariant, string> = {\n solid:\n 'rounded-xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10',\n outline:\n 'rounded-xl bg-white/10 backdrop-opacity-5 border border-white/60 dark:bg-slate-900/30 dark:border-white/20',\n text: 'rounded-xl bg-transparent border border-transparent',\n ghost:\n 'rounded-xl bg-white/20 backdrop-opacity-5 border border-white/20 dark:bg-slate-900/30 dark:border-white/10',\n filled:\n 'rounded-xl bg-white/60 backdrop-opacity-5 border border-white/40 dark:bg-slate-900/70 dark:border-white/15',\n underlined:\n 'rounded-xl bg-white/20 backdrop-opacity-5 border-b border-white/40 dark:bg-slate-900/30 dark:border-white/20',\n rounded:\n 'rounded-3xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10',\n sharp:\n 'rounded-none bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10'\n};\n\n/**\n * Glass-like block container with blur and shared variant styling.\n */\nconst Block = React.forwardRef<HTMLDivElement, BlockProps>(function Block(\n { className, variant = 'solid', blur = 'sm', interactive = false, children, ...rest },\n ref\n) {\n const variantClass = variantClasses[variant] ?? variantClasses.solid;\n const blurClass = blurClasses[blur] ?? blurClasses.sm;\n const interactiveClass = interactive\n ? 'transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900'\n : undefined;\n const tabIndexValue = interactive && rest.tabIndex === undefined ? 0 : rest.tabIndex;\n\n return (\n <div\n {...rest}\n ref={ref}\n tabIndex={tabIndexValue}\n className={twMerge(blockBase, variantClass, blurClass, 'p-2', interactiveClass, className)}\n >\n {children}\n </div>\n );\n});\n\nBlock.displayName = 'Block';\n\nexport type { BlockProps, BlockBlur };\n\nexport default Block;\n"]}
@@ -0,0 +1,32 @@
1
+ import * as react from 'react';
2
+ import { G as GlobalVariant } from './global.types-E2uVLemv.cjs';
3
+
4
+ type BlockBlur = 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
5
+ type BlockProps = react.HTMLAttributes<HTMLDivElement> & {
6
+ /**
7
+ * Visual variant shared across Block components.
8
+ * @default 'solid'
9
+ */
10
+ variant?: GlobalVariant;
11
+ /**
12
+ * Backdrop blur intensity mapped to Tailwind's `backdrop-blur-*` utilities.
13
+ * @default 'sm'
14
+ */
15
+ blur?: BlockBlur;
16
+ /**
17
+ * Adds hover + focus ring styles for interactive usage.
18
+ * @default false
19
+ */
20
+ interactive?: boolean;
21
+ };
22
+
23
+ /**
24
+ * Glass-like block container with blur and shared variant styling.
25
+ */
26
+ declare const Block: react.ForwardRefExoticComponent<react.HTMLAttributes<HTMLDivElement> & {
27
+ variant?: GlobalVariant;
28
+ blur?: BlockBlur;
29
+ interactive?: boolean;
30
+ } & react.RefAttributes<HTMLDivElement>>;
31
+
32
+ export { type BlockBlur, type BlockProps, Block as default };
@@ -0,0 +1,32 @@
1
+ import * as react from 'react';
2
+ import { G as GlobalVariant } from './global.types-E2uVLemv.js';
3
+
4
+ type BlockBlur = 'none' | 'sm' | 'base' | 'md' | 'lg' | 'xl' | '2xl' | '3xl';
5
+ type BlockProps = react.HTMLAttributes<HTMLDivElement> & {
6
+ /**
7
+ * Visual variant shared across Block components.
8
+ * @default 'solid'
9
+ */
10
+ variant?: GlobalVariant;
11
+ /**
12
+ * Backdrop blur intensity mapped to Tailwind's `backdrop-blur-*` utilities.
13
+ * @default 'sm'
14
+ */
15
+ blur?: BlockBlur;
16
+ /**
17
+ * Adds hover + focus ring styles for interactive usage.
18
+ * @default false
19
+ */
20
+ interactive?: boolean;
21
+ };
22
+
23
+ /**
24
+ * Glass-like block container with blur and shared variant styling.
25
+ */
26
+ declare const Block: react.ForwardRefExoticComponent<react.HTMLAttributes<HTMLDivElement> & {
27
+ variant?: GlobalVariant;
28
+ blur?: BlockBlur;
29
+ interactive?: boolean;
30
+ } & react.RefAttributes<HTMLDivElement>>;
31
+
32
+ export { type BlockBlur, type BlockProps, Block as default };
package/dist/block.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Block_default as default } from './chunk-5GT6L4BE.js';
2
+ //# sourceMappingURL=block.js.map
3
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"block.js"}
@@ -0,0 +1,48 @@
1
+ import * as React from 'react';
2
+ import { twMerge } from 'tailwind-merge';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // src/Blocks/Block/index.tsx
6
+ var blockBase = "block-base relative overflow-hidden text-gray-900 dark:text-slate-100";
7
+ var blurClasses = {
8
+ none: "backdrop-blur-none",
9
+ sm: "backdrop-blur-sm",
10
+ base: "backdrop-blur",
11
+ md: "backdrop-blur-md",
12
+ lg: "backdrop-blur-lg",
13
+ xl: "backdrop-blur-xl",
14
+ "2xl": "backdrop-blur-2xl",
15
+ "3xl": "backdrop-blur-3xl"
16
+ };
17
+ var variantClasses = {
18
+ solid: "rounded-xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10",
19
+ outline: "rounded-xl bg-white/10 backdrop-opacity-5 border border-white/60 dark:bg-slate-900/30 dark:border-white/20",
20
+ text: "rounded-xl bg-transparent border border-transparent",
21
+ ghost: "rounded-xl bg-white/20 backdrop-opacity-5 border border-white/20 dark:bg-slate-900/30 dark:border-white/10",
22
+ filled: "rounded-xl bg-white/60 backdrop-opacity-5 border border-white/40 dark:bg-slate-900/70 dark:border-white/15",
23
+ underlined: "rounded-xl bg-white/20 backdrop-opacity-5 border-b border-white/40 dark:bg-slate-900/30 dark:border-white/20",
24
+ rounded: "rounded-3xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10",
25
+ sharp: "rounded-none bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10"
26
+ };
27
+ var Block = React.forwardRef(function Block2({ className, variant = "solid", blur = "sm", interactive = false, children, ...rest }, ref) {
28
+ const variantClass = variantClasses[variant] ?? variantClasses.solid;
29
+ const blurClass = blurClasses[blur] ?? blurClasses.sm;
30
+ const interactiveClass = interactive ? "transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900" : void 0;
31
+ const tabIndexValue = interactive && rest.tabIndex === void 0 ? 0 : rest.tabIndex;
32
+ return /* @__PURE__ */ jsx(
33
+ "div",
34
+ {
35
+ ...rest,
36
+ ref,
37
+ tabIndex: tabIndexValue,
38
+ className: twMerge(blockBase, variantClass, blurClass, "p-2", interactiveClass, className),
39
+ children
40
+ }
41
+ );
42
+ });
43
+ Block.displayName = "Block";
44
+ var Block_default = Block;
45
+
46
+ export { Block_default };
47
+ //# sourceMappingURL=chunk-5GT6L4BE.js.map
48
+ //# sourceMappingURL=chunk-5GT6L4BE.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Blocks/Block/index.tsx"],"names":["Block"],"mappings":";;;;;AAKA,IAAM,SAAA,GAAY,uEAAA;AAElB,IAAM,WAAA,GAAyC;AAAA,EAC7C,IAAA,EAAM,oBAAA;AAAA,EACN,EAAA,EAAI,kBAAA;AAAA,EACJ,IAAA,EAAM,eAAA;AAAA,EACN,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI,kBAAA;AAAA,EACJ,EAAA,EAAI,kBAAA;AAAA,EACJ,KAAA,EAAO,mBAAA;AAAA,EACP,KAAA,EAAO;AACT,CAAA;AAEA,IAAM,cAAA,GAAgD;AAAA,EACpD,KAAA,EACE,4GAAA;AAAA,EACF,OAAA,EACE,4GAAA;AAAA,EACF,IAAA,EAAM,qDAAA;AAAA,EACN,KAAA,EACE,4GAAA;AAAA,EACF,MAAA,EACE,4GAAA;AAAA,EACF,UAAA,EACE,8GAAA;AAAA,EACF,OAAA,EACE,6GAAA;AAAA,EACF,KAAA,EACE;AACJ,CAAA;AAKA,IAAM,QAAc,KAAA,CAAA,UAAA,CAAuC,SAASA,MAAAA,CAClE,EAAE,WAAW,OAAA,GAAU,OAAA,EAAS,IAAA,GAAO,IAAA,EAAM,cAAc,KAAA,EAAO,QAAA,EAAU,GAAG,IAAA,IAC/E,GAAA,EACA;AACA,EAAA,MAAM,YAAA,GAAe,cAAA,CAAe,OAAO,CAAA,IAAK,cAAA,CAAe,KAAA;AAC/D,EAAA,MAAM,SAAA,GAAY,WAAA,CAAY,IAAI,CAAA,IAAK,WAAA,CAAY,EAAA;AACnD,EAAA,MAAM,gBAAA,GAAmB,cACrB,uPAAA,GACA,MAAA;AACJ,EAAA,MAAM,gBAAgB,WAAA,IAAe,IAAA,CAAK,QAAA,KAAa,MAAA,GAAY,IAAI,IAAA,CAAK,QAAA;AAE5E,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,IAAA;AAAA,MACJ,GAAA;AAAA,MACA,QAAA,EAAU,aAAA;AAAA,MACV,WAAW,OAAA,CAAQ,SAAA,EAAW,cAAc,SAAA,EAAW,KAAA,EAAO,kBAAkB,SAAS,CAAA;AAAA,MAExF;AAAA;AAAA,GACH;AAEJ,CAAC,CAAA;AAED,KAAA,CAAM,WAAA,GAAc,OAAA;AAIpB,IAAO,aAAA,GAAQ","file":"chunk-5GT6L4BE.js","sourcesContent":["import * as React from 'react';\nimport type { GlobalVariant } from '@lindle/linoardo/global.types';\nimport { twMerge } from 'tailwind-merge';\nimport type { BlockBlur, BlockProps } from './types.block';\n\nconst blockBase = 'block-base relative overflow-hidden text-gray-900 dark:text-slate-100';\n\nconst blurClasses: Record<BlockBlur, string> = {\n none: 'backdrop-blur-none',\n sm: 'backdrop-blur-sm',\n base: 'backdrop-blur',\n md: 'backdrop-blur-md',\n lg: 'backdrop-blur-lg',\n xl: 'backdrop-blur-xl',\n '2xl': 'backdrop-blur-2xl',\n '3xl': 'backdrop-blur-3xl'\n};\n\nconst variantClasses: Record<GlobalVariant, string> = {\n solid:\n 'rounded-xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10',\n outline:\n 'rounded-xl bg-white/10 backdrop-opacity-5 border border-white/60 dark:bg-slate-900/30 dark:border-white/20',\n text: 'rounded-xl bg-transparent border border-transparent',\n ghost:\n 'rounded-xl bg-white/20 backdrop-opacity-5 border border-white/20 dark:bg-slate-900/30 dark:border-white/10',\n filled:\n 'rounded-xl bg-white/60 backdrop-opacity-5 border border-white/40 dark:bg-slate-900/70 dark:border-white/15',\n underlined:\n 'rounded-xl bg-white/20 backdrop-opacity-5 border-b border-white/40 dark:bg-slate-900/30 dark:border-white/20',\n rounded:\n 'rounded-3xl bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10',\n sharp:\n 'rounded-none bg-white/40 backdrop-opacity-5 border border-white/30 dark:bg-slate-900/50 dark:border-white/10'\n};\n\n/**\n * Glass-like block container with blur and shared variant styling.\n */\nconst Block = React.forwardRef<HTMLDivElement, BlockProps>(function Block(\n { className, variant = 'solid', blur = 'sm', interactive = false, children, ...rest },\n ref\n) {\n const variantClass = variantClasses[variant] ?? variantClasses.solid;\n const blurClass = blurClasses[blur] ?? blurClasses.sm;\n const interactiveClass = interactive\n ? 'transition-all duration-200 hover:-translate-y-0.5 hover:shadow-xl focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-white dark:focus-visible:ring-offset-slate-900'\n : undefined;\n const tabIndexValue = interactive && rest.tabIndex === undefined ? 0 : rest.tabIndex;\n\n return (\n <div\n {...rest}\n ref={ref}\n tabIndex={tabIndexValue}\n className={twMerge(blockBase, variantClass, blurClass, 'p-2', interactiveClass, className)}\n >\n {children}\n </div>\n );\n});\n\nBlock.displayName = 'Block';\n\nexport type { BlockProps, BlockBlur };\n\nexport default Block;\n"]}
@@ -0,0 +1,146 @@
1
+ import * as React from 'react';
2
+ import { twMerge } from 'tailwind-merge';
3
+ import { jsxs, jsx } from 'react/jsx-runtime';
4
+
5
+ // src/Blocks/AppBar/index.tsx
6
+ var positionClasses = {
7
+ fixed: "fixed inset-x-0 top-0",
8
+ absolute: "absolute inset-x-0 top-0",
9
+ sticky: "sticky inset-x-0 top-0",
10
+ static: "static",
11
+ relative: "relative"
12
+ };
13
+ var colorClasses = {
14
+ primary: "bg-primary text-white",
15
+ surface: "bg-white text-gray-900 border-b border-gray-200",
16
+ muted: "bg-gray-50 text-gray-900 border-b border-gray-200",
17
+ dark: "bg-gray-900 text-white",
18
+ transparent: "bg-transparent text-inherit"
19
+ };
20
+ var AppBar = ({
21
+ title,
22
+ logo,
23
+ logoAlt = "Logo",
24
+ brandHref,
25
+ navigation = [],
26
+ actions,
27
+ position = "static",
28
+ color = "surface",
29
+ dense = false,
30
+ elevated = true,
31
+ contained = true,
32
+ titlePosition = "start",
33
+ className,
34
+ children,
35
+ ...rest
36
+ }) => {
37
+ const [mobileOpen, setMobileOpen] = React.useState(false);
38
+ const isDark = color === "primary" || color === "dark";
39
+ const isTransparent = color === "transparent";
40
+ const barClass = twMerge(
41
+ "app-bar z-40 w-full backdrop-blur-md",
42
+ positionClasses[position] ?? positionClasses.static,
43
+ colorClasses[color] ?? colorClasses.surface,
44
+ elevated && !isTransparent ? "shadow-sm shadow-black/10" : void 0,
45
+ "relative",
46
+ className
47
+ );
48
+ const innerClass = twMerge(
49
+ "mx-auto flex w-full items-center gap-4",
50
+ contained ? "max-w-6xl px-4 sm:px-6 lg:px-8" : "px-4",
51
+ dense ? "py-2.5" : "py-4"
52
+ );
53
+ const brandTextClass = isDark ? "text-white" : "text-gray-900";
54
+ const navBaseClass = twMerge(
55
+ "inline-flex items-center gap-2 rounded-xl px-3 py-2 text-sm font-medium transition focus-visible:outline-none",
56
+ isDark ? "hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-white/70" : "hover:bg-gray-100 focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"
57
+ );
58
+ const navActiveClass = isDark ? "bg-white/15 text-white" : "bg-primary/10 text-primary";
59
+ const renderNavItem = (item, index) => {
60
+ const { href, label, active, onClick } = item;
61
+ const Component = href ? "a" : "button";
62
+ const resolvedHref = href && href.trim().length > 0 ? href : void 0;
63
+ return /* @__PURE__ */ jsx(
64
+ Component,
65
+ {
66
+ href: resolvedHref,
67
+ onClick,
68
+ className: twMerge(navBaseClass, active ? navActiveClass : void 0),
69
+ "aria-current": active ? "page" : void 0,
70
+ children: label
71
+ },
72
+ `${resolvedHref ?? "item"}-${index}`
73
+ );
74
+ };
75
+ const brandAlignClass = titlePosition === "center" ? "justify-self-center text-center" : titlePosition === "end" ? "justify-self-end text-right" : "justify-self-start";
76
+ const brandNode = title || logo ? /* @__PURE__ */ jsxs("div", { className: twMerge("flex min-w-0 items-center gap-3", brandAlignClass), children: [
77
+ logo ? /* @__PURE__ */ jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-white/10 ring-1 ring-black/5", children: /* @__PURE__ */ jsx(
78
+ "img",
79
+ {
80
+ src: logo,
81
+ alt: logoAlt,
82
+ className: "h-full w-full object-cover",
83
+ loading: "lazy",
84
+ decoding: "async"
85
+ }
86
+ ) }) : null,
87
+ /* @__PURE__ */ jsx("div", { className: "min-w-0", children: title ? /* @__PURE__ */ jsx("div", { className: twMerge("text-base font-semibold leading-tight", brandTextClass), children: brandHref ? /* @__PURE__ */ jsx("a", { href: brandHref, className: "hover:underline focus-visible:outline-none", children: title }) : title }) : null })
88
+ ] }) : null;
89
+ return /* @__PURE__ */ jsxs("header", { ...rest, className: barClass, children: [
90
+ /* @__PURE__ */ jsx("div", { className: innerClass, children: /* @__PURE__ */ jsxs("div", { className: "grid w-full grid-cols-[auto_1fr_auto] items-center gap-3", children: [
91
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
92
+ navigation.length > 0 ? /* @__PURE__ */ jsx(
93
+ "button",
94
+ {
95
+ type: "button",
96
+ "aria-label": "Otev\u0159\xEDt navigaci",
97
+ className: twMerge(
98
+ "inline-flex h-10 w-10 items-center justify-center rounded-xl text-xl sm:hidden",
99
+ isDark ? "text-white hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-white/60" : "text-gray-700 hover:bg-gray-100 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent"
100
+ ),
101
+ "aria-expanded": mobileOpen,
102
+ onClick: () => setMobileOpen((open) => !open),
103
+ children: /* @__PURE__ */ jsx("i", { className: mobileOpen ? "mdi mdi-close" : "mdi mdi-menu", "aria-hidden": true })
104
+ }
105
+ ) : null,
106
+ navigation.length > 0 ? /* @__PURE__ */ jsx("nav", { className: "hidden items-center gap-1 sm:flex", "aria-label": "Hlavni navigace", children: navigation.map(renderNavItem) }) : null
107
+ ] }),
108
+ brandNode,
109
+ /* @__PURE__ */ jsxs("div", { className: "ml-auto flex items-center justify-end gap-2", children: [
110
+ children,
111
+ actions
112
+ ] })
113
+ ] }) }),
114
+ navigation.length > 0 && mobileOpen ? /* @__PURE__ */ jsx("div", { className: "sm:hidden", children: /* @__PURE__ */ jsx("nav", { className: "absolute inset-x-0 top-full border-t border-gray-200/70 bg-white/95 p-3 shadow-lg shadow-gray-900/5 backdrop-blur-md", children: /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-2", "aria-label": "Mobilni navigace", children: navigation.map((item, index) => {
115
+ const { href, label, active, onClick } = item;
116
+ const Component = href ? "a" : "button";
117
+ const resolvedHref = href && href.trim().length > 0 ? href : void 0;
118
+ return /* @__PURE__ */ jsxs(
119
+ Component,
120
+ {
121
+ href: resolvedHref,
122
+ onClick: (event) => {
123
+ onClick?.(event);
124
+ setMobileOpen(false);
125
+ },
126
+ className: twMerge(
127
+ "flex items-center justify-between rounded-xl px-3 py-2 text-sm font-medium transition",
128
+ active ? "bg-primary/10 text-primary" : "text-gray-800 hover:bg-gray-100"
129
+ ),
130
+ "aria-current": active ? "page" : void 0,
131
+ children: [
132
+ label,
133
+ active ? /* @__PURE__ */ jsx("i", { className: "mdi mdi-circle-small text-primary", "aria-hidden": true }) : null
134
+ ]
135
+ },
136
+ `${resolvedHref ?? "mobile-item"}-${index}`
137
+ );
138
+ }) }) }) }) : null
139
+ ] });
140
+ };
141
+ AppBar.displayName = "AppBar";
142
+ var AppBar_default = AppBar;
143
+
144
+ export { AppBar_default };
145
+ //# sourceMappingURL=chunk-67BAO35I.js.map
146
+ //# sourceMappingURL=chunk-67BAO35I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Blocks/AppBar/index.tsx"],"names":[],"mappings":"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","file":"chunk-67BAO35I.js","sourcesContent":["import * as React from 'react';\nimport { twMerge } from 'tailwind-merge';\n\nexport type AppBarNavItem = {\n label: React.ReactNode;\n href?: string;\n active?: boolean;\n onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLButtonElement>;\n};\n\nexport type AppBarProps = React.HTMLAttributes<HTMLElement> & {\n title?: React.ReactNode;\n logo?: string;\n logoAlt?: string;\n brandHref?: string;\n navigation?: AppBarNavItem[];\n actions?: React.ReactNode;\n position?: 'fixed' | 'absolute' | 'sticky' | 'static' | 'relative';\n color?: 'primary' | 'surface' | 'muted' | 'dark' | 'transparent';\n dense?: boolean;\n elevated?: boolean;\n contained?: boolean;\n titlePosition?: 'start' | 'center' | 'end';\n};\n\nconst positionClasses: Record<NonNullable<AppBarProps['position']>, string> = {\n fixed: 'fixed inset-x-0 top-0',\n absolute: 'absolute inset-x-0 top-0',\n sticky: 'sticky inset-x-0 top-0',\n static: 'static',\n relative: 'relative'\n};\n\nconst colorClasses: Record<NonNullable<AppBarProps['color']>, string> = {\n primary: 'bg-primary text-white',\n surface: 'bg-white text-gray-900 border-b border-gray-200',\n muted: 'bg-gray-50 text-gray-900 border-b border-gray-200',\n dark: 'bg-gray-900 text-white',\n transparent: 'bg-transparent text-inherit'\n};\n\nconst AppBar: React.FC<AppBarProps> = ({\n title,\n logo,\n logoAlt = 'Logo',\n brandHref,\n navigation = [],\n actions,\n position = 'static',\n color = 'surface',\n dense = false,\n elevated = true,\n contained = true,\n titlePosition = 'start',\n className,\n children,\n ...rest\n}) => {\n const [mobileOpen, setMobileOpen] = React.useState(false);\n\n const isDark = color === 'primary' || color === 'dark';\n const isTransparent = color === 'transparent';\n\n const barClass = twMerge(\n 'app-bar z-40 w-full backdrop-blur-md',\n positionClasses[position] ?? positionClasses.static,\n colorClasses[color] ?? colorClasses.surface,\n elevated && !isTransparent ? 'shadow-sm shadow-black/10' : undefined,\n 'relative',\n className\n );\n\n const innerClass = twMerge(\n 'mx-auto flex w-full items-center gap-4',\n contained ? 'max-w-6xl px-4 sm:px-6 lg:px-8' : 'px-4',\n dense ? 'py-2.5' : 'py-4'\n );\n\n const brandTextClass = isDark ? 'text-white' : 'text-gray-900';\n const navBaseClass = twMerge(\n 'inline-flex items-center gap-2 rounded-xl px-3 py-2 text-sm font-medium transition focus-visible:outline-none',\n isDark\n ? 'hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-white/70'\n : 'hover:bg-gray-100 focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent'\n );\n const navActiveClass = isDark ? 'bg-white/15 text-white' : 'bg-primary/10 text-primary';\n\n const renderNavItem = (item: AppBarNavItem, index: number) => {\n const { href, label, active, onClick } = item;\n const Component = href ? 'a' : 'button';\n const resolvedHref = href && href.trim().length > 0 ? href : undefined;\n return (\n <Component\n key={`${resolvedHref ?? 'item'}-${index}`}\n href={resolvedHref}\n onClick={onClick as never}\n className={twMerge(navBaseClass, active ? navActiveClass : undefined)}\n aria-current={active ? 'page' : undefined}\n >\n {label}\n </Component>\n );\n };\n\n const brandAlignClass =\n titlePosition === 'center'\n ? 'justify-self-center text-center'\n : titlePosition === 'end'\n ? 'justify-self-end text-right'\n : 'justify-self-start';\n\n const brandNode =\n title || logo ? (\n <div className={twMerge('flex min-w-0 items-center gap-3', brandAlignClass)}>\n {logo ? (\n <div className='flex h-10 w-10 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-white/10 ring-1 ring-black/5'>\n <img\n src={logo}\n alt={logoAlt}\n className='h-full w-full object-cover'\n loading='lazy'\n decoding='async'\n />\n </div>\n ) : null}\n <div className='min-w-0'>\n {title ? (\n <div className={twMerge('text-base font-semibold leading-tight', brandTextClass)}>\n {brandHref ? (\n <a href={brandHref} className='hover:underline focus-visible:outline-none'>\n {title}\n </a>\n ) : (\n title\n )}\n </div>\n ) : null}\n </div>\n </div>\n ) : null;\n\n return (\n <header {...rest} className={barClass}>\n <div className={innerClass}>\n <div className='grid w-full grid-cols-[auto_1fr_auto] items-center gap-3'>\n <div className='flex items-center gap-2'>\n {navigation.length > 0 ? (\n <button\n type='button'\n aria-label='Otevřít navigaci'\n className={twMerge(\n 'inline-flex h-10 w-10 items-center justify-center rounded-xl text-xl sm:hidden',\n isDark\n ? 'text-white hover:bg-white/10 focus-visible:ring-2 focus-visible:ring-white/60'\n : 'text-gray-700 hover:bg-gray-100 focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2 focus-visible:ring-offset-transparent'\n )}\n aria-expanded={mobileOpen}\n onClick={() => setMobileOpen(open => !open)}\n >\n <i className={mobileOpen ? 'mdi mdi-close' : 'mdi mdi-menu'} aria-hidden />\n </button>\n ) : null}\n {navigation.length > 0 ? (\n <nav className='hidden items-center gap-1 sm:flex' aria-label='Hlavni navigace'>\n {navigation.map(renderNavItem)}\n </nav>\n ) : null}\n </div>\n {brandNode}\n <div className='ml-auto flex items-center justify-end gap-2'>\n {children}\n {actions}\n </div>\n </div>\n </div>\n {navigation.length > 0 && mobileOpen ? (\n <div className='sm:hidden'>\n <nav className='absolute inset-x-0 top-full border-t border-gray-200/70 bg-white/95 p-3 shadow-lg shadow-gray-900/5 backdrop-blur-md'>\n <div className='flex flex-col gap-2' aria-label='Mobilni navigace'>\n {navigation.map((item, index) => {\n const { href, label, active, onClick } = item;\n const Component = href ? 'a' : 'button';\n const resolvedHref = href && href.trim().length > 0 ? href : undefined;\n return (\n <Component\n key={`${resolvedHref ?? 'mobile-item'}-${index}`}\n href={resolvedHref}\n onClick={event => {\n onClick?.(event as never);\n setMobileOpen(false);\n }}\n className={twMerge(\n 'flex items-center justify-between rounded-xl px-3 py-2 text-sm font-medium transition',\n active ? 'bg-primary/10 text-primary' : 'text-gray-800 hover:bg-gray-100'\n )}\n aria-current={active ? 'page' : undefined}\n >\n {label}\n {active ? (\n <i className='mdi mdi-circle-small text-primary' aria-hidden />\n ) : null}\n </Component>\n );\n })}\n </div>\n </nav>\n </div>\n ) : null}\n </header>\n );\n};\n\nAppBar.displayName = 'AppBar';\n\nexport default AppBar;\n"]}
@@ -0,0 +1,14 @@
1
+ // src/utils/helpers/randomStr.ts
2
+ var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
3
+ function generateString(length = 5) {
4
+ let result = "";
5
+ const charactersLength = characters.length;
6
+ for (let i = 0; i < length; i++) {
7
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
8
+ }
9
+ return result;
10
+ }
11
+
12
+ export { generateString };
13
+ //# sourceMappingURL=chunk-6SKW43XI.js.map
14
+ //# sourceMappingURL=chunk-6SKW43XI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/helpers/randomStr.ts"],"names":[],"mappings":";AAAA,IAAM,UAAA,GAAa,gEAAA;AAEZ,SAAS,cAAA,CAAe,SAAS,CAAA,EAAG;AACzC,EAAA,IAAI,MAAA,GAAiB,EAAA;AACrB,EAAA,MAAM,mBAAmB,UAAA,CAAW,MAAA;AACpC,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,MAAA,EAAQ,CAAA,EAAA,EAAK;AAC/B,IAAA,MAAA,IAAU,UAAA,CAAW,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,GAAI,gBAAgB,CAAC,CAAA;AAAA,EAC1E;AAEA,EAAA,OAAO,MAAA;AACT","file":"chunk-6SKW43XI.js","sourcesContent":["const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n\nexport function generateString(length = 5) {\n let result: string = '';\n const charactersLength = characters.length;\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength));\n }\n\n return result;\n}\n"]}
@@ -144,13 +144,13 @@ var Input = ({
144
144
  {
145
145
  htmlFor: inputName,
146
146
  className: twMerge(
147
- "absolute transition-all duration-150 pointer-events-none text-gray-700 dark:text-gray-200",
147
+ "absolute transition-all duration-150 pointer-events-none text-gray-700 rounded dark:text-gray-200",
148
148
  labelLeftClass,
149
149
  // Floated state: center label's vertical middle on the top border line
150
- "top-0 -translate-y-2/3 text-xs px-1",
150
+ "-top-1.5 left-1 peer-focus:left-7 -translate-y-2/3 text-xs px-1",
151
151
  labelBgDefault,
152
152
  // focus state mirrors floated state (keeps center on border)
153
- "peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:text-xs peer-focus:px-1 peer-focus:bg-white/90 peer-focus:text-gray-600 dark:peer-focus:bg-slate-900 dark:peer-focus:text-gray-300",
153
+ "peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:text-xs peer-focus:px-1 peer-focus:bg-white peer-focus:text-gray-600 dark:peer-focus:bg-slate-900 dark:peer-focus:text-gray-300",
154
154
  // when input is empty (placeholder shown) -> center label inside input
155
155
  "peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:text-sm peer-placeholder-shown:bg-transparent peer-placeholder-shown:text-gray-500 dark:peer-placeholder-shown:text-gray-400"
156
156
  ),
@@ -164,5 +164,5 @@ var Input = ({
164
164
  var Input_default = Input;
165
165
 
166
166
  export { Input_default };
167
- //# sourceMappingURL=chunk-JGEXEDKS.js.map
168
- //# sourceMappingURL=chunk-JGEXEDKS.js.map
167
+ //# sourceMappingURL=chunk-AUFMBVXA.js.map
168
+ //# sourceMappingURL=chunk-AUFMBVXA.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/Form/Input/states.input.ts","../src/Form/Input/index.tsx"],"names":["normalizedName"],"mappings":"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","file":"chunk-JGEXEDKS.js","sourcesContent":["import { iconBaseClasses } from '@lindle/linoardo/globals';\nimport { InputProp } from './types';\n\nexport const resolveIconClassName = (icon?: InputProp['icon']) => {\n if (!icon) {\n return undefined;\n }\n\n if (typeof icon === 'string') {\n const trimmed = icon.trim();\n if (!trimmed) {\n return undefined;\n }\n\n if (trimmed.includes(' ')) {\n return trimmed;\n }\n\n const normalizedName = trimmed.startsWith('mdi-') ? trimmed : `mdi-${trimmed}`;\n return ['mdi', normalizedName].join(' ');\n }\n\n const [library, iconNameRaw] = icon;\n const baseClasses = iconBaseClasses[library] ?? [library];\n const iconName = iconNameRaw.trim();\n if (!iconName) {\n return baseClasses.join(' ');\n }\n const normalizedName = iconName.startsWith('mdi-') ? iconName : `mdi-${iconName}`;\n const classes = [...baseClasses, normalizedName];\n return Array.from(new Set(classes)).join(' ');\n};\n","import React from 'react';\nimport { twMerge } from 'tailwind-merge';\nimport { InputProp, InputVariant, InputSize } from './types';\nimport { resolveIconClassName } from './states.input';\n\n/**\n * Text input with multiple visual variants and inline status or icon adornments.\n * Label is purely CSS-driven (peer + placeholder-shown + focus), no hooks used.\n */\nconst Input: React.FC<InputProp> = ({\n variant = 'outline',\n size = 'medium',\n success,\n error,\n warn,\n icon,\n className,\n wrapperClassName,\n label,\n ...props\n}) => {\n const { placeholder, onFocus, onBlur, ...inputProps } = props;\n const reactId = React.useId();\n const hasLabel = Boolean(label);\n const hasProvidedPlaceholder = typeof placeholder === 'string' && placeholder.trim().length > 0;\n const hidePlaceholderUntilFocus = hasLabel && hasProvidedPlaceholder;\n const [isFocused, setIsFocused] = React.useState(false);\n const classBase =\n 'input-base focus-visible:outline-none focus-visible:ring-primary transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed w-full text-gray-900 dark:text-gray-100 placeholder:text-gray-500 dark:placeholder:text-gray-400';\n const variantClasses = {\n solid:\n 'rounded border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40',\n sharp:\n 'rounded-none border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40',\n outline:\n 'rounded border-2 border-black bg-white focus-visible:border-black focus-visible:ring-2 focus-visible:ring-black/30 dark:border-black dark:bg-transparent dark:focus-visible:border-black dark:focus-visible:ring-black/40',\n text: 'rounded-none border-0 border-b border-transparent px-0 bg-transparent focus-visible:border-primary focus-visible:ring-0 focus-visible:ring-transparent dark:border-b-gray-600 dark:focus-visible:border-primary/70',\n ghost:\n 'rounded border border-transparent bg-gray-50 text-gray-900 focus-visible:bg-white focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/15 dark:bg-slate-800 dark:text-gray-100 dark:focus-visible:bg-slate-700 dark:focus-visible:border-primary/60 dark:focus-visible:ring-primary/25',\n filled:\n 'rounded border border-gray-200 bg-gray-100 focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/25 dark:border-gray-700 dark:bg-slate-800 dark:focus-visible:border-primary/60 dark:focus-visible:ring-primary/30',\n underlined:\n 'rounded-none border-0 border-b border-gray-300 px-0 bg-transparent focus-visible:border-primary focus-visible:ring-0 focus-visible:ring-transparent dark:border-b-gray-600 dark:focus-visible:border-primary/70',\n rounded:\n 'rounded-full px-4 border border-gray-300 bg-white focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/20 shadow-sm dark:border-gray-600 dark:bg-slate-900 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/30 dark:shadow-black/20'\n } satisfies Record<InputVariant, string>;\n const sizeClasses = {\n 'x-small': { paddingNoIcon: 'px-2 py-2', paddingWithIcon: 'pl-8 pr-2 py-2', text: 'text-xs' },\n small: {\n paddingNoIcon: 'px-2.5 py-2.5',\n paddingWithIcon: 'pl-9 pr-2.5 py-2.5',\n text: 'text-sm'\n },\n medium: { paddingNoIcon: 'px-3 py-3', paddingWithIcon: 'pl-10 pr-3 py-3', text: 'text-base' },\n large: {\n paddingNoIcon: 'px-3.5 py-3.5',\n paddingWithIcon: 'pl-11 pr-3.5 py-3.5',\n text: 'text-lg'\n },\n 'x-large': { paddingNoIcon: 'px-4 py-4', paddingWithIcon: 'pl-12 pr-4 py-4', text: 'text-xl' }\n } satisfies Record<InputSize, { paddingNoIcon: string; paddingWithIcon: string; text: string }>;\n\n const status = error\n ? { tone: 'error' as const, message: error }\n : warn\n ? { tone: 'warn' as const, message: warn }\n : success\n ? { tone: 'success' as const, message: success }\n : undefined;\n\n const statusClasses = {\n error: 'border-red-500 focus:border-red-500 focus:ring-red-400',\n warn: 'border-amber-500 focus:border-amber-500 focus:ring-amber-400',\n success: 'border-emerald-500 focus:border-emerald-500 focus:ring-emerald-400'\n } as const;\n\n const statusMessageClasses = {\n error: 'text-red-600 dark:text-red-300',\n warn: 'text-amber-600 dark:text-amber-300',\n success: 'text-emerald-600 dark:text-emerald-300'\n } as const;\n\n const variantClass = variantClasses[variant] ?? variantClasses.outline;\n const toneClass = status ? statusClasses[status.tone] : undefined;\n let prependIconClass = resolveIconClassName(icon);\n const sizeConfig = sizeClasses[size] ?? sizeClasses.medium;\n const sizeClass = [\n prependIconClass ? sizeConfig.paddingWithIcon : sizeConfig.paddingNoIcon,\n sizeConfig.text\n ].join(' ');\n\n // useId keeps SSR/CSR ids consistent while still providing a fallback name\n const inputName = inputProps.name || reactId;\n\n // Ensure placeholder is present when label exists so :placeholder-shown works.\n // Label stays primary; placeholder only appears on focus when the field is empty.\n const basePlaceholder = placeholder ?? (hasLabel ? ' ' : undefined);\n const placeholderValue = hidePlaceholderUntilFocus\n ? isFocused\n ? placeholder\n : ' '\n : basePlaceholder;\n const placeholderClass = hidePlaceholderUntilFocus\n ? 'placeholder-transparent focus:placeholder-gray-500 focus:dark:placeholder-gray-400'\n : undefined;\n\n // Label left offset depends on icon presence\n const labelLeftClass = prependIconClass ? 'left-10' : 'left-3';\n\n // Background for floated label — keep transparent for outline/text/underlined variants\n const labelBgDefault = ['outline', 'text', 'underlined'].includes(variant)\n ? 'bg-transparent'\n : 'bg-white/90 dark:bg-slate-900';\n\n const handleFocus: React.FocusEventHandler<HTMLInputElement> = event => {\n if (hidePlaceholderUntilFocus) setIsFocused(true);\n onFocus?.(event);\n };\n\n const handleBlur: React.FocusEventHandler<HTMLInputElement> = event => {\n if (hidePlaceholderUntilFocus) setIsFocused(false);\n onBlur?.(event);\n };\n\n return (\n <div className={twMerge('flex flex-col gap-1', wrapperClassName)}>\n <div className='relative flex items-center'>\n {prependIconClass && (\n <i\n className={twMerge(\n 'pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-500 dark:text-gray-400',\n (status?.tone && statusMessageClasses[status?.tone]) || '',\n prependIconClass\n )}\n aria-hidden\n />\n )}\n\n {/* input is peer so label can react with peer-* utilities */}\n <input\n {...inputProps}\n id={inputName}\n name={inputName}\n placeholder={placeholderValue}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className={twMerge(\n 'peer',\n classBase,\n variantClass,\n toneClass,\n sizeClass,\n placeholderClass,\n className\n )}\n />\n\n {label && (\n <label\n htmlFor={inputName}\n className={twMerge(\n 'absolute transition-all duration-150 pointer-events-none text-gray-700 dark:text-gray-200',\n labelLeftClass,\n // Floated state: center label's vertical middle on the top border line\n 'top-0 -translate-y-2/3 text-xs px-1',\n labelBgDefault,\n // focus state mirrors floated state (keeps center on border)\n 'peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:text-xs peer-focus:px-1 peer-focus:bg-white/90 peer-focus:text-gray-600 dark:peer-focus:bg-slate-900 dark:peer-focus:text-gray-300',\n // when input is empty (placeholder shown) -> center label inside input\n 'peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:text-sm peer-placeholder-shown:bg-transparent peer-placeholder-shown:text-gray-500 dark:peer-placeholder-shown:text-gray-400'\n )}\n >\n {label}\n </label>\n )}\n\n {/* {appendIconClass && (\n <i className={twMerge('pointer-events-none absolute right-3 text-gray-500', appendIconClass)} aria-hidden />\n )} */}\n </div>\n {status?.message && (\n <span className={twMerge('text-sm', statusMessageClasses[status.tone])}>\n {status.message}\n </span>\n )}\n </div>\n );\n};\n\nexport default Input;\n"]}
1
+ {"version":3,"sources":["../src/Form/Input/states.input.ts","../src/Form/Input/index.tsx"],"names":["normalizedName"],"mappings":"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","file":"chunk-AUFMBVXA.js","sourcesContent":["import { iconBaseClasses } from '@lindle/linoardo/globals';\nimport { InputProp } from './types';\n\nexport const resolveIconClassName = (icon?: InputProp['icon']) => {\n if (!icon) {\n return undefined;\n }\n\n if (typeof icon === 'string') {\n const trimmed = icon.trim();\n if (!trimmed) {\n return undefined;\n }\n\n if (trimmed.includes(' ')) {\n return trimmed;\n }\n\n const normalizedName = trimmed.startsWith('mdi-') ? trimmed : `mdi-${trimmed}`;\n return ['mdi', normalizedName].join(' ');\n }\n\n const [library, iconNameRaw] = icon;\n const baseClasses = iconBaseClasses[library] ?? [library];\n const iconName = iconNameRaw.trim();\n if (!iconName) {\n return baseClasses.join(' ');\n }\n const normalizedName = iconName.startsWith('mdi-') ? iconName : `mdi-${iconName}`;\n const classes = [...baseClasses, normalizedName];\n return Array.from(new Set(classes)).join(' ');\n};\n","import React from 'react';\nimport { twMerge } from 'tailwind-merge';\nimport { InputProp, InputVariant, InputSize } from './types';\nimport { resolveIconClassName } from './states.input';\n\n/**\n * Text input with multiple visual variants and inline status or icon adornments.\n * Label is purely CSS-driven (peer + placeholder-shown + focus), no hooks used.\n */\nconst Input: React.FC<InputProp> = ({\n variant = 'outline',\n size = 'medium',\n success,\n error,\n warn,\n icon,\n className,\n wrapperClassName,\n label,\n ...props\n}) => {\n const { placeholder, onFocus, onBlur, ...inputProps } = props;\n const reactId = React.useId();\n const hasLabel = Boolean(label);\n const hasProvidedPlaceholder = typeof placeholder === 'string' && placeholder.trim().length > 0;\n const hidePlaceholderUntilFocus = hasLabel && hasProvidedPlaceholder;\n const [isFocused, setIsFocused] = React.useState(false);\n const classBase =\n 'input-base focus-visible:outline-none focus-visible:ring-primary transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed w-full text-gray-900 dark:text-gray-100 placeholder:text-gray-500 dark:placeholder:text-gray-400';\n const variantClasses = {\n solid:\n 'rounded border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40',\n sharp:\n 'rounded-none border border-gray-400 bg-white shadow-sm focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/30 dark:border-gray-600 dark:bg-slate-900 dark:shadow-black/20 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/40',\n outline:\n 'rounded border-2 border-black bg-white focus-visible:border-black focus-visible:ring-2 focus-visible:ring-black/30 dark:border-black dark:bg-transparent dark:focus-visible:border-black dark:focus-visible:ring-black/40',\n text: 'rounded-none border-0 border-b border-transparent px-0 bg-transparent focus-visible:border-primary focus-visible:ring-0 focus-visible:ring-transparent dark:border-b-gray-600 dark:focus-visible:border-primary/70',\n ghost:\n 'rounded border border-transparent bg-gray-50 text-gray-900 focus-visible:bg-white focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/15 dark:bg-slate-800 dark:text-gray-100 dark:focus-visible:bg-slate-700 dark:focus-visible:border-primary/60 dark:focus-visible:ring-primary/25',\n filled:\n 'rounded border border-gray-200 bg-gray-100 focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/25 dark:border-gray-700 dark:bg-slate-800 dark:focus-visible:border-primary/60 dark:focus-visible:ring-primary/30',\n underlined:\n 'rounded-none border-0 border-b border-gray-300 px-0 bg-transparent focus-visible:border-primary focus-visible:ring-0 focus-visible:ring-transparent dark:border-b-gray-600 dark:focus-visible:border-primary/70',\n rounded:\n 'rounded-full px-4 border border-gray-300 bg-white focus-visible:border-primary focus-visible:ring-2 focus-visible:ring-primary/20 shadow-sm dark:border-gray-600 dark:bg-slate-900 dark:focus-visible:border-primary/70 dark:focus-visible:ring-primary/30 dark:shadow-black/20'\n } satisfies Record<InputVariant, string>;\n const sizeClasses = {\n 'x-small': { paddingNoIcon: 'px-2 py-2', paddingWithIcon: 'pl-8 pr-2 py-2', text: 'text-xs' },\n small: {\n paddingNoIcon: 'px-2.5 py-2.5',\n paddingWithIcon: 'pl-9 pr-2.5 py-2.5',\n text: 'text-sm'\n },\n medium: { paddingNoIcon: 'px-3 py-3', paddingWithIcon: 'pl-10 pr-3 py-3', text: 'text-base' },\n large: {\n paddingNoIcon: 'px-3.5 py-3.5',\n paddingWithIcon: 'pl-11 pr-3.5 py-3.5',\n text: 'text-lg'\n },\n 'x-large': { paddingNoIcon: 'px-4 py-4', paddingWithIcon: 'pl-12 pr-4 py-4', text: 'text-xl' }\n } satisfies Record<InputSize, { paddingNoIcon: string; paddingWithIcon: string; text: string }>;\n\n const status = error\n ? { tone: 'error' as const, message: error }\n : warn\n ? { tone: 'warn' as const, message: warn }\n : success\n ? { tone: 'success' as const, message: success }\n : undefined;\n\n const statusClasses = {\n error: 'border-red-500 focus:border-red-500 focus:ring-red-400',\n warn: 'border-amber-500 focus:border-amber-500 focus:ring-amber-400',\n success: 'border-emerald-500 focus:border-emerald-500 focus:ring-emerald-400'\n } as const;\n\n const statusMessageClasses = {\n error: 'text-red-600 dark:text-red-300',\n warn: 'text-amber-600 dark:text-amber-300',\n success: 'text-emerald-600 dark:text-emerald-300'\n } as const;\n\n const variantClass = variantClasses[variant] ?? variantClasses.outline;\n const toneClass = status ? statusClasses[status.tone] : undefined;\n let prependIconClass = resolveIconClassName(icon);\n const sizeConfig = sizeClasses[size] ?? sizeClasses.medium;\n const sizeClass = [\n prependIconClass ? sizeConfig.paddingWithIcon : sizeConfig.paddingNoIcon,\n sizeConfig.text\n ].join(' ');\n\n // useId keeps SSR/CSR ids consistent while still providing a fallback name\n const inputName = inputProps.name || reactId;\n\n // Ensure placeholder is present when label exists so :placeholder-shown works.\n // Label stays primary; placeholder only appears on focus when the field is empty.\n const basePlaceholder = placeholder ?? (hasLabel ? ' ' : undefined);\n const placeholderValue = hidePlaceholderUntilFocus\n ? isFocused\n ? placeholder\n : ' '\n : basePlaceholder;\n const placeholderClass = hidePlaceholderUntilFocus\n ? 'placeholder-transparent focus:placeholder-gray-500 focus:dark:placeholder-gray-400'\n : undefined;\n\n // Label left offset depends on icon presence\n const labelLeftClass = prependIconClass ? 'left-10' : 'left-3';\n\n // Background for floated label — keep transparent for outline/text/underlined variants\n const labelBgDefault = ['outline', 'text', 'underlined'].includes(variant)\n ? 'bg-transparent'\n : 'bg-white/90 dark:bg-slate-900';\n\n const handleFocus: React.FocusEventHandler<HTMLInputElement> = event => {\n if (hidePlaceholderUntilFocus) setIsFocused(true);\n onFocus?.(event);\n };\n\n const handleBlur: React.FocusEventHandler<HTMLInputElement> = event => {\n if (hidePlaceholderUntilFocus) setIsFocused(false);\n onBlur?.(event);\n };\n\n return (\n <div className={twMerge('flex flex-col gap-1', wrapperClassName)}>\n <div className='relative flex items-center'>\n {prependIconClass && (\n <i\n className={twMerge(\n 'pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-gray-500 dark:text-gray-400',\n (status?.tone && statusMessageClasses[status?.tone]) || '',\n prependIconClass\n )}\n aria-hidden\n />\n )}\n\n {/* input is peer so label can react with peer-* utilities */}\n <input\n {...inputProps}\n id={inputName}\n name={inputName}\n placeholder={placeholderValue}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className={twMerge(\n 'peer',\n classBase,\n variantClass,\n toneClass,\n sizeClass,\n placeholderClass,\n className\n )}\n />\n\n {label && (\n <label\n htmlFor={inputName}\n className={twMerge(\n 'absolute transition-all duration-150 pointer-events-none text-gray-700 rounded dark:text-gray-200',\n labelLeftClass,\n // Floated state: center label's vertical middle on the top border line\n '-top-1.5 left-1 peer-focus:left-7 -translate-y-2/3 text-xs px-1',\n labelBgDefault,\n // focus state mirrors floated state (keeps center on border)\n 'peer-focus:top-0 peer-focus:-translate-y-1/2 peer-focus:text-xs peer-focus:px-1 peer-focus:bg-white peer-focus:text-gray-600 dark:peer-focus:bg-slate-900 dark:peer-focus:text-gray-300',\n // when input is empty (placeholder shown) -> center label inside input\n 'peer-placeholder-shown:top-1/2 peer-placeholder-shown:-translate-y-1/2 peer-placeholder-shown:text-sm peer-placeholder-shown:bg-transparent peer-placeholder-shown:text-gray-500 dark:peer-placeholder-shown:text-gray-400'\n )}\n >\n {label}\n </label>\n )}\n\n {/* {appendIconClass && (\n <i className={twMerge('pointer-events-none absolute right-3 text-gray-500', appendIconClass)} aria-hidden />\n )} */}\n </div>\n {status?.message && (\n <span className={twMerge('text-sm', statusMessageClasses[status.tone])}>\n {status.message}\n </span>\n )}\n </div>\n );\n};\n\nexport default Input;\n"]}