@memelabui/ui 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -513,126 +513,129 @@ var Textarea = React.forwardRef(function Textarea2({ hasError, label, error, hel
513
513
  helperText && !error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: helperId, className: "text-white/40 text-xs mt-1", children: helperText })
514
514
  ] });
515
515
  });
516
- function TagInput({
517
- value,
518
- onChange,
519
- placeholder,
520
- disabled = false,
521
- label,
522
- error,
523
- maxTags,
524
- className,
525
- id: externalId
526
- }) {
527
- const generatedId = React.useId();
528
- const inputId = externalId ?? generatedId;
529
- const errorId = error ? `${inputId}-error` : void 0;
530
- const inputRef = React.useRef(null);
531
- const atMax = maxTags !== void 0 && value.length >= maxTags;
532
- function addTag(raw) {
533
- const tag = raw.trim();
534
- if (!tag || value.includes(tag) || atMax) return;
535
- onChange([...value, tag]);
536
- }
537
- function removeTag(index) {
538
- onChange(value.filter((_, i) => i !== index));
539
- }
540
- function handleKeyDown(e) {
541
- const input = inputRef.current;
542
- if (!input) return;
543
- if (e.key === "Enter" || e.key === "," || e.key === "Tab") {
544
- if (input.value) {
545
- e.preventDefault();
546
- addTag(input.value);
547
- input.value = "";
548
- }
549
- return;
516
+ var TagInput = React.forwardRef(
517
+ function TagInput2({
518
+ value,
519
+ onChange,
520
+ placeholder,
521
+ disabled = false,
522
+ label,
523
+ error,
524
+ maxTags,
525
+ className,
526
+ id: externalId
527
+ }, ref) {
528
+ const generatedId = React.useId();
529
+ const inputId = externalId ?? generatedId;
530
+ const errorId = error ? `${inputId}-error` : void 0;
531
+ const internalRef = React.useRef(null);
532
+ const inputRef = ref ?? internalRef;
533
+ const atMax = maxTags !== void 0 && value.length >= maxTags;
534
+ function addTag(raw) {
535
+ const tag = raw.trim();
536
+ if (!tag || value.includes(tag) || atMax) return;
537
+ onChange([...value, tag]);
550
538
  }
551
- if (e.key === "Backspace" && !input.value && value.length > 0) {
552
- removeTag(value.length - 1);
539
+ function removeTag(index) {
540
+ onChange(value.filter((_, i) => i !== index));
553
541
  }
554
- }
555
- function handlePaste(e) {
556
- const pasted = e.clipboardData.getData("text");
557
- if (!pasted.includes(",")) return;
558
- e.preventDefault();
559
- const parts = pasted.split(",");
560
- const next = [...value];
561
- for (const part of parts) {
562
- const tag = part.trim();
563
- if (tag && !next.includes(tag)) {
564
- if (maxTags !== void 0 && next.length >= maxTags) break;
565
- next.push(tag);
542
+ function handleKeyDown(e) {
543
+ const input = inputRef.current;
544
+ if (!input) return;
545
+ if (e.key === "Enter" || e.key === "," || e.key === "Tab") {
546
+ if (input.value) {
547
+ e.preventDefault();
548
+ addTag(input.value);
549
+ input.value = "";
550
+ }
551
+ return;
552
+ }
553
+ if (e.key === "Backspace" && !input.value && value.length > 0) {
554
+ removeTag(value.length - 1);
566
555
  }
567
556
  }
568
- onChange(next);
569
- if (inputRef.current) inputRef.current.value = "";
570
- }
571
- const wrapper = /* @__PURE__ */ jsxRuntime.jsxs(
572
- "div",
573
- {
574
- className: cn(
575
- "flex flex-wrap items-center gap-1.5 min-h-[42px] w-full rounded-xl px-3 py-2 bg-white/10 ring-1 ring-white/10 transition-shadow focus-within:ring-2 focus-within:ring-primary/40",
576
- error && "ring-2 ring-rose-500/40 focus-within:ring-rose-500/40",
577
- disabled && "opacity-50 cursor-not-allowed",
578
- className
579
- ),
580
- onClick: () => inputRef.current?.focus(),
581
- children: [
582
- value.map((tag, i) => /* @__PURE__ */ jsxRuntime.jsxs(
583
- "span",
584
- {
585
- className: "inline-flex items-center gap-1 bg-white/10 text-white/90 rounded-full text-xs px-2.5 py-1 ring-1 ring-white/10",
586
- children: [
587
- tag,
588
- !disabled && /* @__PURE__ */ jsxRuntime.jsx(
589
- "button",
590
- {
591
- type: "button",
592
- "aria-label": `Remove ${tag}`,
593
- onClick: (e) => {
594
- e.stopPropagation();
595
- removeTag(i);
596
- },
597
- className: "text-white/50 hover:text-white/90 transition-colors leading-none",
598
- children: "\u2715"
599
- }
600
- )
601
- ]
602
- },
603
- `${tag}-${i}`
604
- )),
605
- /* @__PURE__ */ jsxRuntime.jsx(
606
- "input",
607
- {
608
- ref: inputRef,
609
- id: inputId,
610
- type: "text",
611
- disabled: disabled || atMax,
612
- placeholder: value.length === 0 ? placeholder : void 0,
613
- "aria-invalid": !!error || void 0,
614
- "aria-describedby": errorId,
615
- onKeyDown: handleKeyDown,
616
- onPaste: handlePaste,
617
- onBlur: (e) => {
618
- if (e.target.value) {
619
- addTag(e.target.value);
620
- e.target.value = "";
621
- }
622
- },
623
- className: "flex-1 min-w-[120px] bg-transparent text-sm text-white outline-none placeholder-white/30 disabled:cursor-not-allowed"
624
- }
625
- )
626
- ]
557
+ function handlePaste(e) {
558
+ const pasted = e.clipboardData.getData("text");
559
+ if (!pasted.includes(",")) return;
560
+ e.preventDefault();
561
+ const parts = pasted.split(",");
562
+ const next = [...value];
563
+ for (const part of parts) {
564
+ const tag = part.trim();
565
+ if (tag && !next.includes(tag)) {
566
+ if (maxTags !== void 0 && next.length >= maxTags) break;
567
+ next.push(tag);
568
+ }
569
+ }
570
+ onChange(next);
571
+ if (inputRef.current) inputRef.current.value = "";
627
572
  }
628
- );
629
- if (!label && !error) return wrapper;
630
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
631
- label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "block text-sm text-white/70 mb-1.5", children: label }),
632
- wrapper,
633
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "text-rose-400 text-xs mt-1", children: error })
634
- ] });
635
- }
573
+ const wrapper = /* @__PURE__ */ jsxRuntime.jsxs(
574
+ "div",
575
+ {
576
+ className: cn(
577
+ "flex flex-wrap items-center gap-1.5 min-h-[42px] w-full rounded-xl px-3 py-2 bg-white/10 ring-1 ring-white/10 transition-shadow focus-within:ring-2 focus-within:ring-primary/40",
578
+ error && "ring-2 ring-rose-500/40 focus-within:ring-rose-500/40",
579
+ disabled && "opacity-50 cursor-not-allowed",
580
+ className
581
+ ),
582
+ onClick: () => inputRef.current?.focus(),
583
+ children: [
584
+ value.map((tag, i) => /* @__PURE__ */ jsxRuntime.jsxs(
585
+ "span",
586
+ {
587
+ className: "inline-flex items-center gap-1 bg-white/10 text-white/90 rounded-full text-xs px-2.5 py-1 ring-1 ring-white/10",
588
+ children: [
589
+ tag,
590
+ !disabled && /* @__PURE__ */ jsxRuntime.jsx(
591
+ "button",
592
+ {
593
+ type: "button",
594
+ "aria-label": `Remove ${tag}`,
595
+ onClick: (e) => {
596
+ e.stopPropagation();
597
+ removeTag(i);
598
+ },
599
+ className: "text-white/50 hover:text-white/90 transition-colors leading-none",
600
+ children: "\u2715"
601
+ }
602
+ )
603
+ ]
604
+ },
605
+ `${tag}-${i}`
606
+ )),
607
+ /* @__PURE__ */ jsxRuntime.jsx(
608
+ "input",
609
+ {
610
+ ref: inputRef,
611
+ id: inputId,
612
+ type: "text",
613
+ disabled: disabled || atMax,
614
+ placeholder: value.length === 0 ? placeholder : void 0,
615
+ "aria-invalid": !!error || void 0,
616
+ "aria-describedby": errorId,
617
+ onKeyDown: handleKeyDown,
618
+ onPaste: handlePaste,
619
+ onBlur: (e) => {
620
+ if (e.target.value) {
621
+ addTag(e.target.value);
622
+ e.target.value = "";
623
+ }
624
+ },
625
+ className: "flex-1 min-w-[120px] bg-transparent text-sm text-white outline-none placeholder-white/30 disabled:cursor-not-allowed"
626
+ }
627
+ )
628
+ ]
629
+ }
630
+ );
631
+ if (!label && !error) return wrapper;
632
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
633
+ label && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: inputId, className: "block text-sm text-white/70 mb-1.5", children: label }),
634
+ wrapper,
635
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: "text-rose-400 text-xs mt-1", children: error })
636
+ ] });
637
+ }
638
+ );
636
639
  var base3 = "inline-flex items-center justify-center rounded-full font-semibold ring-1 ring-white/10";
637
640
  var sizeClass4 = {
638
641
  sm: "text-xs px-2.5 py-1",
package/dist/index.d.cts CHANGED
@@ -199,7 +199,7 @@ type TagInputProps = {
199
199
  className?: string;
200
200
  id?: string;
201
201
  };
202
- declare function TagInput({ value, onChange, placeholder, disabled, label, error, maxTags, className, id: externalId, }: TagInputProps): react_jsx_runtime.JSX.Element;
202
+ declare const TagInput: react.ForwardRefExoticComponent<TagInputProps & react.RefAttributes<HTMLInputElement>>;
203
203
 
204
204
  type BadgeVariant = 'neutral' | 'primary' | 'success' | 'successSolid' | 'warning' | 'danger' | 'dangerSolid' | 'accent';
205
205
  type BadgeSize = 'sm' | 'md';
package/dist/index.d.ts CHANGED
@@ -199,7 +199,7 @@ type TagInputProps = {
199
199
  className?: string;
200
200
  id?: string;
201
201
  };
202
- declare function TagInput({ value, onChange, placeholder, disabled, label, error, maxTags, className, id: externalId, }: TagInputProps): react_jsx_runtime.JSX.Element;
202
+ declare const TagInput: react.ForwardRefExoticComponent<TagInputProps & react.RefAttributes<HTMLInputElement>>;
203
203
 
204
204
  type BadgeVariant = 'neutral' | 'primary' | 'success' | 'successSolid' | 'warning' | 'danger' | 'dangerSolid' | 'accent';
205
205
  type BadgeSize = 'sm' | 'md';
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { forwardRef, useState, useId, useMemo, useRef, useEffect, createContext, useCallback, isValidElement, cloneElement, useReducer, useContext, Component } from 'react';
1
+ import React, { forwardRef, useState, useId, useRef, useMemo, useEffect, createContext, useCallback, isValidElement, cloneElement, useReducer, useContext, Component } from 'react';
2
2
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
3
3
  import { createPortal } from 'react-dom';
4
4
 
@@ -507,126 +507,129 @@ var Textarea = forwardRef(function Textarea2({ hasError, label, error, helperTex
507
507
  helperText && !error && /* @__PURE__ */ jsx("p", { id: helperId, className: "text-white/40 text-xs mt-1", children: helperText })
508
508
  ] });
509
509
  });
510
- function TagInput({
511
- value,
512
- onChange,
513
- placeholder,
514
- disabled = false,
515
- label,
516
- error,
517
- maxTags,
518
- className,
519
- id: externalId
520
- }) {
521
- const generatedId = useId();
522
- const inputId = externalId ?? generatedId;
523
- const errorId = error ? `${inputId}-error` : void 0;
524
- const inputRef = useRef(null);
525
- const atMax = maxTags !== void 0 && value.length >= maxTags;
526
- function addTag(raw) {
527
- const tag = raw.trim();
528
- if (!tag || value.includes(tag) || atMax) return;
529
- onChange([...value, tag]);
530
- }
531
- function removeTag(index) {
532
- onChange(value.filter((_, i) => i !== index));
533
- }
534
- function handleKeyDown(e) {
535
- const input = inputRef.current;
536
- if (!input) return;
537
- if (e.key === "Enter" || e.key === "," || e.key === "Tab") {
538
- if (input.value) {
539
- e.preventDefault();
540
- addTag(input.value);
541
- input.value = "";
542
- }
543
- return;
510
+ var TagInput = forwardRef(
511
+ function TagInput2({
512
+ value,
513
+ onChange,
514
+ placeholder,
515
+ disabled = false,
516
+ label,
517
+ error,
518
+ maxTags,
519
+ className,
520
+ id: externalId
521
+ }, ref) {
522
+ const generatedId = useId();
523
+ const inputId = externalId ?? generatedId;
524
+ const errorId = error ? `${inputId}-error` : void 0;
525
+ const internalRef = useRef(null);
526
+ const inputRef = ref ?? internalRef;
527
+ const atMax = maxTags !== void 0 && value.length >= maxTags;
528
+ function addTag(raw) {
529
+ const tag = raw.trim();
530
+ if (!tag || value.includes(tag) || atMax) return;
531
+ onChange([...value, tag]);
544
532
  }
545
- if (e.key === "Backspace" && !input.value && value.length > 0) {
546
- removeTag(value.length - 1);
533
+ function removeTag(index) {
534
+ onChange(value.filter((_, i) => i !== index));
547
535
  }
548
- }
549
- function handlePaste(e) {
550
- const pasted = e.clipboardData.getData("text");
551
- if (!pasted.includes(",")) return;
552
- e.preventDefault();
553
- const parts = pasted.split(",");
554
- const next = [...value];
555
- for (const part of parts) {
556
- const tag = part.trim();
557
- if (tag && !next.includes(tag)) {
558
- if (maxTags !== void 0 && next.length >= maxTags) break;
559
- next.push(tag);
536
+ function handleKeyDown(e) {
537
+ const input = inputRef.current;
538
+ if (!input) return;
539
+ if (e.key === "Enter" || e.key === "," || e.key === "Tab") {
540
+ if (input.value) {
541
+ e.preventDefault();
542
+ addTag(input.value);
543
+ input.value = "";
544
+ }
545
+ return;
546
+ }
547
+ if (e.key === "Backspace" && !input.value && value.length > 0) {
548
+ removeTag(value.length - 1);
560
549
  }
561
550
  }
562
- onChange(next);
563
- if (inputRef.current) inputRef.current.value = "";
564
- }
565
- const wrapper = /* @__PURE__ */ jsxs(
566
- "div",
567
- {
568
- className: cn(
569
- "flex flex-wrap items-center gap-1.5 min-h-[42px] w-full rounded-xl px-3 py-2 bg-white/10 ring-1 ring-white/10 transition-shadow focus-within:ring-2 focus-within:ring-primary/40",
570
- error && "ring-2 ring-rose-500/40 focus-within:ring-rose-500/40",
571
- disabled && "opacity-50 cursor-not-allowed",
572
- className
573
- ),
574
- onClick: () => inputRef.current?.focus(),
575
- children: [
576
- value.map((tag, i) => /* @__PURE__ */ jsxs(
577
- "span",
578
- {
579
- className: "inline-flex items-center gap-1 bg-white/10 text-white/90 rounded-full text-xs px-2.5 py-1 ring-1 ring-white/10",
580
- children: [
581
- tag,
582
- !disabled && /* @__PURE__ */ jsx(
583
- "button",
584
- {
585
- type: "button",
586
- "aria-label": `Remove ${tag}`,
587
- onClick: (e) => {
588
- e.stopPropagation();
589
- removeTag(i);
590
- },
591
- className: "text-white/50 hover:text-white/90 transition-colors leading-none",
592
- children: "\u2715"
593
- }
594
- )
595
- ]
596
- },
597
- `${tag}-${i}`
598
- )),
599
- /* @__PURE__ */ jsx(
600
- "input",
601
- {
602
- ref: inputRef,
603
- id: inputId,
604
- type: "text",
605
- disabled: disabled || atMax,
606
- placeholder: value.length === 0 ? placeholder : void 0,
607
- "aria-invalid": !!error || void 0,
608
- "aria-describedby": errorId,
609
- onKeyDown: handleKeyDown,
610
- onPaste: handlePaste,
611
- onBlur: (e) => {
612
- if (e.target.value) {
613
- addTag(e.target.value);
614
- e.target.value = "";
615
- }
616
- },
617
- className: "flex-1 min-w-[120px] bg-transparent text-sm text-white outline-none placeholder-white/30 disabled:cursor-not-allowed"
618
- }
619
- )
620
- ]
551
+ function handlePaste(e) {
552
+ const pasted = e.clipboardData.getData("text");
553
+ if (!pasted.includes(",")) return;
554
+ e.preventDefault();
555
+ const parts = pasted.split(",");
556
+ const next = [...value];
557
+ for (const part of parts) {
558
+ const tag = part.trim();
559
+ if (tag && !next.includes(tag)) {
560
+ if (maxTags !== void 0 && next.length >= maxTags) break;
561
+ next.push(tag);
562
+ }
563
+ }
564
+ onChange(next);
565
+ if (inputRef.current) inputRef.current.value = "";
621
566
  }
622
- );
623
- if (!label && !error) return wrapper;
624
- return /* @__PURE__ */ jsxs("div", { children: [
625
- label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "block text-sm text-white/70 mb-1.5", children: label }),
626
- wrapper,
627
- error && /* @__PURE__ */ jsx("p", { id: errorId, className: "text-rose-400 text-xs mt-1", children: error })
628
- ] });
629
- }
567
+ const wrapper = /* @__PURE__ */ jsxs(
568
+ "div",
569
+ {
570
+ className: cn(
571
+ "flex flex-wrap items-center gap-1.5 min-h-[42px] w-full rounded-xl px-3 py-2 bg-white/10 ring-1 ring-white/10 transition-shadow focus-within:ring-2 focus-within:ring-primary/40",
572
+ error && "ring-2 ring-rose-500/40 focus-within:ring-rose-500/40",
573
+ disabled && "opacity-50 cursor-not-allowed",
574
+ className
575
+ ),
576
+ onClick: () => inputRef.current?.focus(),
577
+ children: [
578
+ value.map((tag, i) => /* @__PURE__ */ jsxs(
579
+ "span",
580
+ {
581
+ className: "inline-flex items-center gap-1 bg-white/10 text-white/90 rounded-full text-xs px-2.5 py-1 ring-1 ring-white/10",
582
+ children: [
583
+ tag,
584
+ !disabled && /* @__PURE__ */ jsx(
585
+ "button",
586
+ {
587
+ type: "button",
588
+ "aria-label": `Remove ${tag}`,
589
+ onClick: (e) => {
590
+ e.stopPropagation();
591
+ removeTag(i);
592
+ },
593
+ className: "text-white/50 hover:text-white/90 transition-colors leading-none",
594
+ children: "\u2715"
595
+ }
596
+ )
597
+ ]
598
+ },
599
+ `${tag}-${i}`
600
+ )),
601
+ /* @__PURE__ */ jsx(
602
+ "input",
603
+ {
604
+ ref: inputRef,
605
+ id: inputId,
606
+ type: "text",
607
+ disabled: disabled || atMax,
608
+ placeholder: value.length === 0 ? placeholder : void 0,
609
+ "aria-invalid": !!error || void 0,
610
+ "aria-describedby": errorId,
611
+ onKeyDown: handleKeyDown,
612
+ onPaste: handlePaste,
613
+ onBlur: (e) => {
614
+ if (e.target.value) {
615
+ addTag(e.target.value);
616
+ e.target.value = "";
617
+ }
618
+ },
619
+ className: "flex-1 min-w-[120px] bg-transparent text-sm text-white outline-none placeholder-white/30 disabled:cursor-not-allowed"
620
+ }
621
+ )
622
+ ]
623
+ }
624
+ );
625
+ if (!label && !error) return wrapper;
626
+ return /* @__PURE__ */ jsxs("div", { children: [
627
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "block text-sm text-white/70 mb-1.5", children: label }),
628
+ wrapper,
629
+ error && /* @__PURE__ */ jsx("p", { id: errorId, className: "text-rose-400 text-xs mt-1", children: error })
630
+ ] });
631
+ }
632
+ );
630
633
  var base3 = "inline-flex items-center justify-center rounded-full font-semibold ring-1 ring-white/10";
631
634
  var sizeClass4 = {
632
635
  sm: "text-xs px-2.5 py-1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memelabui/ui",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "MemeLab shared UI component library — React + Tailwind + Glassmorphism",
5
5
  "type": "module",
6
6
  "sideEffects": [