@senestia/ui 0.1.0-beta.0190ae9 → 0.1.0-beta.0c3734c

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.
@@ -412,7 +412,7 @@ var l = Object.defineProperty, u = (e, t) => {
412
412
  search: i,
413
413
  password: n
414
414
  }, O = ({ label: n, required: i = !1, labelRemark: a, placeholder: o = "Placeholder", value: l, onChange: u, helperText: d, errorText: f, state: p = "Idle", size: m = "md", leadingDropdownText: h, leadingIcon: v, counter: y, unit: x, trailingIcon: S, trailingIcons: O, trailingIconSeparator: k = !1 }) => {
415
- let { isInvalid: A, isHover: j, isActive: M, isDisabled: N, isSkeleton: P, isKeyboardFocus: F } = E(p), I = w[m], L = A ? b.invalidBorder : M || F ? b.activeBorder : j ? b.hoverBorder : g.borderMidgray, R = N ? g.bgDisabled : j ? g.bgLightgray : g.bgWhite, z = N ? g.fgLow : g.fgMid, B = g.fgLow, V = N ? g.fgLow : g.fgHigh, H = N ? g.fgLow : g.fgHigh, U = N ? g.fgLow : g.fgMid, W = A ? _.error : g.fgMid;
415
+ let { isInvalid: A, isHover: j, isActive: M, isDisabled: N, isSkeleton: P, isKeyboardFocus: F } = E(p), I = w[m], L = A ? b.invalidBorder : M || F ? b.activeBorder : j ? b.hoverBorder : g.borderMidgray, R = N ? g.bgDisabled : j ? g.bgLightgray : g.bgWhite, z = N ? g.fgLow : g.fgMid, B = N ? g.fgLow : g.fgHigh, V = N ? g.fgLow : g.fgHigh, H = N ? g.fgLow : g.fgMid, U = A ? _.error : g.fgMid;
416
416
  if (P) return /* @__PURE__ */ c("div", {
417
417
  style: {
418
418
  width: 320,
@@ -431,7 +431,7 @@ var l = Object.defineProperty, u = (e, t) => {
431
431
  borderRadius: 24
432
432
  } })]
433
433
  });
434
- let G = v === !0 ? t : v || null, K = O?.length ? O : S ? [S] : [], q = A ? f : d, J = {
434
+ let W = v === !0 ? t : v || null, G = O?.length ? O : S ? [S] : [], K = A ? f : d, q = {
435
435
  fontFamily: C,
436
436
  fontWeight: 500
437
437
  };
@@ -467,7 +467,7 @@ var l = Object.defineProperty, u = (e, t) => {
467
467
  },
468
468
  children: [/* @__PURE__ */ s("span", {
469
469
  style: {
470
- ...J,
470
+ ...q,
471
471
  fontSize: I.labelFontSize,
472
472
  lineHeight: `${I.labelLineHeight}px`,
473
473
  color: z,
@@ -478,14 +478,14 @@ var l = Object.defineProperty, u = (e, t) => {
478
478
  children: n
479
479
  }), /* @__PURE__ */ s(r, {
480
480
  size: I.labelIconSize,
481
- color: U,
481
+ color: H,
482
482
  strokeWidth: 1.8,
483
483
  style: { flexShrink: 0 }
484
484
  })]
485
485
  }),
486
486
  a && /* @__PURE__ */ s("span", {
487
487
  style: {
488
- ...J,
488
+ ...q,
489
489
  fontSize: I.labelFontSize,
490
490
  lineHeight: `${I.labelLineHeight}px`,
491
491
  color: z,
@@ -532,7 +532,7 @@ var l = Object.defineProperty, u = (e, t) => {
532
532
  },
533
533
  children: [/* @__PURE__ */ s("span", {
534
534
  style: {
535
- ...J,
535
+ ...q,
536
536
  fontSize: I.inputFontSize,
537
537
  lineHeight: `${I.inputLineHeight}px`,
538
538
  color: g.fgHigh,
@@ -552,9 +552,9 @@ var l = Object.defineProperty, u = (e, t) => {
552
552
  strokeLinejoin: "round"
553
553
  })
554
554
  })]
555
- }) : G ? /* @__PURE__ */ s(G, {
555
+ }) : W ? /* @__PURE__ */ s(W, {
556
556
  size: I.iconSize,
557
- color: H,
557
+ color: V,
558
558
  strokeWidth: 1.6,
559
559
  style: { flexShrink: 0 }
560
560
  }) : null, /* @__PURE__ */ c("div", {
@@ -571,27 +571,28 @@ var l = Object.defineProperty, u = (e, t) => {
571
571
  } : {}
572
572
  },
573
573
  children: [
574
- /* @__PURE__ */ s("div", {
574
+ /* @__PURE__ */ s("input", {
575
+ type: "text",
576
+ value: l ?? "",
577
+ onChange: (e) => u?.(e.target.value),
578
+ placeholder: o,
579
+ disabled: N,
575
580
  style: {
581
+ ...q,
576
582
  flex: "1 0 0",
583
+ border: "none",
584
+ outline: "none",
585
+ background: "transparent",
586
+ fontSize: I.inputFontSize,
587
+ lineHeight: `${I.inputLineHeight}px`,
588
+ color: B,
589
+ width: "100%",
590
+ minWidth: 0,
577
591
  overflow: "hidden",
578
- display: "flex",
579
- alignItems: "center"
580
- },
581
- children: /* @__PURE__ */ s("span", {
582
- style: {
583
- ...J,
584
- fontSize: I.inputFontSize,
585
- lineHeight: `${I.inputLineHeight}px`,
586
- color: l ? V : B,
587
- overflow: "hidden",
588
- textOverflow: "ellipsis",
589
- whiteSpace: "nowrap",
590
- display: "block",
591
- width: "100%"
592
- },
593
- children: l || o
594
- })
592
+ textOverflow: "ellipsis",
593
+ whiteSpace: "nowrap",
594
+ cursor: N ? "not-allowed" : "text"
595
+ }
595
596
  }),
596
597
  y && /* @__PURE__ */ c("div", {
597
598
  style: {
@@ -607,7 +608,7 @@ var l = Object.defineProperty, u = (e, t) => {
607
608
  },
608
609
  children: [/* @__PURE__ */ s("span", {
609
610
  style: {
610
- ...J,
611
+ ...q,
611
612
  fontSize: I.counterFontSize,
612
613
  lineHeight: `${I.counterLineHeight}px`,
613
614
  color: g.fgHigh
@@ -615,7 +616,7 @@ var l = Object.defineProperty, u = (e, t) => {
615
616
  children: y.value
616
617
  }), /* @__PURE__ */ c("span", {
617
618
  style: {
618
- ...J,
619
+ ...q,
619
620
  fontSize: I.counterFontSize,
620
621
  lineHeight: `${I.counterLineHeight}px`,
621
622
  color: g.fgMid
@@ -625,7 +626,7 @@ var l = Object.defineProperty, u = (e, t) => {
625
626
  }),
626
627
  x && /* @__PURE__ */ s("span", {
627
628
  style: {
628
- ...J,
629
+ ...q,
629
630
  fontSize: I.inputFontSize,
630
631
  lineHeight: `${I.inputLineHeight}px`,
631
632
  color: g.fgHigh,
@@ -636,14 +637,14 @@ var l = Object.defineProperty, u = (e, t) => {
636
637
  },
637
638
  children: x
638
639
  }),
639
- K.length > 0 && /* @__PURE__ */ s("div", {
640
+ G.length > 0 && /* @__PURE__ */ s("div", {
640
641
  style: {
641
642
  display: "flex",
642
643
  alignItems: "center",
643
644
  gap: 4,
644
645
  flexShrink: 0
645
646
  },
646
- children: K.map((t, n) => {
647
+ children: G.map((t, n) => {
647
648
  let r = D[t];
648
649
  return /* @__PURE__ */ c(e.Fragment, { children: [k && n > 0 && /* @__PURE__ */ s("div", { style: {
649
650
  width: 1,
@@ -653,7 +654,7 @@ var l = Object.defineProperty, u = (e, t) => {
653
654
  alignSelf: "center"
654
655
  } }), /* @__PURE__ */ s(r, {
655
656
  size: I.iconSize,
656
- color: H,
657
+ color: V,
657
658
  strokeWidth: 1.6,
658
659
  style: { flexShrink: 0 }
659
660
  })] }, `${t}-${n}`);
@@ -662,16 +663,16 @@ var l = Object.defineProperty, u = (e, t) => {
662
663
  ]
663
664
  })]
664
665
  })]
665
- }), q && /* @__PURE__ */ s("p", {
666
+ }), K && /* @__PURE__ */ s("p", {
666
667
  style: {
667
- ...J,
668
+ ...q,
668
669
  margin: 0,
669
670
  fontSize: I.helperFontSize,
670
671
  lineHeight: `${I.helperLineHeight}px`,
671
- color: W,
672
+ color: U,
672
673
  width: "100%"
673
674
  },
674
- children: q
675
+ children: K
675
676
  })]
676
677
  });
677
678
  }, k = h;
@@ -1 +1 @@
1
- {"version":3,"file":"senestia-ui.es.js","names":[],"sources":["../src/stories/Badge.tsx","../src/stories/tokens.ts","../src/stories/InputField.tsx","../src/index.ts"],"sourcesContent":["import React from 'react';\nimport { X } from 'lucide-react';\n\n// ─── Design System Font ──────────────────────────────────────────────────────\nconst font = 'Sarabun, sans-serif';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type BadgeColor =\n | 'Gray'\n | 'Primary'\n | 'Error'\n | 'Warning'\n | 'Success'\n | 'Blue light'\n | 'Blue'\n | 'Indigo'\n | 'Purple'\n | 'Pink'\n | 'Orange'\n | 'Gray blue';\n\nexport type BadgeSize = 'sm' | 'md' | 'lg';\n\nexport type BadgeType = 'Idle' | 'Status Dot' | 'Closable' | 'Pill color';\n\nexport interface BadgeProps {\n /** Badge label text */\n label?: string;\n /** Color variant */\n color?: BadgeColor;\n /** Size variant */\n size?: BadgeSize;\n /** Type / style variant */\n type?: BadgeType;\n /** Icon to render inside Pill color type (Lucide icon component) */\n icon?: React.ElementType;\n /** Called when close button is clicked (Closable type) */\n onClose?: () => void;\n}\n\n// ─── Color Tokens ────────────────────────────────────────────────────────────\n\nconst COLOR_TOKENS: Record<\n BadgeColor,\n { bg: string; border: string; text: string; dot: string }\n> = {\n Gray: { bg: '#f9fafb', border: '#eaecf0', text: '#06080b', dot: '#667085' },\n Primary: { bg: '#f4f6f9', border: '#e6ebf2', text: '#1e2b3b', dot: '#6c8fbe' },\n Error: { bg: '#fef0ef', border: '#fbd2d0', text: '#cc1a11', dot: '#f04438' },\n Warning: { bg: '#fff9ee', border: '#ffedcc', text: '#db8f02', dot: '#f79009' },\n Success: { bg: '#f0fdfa', border: '#d2f9f1', text: '#15a686', dot: '#12b76a' },\n 'Blue light': { bg: '#f0f9ff', border: '#b9e6fe', text: '#026aa2', dot: '#0ba5ec' },\n Blue: { bg: '#eff8ff', border: '#b2ddff', text: '#175cd3', dot: '#2e90fa' },\n Indigo: { bg: '#eef4ff', border: '#c7d7fe', text: '#3538cd', dot: '#6172f3' },\n Purple: { bg: '#f4f3ff', border: '#d9d6fe', text: '#5925dc', dot: '#7a5af8' },\n Pink: { bg: '#fef6fb', border: '#fce7f6', text: '#c11574', dot: '#ee46bc' },\n Orange: { bg: '#fef6ee', border: '#ffd6ae', text: '#b93815', dot: '#ef6820' },\n 'Gray blue':{ bg: '#f8f9fc', border: '#d5d9eb', text: '#363f72', dot: '#717bbc' },\n};\n\n// ─── Size Tokens ─────────────────────────────────────────────────────────────\n\nconst SIZE_TOKENS: Record<\n BadgeSize,\n {\n paddingX: number;\n paddingY: number;\n paddingXClose: { left: number; right: number };\n paddingXDot: { left: number; right: number };\n paddingPill: number;\n fontSize: number;\n lineHeight: number;\n dotSize: number;\n iconSize: number;\n closeSize: number;\n }\n> = {\n sm: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 5,\n fontSize: 12, lineHeight: 18,\n dotSize: 6, iconSize: 12, closeSize: 12,\n },\n md: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 6,\n fontSize: 14, lineHeight: 20,\n dotSize: 6, iconSize: 14, closeSize: 14,\n },\n lg: {\n paddingX: 12, paddingY: 4,\n paddingXClose: { left: 12, right: 6 },\n paddingXDot: { left: 8, right: 12 },\n paddingPill: 8,\n fontSize: 14, lineHeight: 20,\n dotSize: 8, iconSize: 16, closeSize: 16,\n },\n};\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const Badge: React.FC<BadgeProps> = ({\n label = 'Label',\n color = 'Gray',\n size = 'sm',\n type = 'Idle',\n icon: IconComponent,\n onClose,\n}) => {\n const c = COLOR_TOKENS[color];\n const s = SIZE_TOKENS[size];\n\n // ── Shared wrapper style ──────────────────────────────────────────────────\n const baseWrapper: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: c.bg,\n border: `1px solid ${c.border}`,\n borderRadius: 16,\n boxSizing: 'border-box',\n width: 'fit-content',\n fontFamily: font,\n };\n\n // ── Text style ────────────────────────────────────────────────────────────\n const textStyle: React.CSSProperties = {\n fontSize: s.fontSize,\n lineHeight: `${s.lineHeight}px`,\n fontWeight: 500,\n color: c.text,\n whiteSpace: 'nowrap',\n fontFamily: font,\n margin: 0,\n };\n\n // ── Idle ─────────────────────────────────────────────────────────────────\n if (type === 'Idle') {\n return (\n <span\n style={{\n ...baseWrapper,\n padding: `${s.paddingY}px ${s.paddingX}px`,\n }}\n >\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Status Dot ────────────────────────────────────────────────────────────\n if (type === 'Status Dot') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 4,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXDot.left,\n paddingRight: s.paddingXDot.right,\n }}\n >\n {/* Dot */}\n <span\n style={{\n display: 'inline-block',\n width: s.dotSize,\n height: s.dotSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n flexShrink: 0,\n }}\n />\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Closable ──────────────────────────────────────────────────────────────\n if (type === 'Closable') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 2,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXClose.left,\n paddingRight: s.paddingXClose.right,\n }}\n >\n <span style={textStyle}>{label}</span>\n <button\n onClick={onClose}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n padding: 2,\n borderRadius: 3,\n cursor: 'pointer',\n color: c.text,\n flexShrink: 0,\n lineHeight: 1,\n }}\n aria-label=\"Remove\"\n >\n <X size={s.closeSize} strokeWidth={2.5} />\n </button>\n </span>\n );\n }\n\n // ── Pill color (icon only) ────────────────────────────────────────────────\n if (type === 'Pill color') {\n const PillIcon = IconComponent;\n return (\n <span\n style={{\n ...baseWrapper,\n padding: s.paddingPill,\n }}\n >\n {PillIcon ? (\n <PillIcon size={s.iconSize} color={c.dot} strokeWidth={2} />\n ) : (\n // Default: colored circle dot\n <span\n style={{\n display: 'inline-block',\n width: s.iconSize,\n height: s.iconSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n }}\n />\n )}\n </span>\n );\n }\n\n return null;\n};\n","/**\n * Senestia Design System — Semantic Color Tokens\n *\n * ┌─────────────────────────────────────────────────────────────┐\n * │ Source: Figma DS-01 · Foundation → Semantic Color │\n * │ Use these tokens in components instead of raw hex values. │\n * └─────────────────────────────────────────────────────────────┘\n */\n\n// ─── Gray-Neutral ─────────────────────────────────────────────────────────────\n\nexport const grayNeutral = {\n /** Semantic/Gray-Neutral/fg/high — primary text, dark icons */\n fgHigh: '#1B1D22',\n /** Semantic/Gray-Neutral/fg/mid-on-white — label text, helper text, secondary icons */\n fgMid: '#6A6E83',\n /** Semantic/Gray-Neutral/fg/low-on-white — placeholder, disabled text */\n fgLow: '#9A9DAD',\n\n /** Semantic/Gray-Neutral/bg/white */\n bgWhite: '#FFFFFF',\n /** Semantic/Gray-Neutral/bg/lightgray — counter pill, subtle backgrounds */\n bgLightgray: '#F8F8F9',\n /** Semantic/Gray-Neutral/bg/disabled */\n bgDisabled: '#F3F4F6',\n\n /** Semantic/Gray-Neutral/border/midgray — default input border */\n borderMidgray: '#CFD1D9',\n /** Semantic/Gray-Neutral/border/light — dividers, card borders */\n borderLight: '#EBECEF',\n /** Disabled border (checkbox, input) */\n borderDisabled: '#E5EAF1',\n\n /** Gray/300 — icon separators */\n gray300: '#D0D5DD',\n /** Skeleton loading shimmer */\n bgSkeleton: '#EEF0F3',\n /** Strong disabled background (checkbox) */\n bgDisabledStrong: '#EBECEF',\n} as const;\n\n// ─── Status ───────────────────────────────────────────────────────────────────\n\nexport const status = {\n /** Error / invalid state */\n error: '#DB1439',\n /** Warning */\n warning: '#DB8F02',\n /** Success */\n success: '#15A686',\n} as const;\n\n// ─── CI Primary (Senestia brand purple) ───────────────────────────────────────\n\nexport const ciPrimary = {\n fgLow: '#C4B3F6',\n fgHigh: '#802CEB',\n bgLow: '#D4C9F6',\n bgMid: '#802CEB',\n bgHigh: '#5A1DA9',\n borderMid: '#996CF3',\n borderHigh: '#802CEB',\n} as const;\n\n// ─── OE Theme (OE brand blue) ─────────────────────────────────────────────────\n\nexport const oePrimary = {\n fgLow: '#5273A1',\n fgHigh: '#3A5274',\n bgLowest: '#EFF2F6', // selected item background in pickers\n bgLow: '#6E90BF',\n bgMid: '#5273A1',\n bgHigh: '#3A5274',\n borderLowest:'#C6D2E3', // focused item border\n borderLow: '#9CB3D2',\n borderMid: '#5273A1',\n /** Primary/300 — supporting/helper text on blue-tinted UI */\n p300: '#809BBF',\n /** Indigo/300 — \"Set to now\" link color */\n linkBlue: '#3C5BD5',\n} as const;\n\n// ─── Interactive states ───────────────────────────────────────────────────────\n\nexport const interactive = {\n /** Active / focused border */\n activeBorder: oePrimary.fgLow, // #5273A1\n /** Hover border */\n hoverBorder: '#3B82F6',\n /** Focus ring shadow */\n focusRing: '#D7DFEA',\n /** Invalid border */\n invalidBorder: status.error,\n} as const;\n\n// ─── Padding tokens (PD) ─────────────────────────────────────────────────────\n\nexport const padding = {\n 'PD-0': 0,\n 'PD-1': 1,\n 'PD-2': 2,\n 'PD-3': 4,\n 'PD-4': 6,\n 'PD-5': 8,\n 'PD-6': 12,\n 'PD-7': 16,\n 'PD-8': 24,\n 'PD-9': 32,\n 'PD-10': 40,\n 'PD-11': 48,\n 'PD-12': 56,\n 'PD-13': 64,\n 'PD-14': 72,\n 'PD-15': 80,\n} as const;\n\n// ─── Corner Radius tokens (CR) ───────────────────────────────────────────────\n\nexport const radius = {\n 'CR-0': 0,\n 'CR-1': 2,\n 'CR-2': 4,\n 'CR-3': 8,\n 'CR-4': 12,\n 'CR-5': 16,\n 'CR-6': 20,\n 'CR-7': 24,\n 'CR-8': 32,\n 'CR-9': 48,\n 'CR-10': 100,\n} as const;\n\n// ─── Typography ───────────────────────────────────────────────────────────────\n\nexport const font = 'Sarabun, sans-serif';\n","import React from 'react';\nimport { Circle, Info, XCircle, Search, Eye } from 'lucide-react';\nimport { grayNeutral, status, interactive, font } from './tokens';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type InputFieldState =\n | 'Idle'\n | 'Idle hover'\n | 'Active'\n | 'Idle invalid'\n | 'Idle invalid hover'\n | 'Idle invalid active'\n | 'Filled'\n | 'Filled hover'\n | 'Filled active'\n | 'Filled invalid'\n | 'Filled invalid hover'\n | 'Filled invalid active'\n | 'Disable'\n | 'Keyboard focus'\n | 'Skeleton';\n\nexport type InputFieldSize = 'sm' | 'md' | 'lg';\n\nexport type InputFieldTrailingIcon = 'clear' | 'password' | 'search';\n\nexport type InputFieldCounter = {\n value: number;\n max: number;\n};\n\nexport interface InputFieldProps {\n /** Label text displayed above the input */\n label: string;\n /** Show required asterisk (*) */\n required?: boolean;\n /** Remark text next to label e.g. \"(optional)\" */\n labelRemark?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Current value */\n value?: string;\n /** Called when value changes */\n onChange?: (value: string) => void;\n /** Helper text below the input (hidden when invalid) */\n helperText?: string;\n /** Error message below the input (shown when invalid state) */\n errorText?: string;\n /** Visual state from Figma */\n state?: InputFieldState;\n /** Input size — affects height, font, and padding */\n size?: InputFieldSize;\n /** Leading dropdown prefix text */\n leadingDropdownText?: string;\n /**\n * Leading icon inside the input (left side).\n * - `true` → default Circle icon\n * - `React.ElementType` → custom Lucide icon\n * - `false/undefined` → no icon\n */\n leadingIcon?: React.ElementType | boolean;\n /** Counter pill e.g. `{ value: 0, max: 20 }` */\n counter?: InputFieldCounter;\n /** Unit text inside the input */\n unit?: string;\n /** Single trailing icon */\n trailingIcon?: InputFieldTrailingIcon;\n /** Multiple trailing icons (overrides trailingIcon) */\n trailingIcons?: InputFieldTrailingIcon[];\n /** Show separator between trailing icons */\n trailingIconSeparator?: boolean;\n}\n\n// ─── Design tokens (from Figma) ──────────────────────────────────────────────\n\n/**\n * Size tokens — matched to Figma nodes:\n * sm (Sm-32): label C5 12/18 · input C4 14/20 · helper C5 12/18\n * md (Md-40): label C4 14/20 · input C3 16/24 · helper C4 14/20\n * lg (Lg-48): label C3 16/24 · input C3 16/24 · helper C4 14/20\n *\n * Spacing (per Figma sm node — gap-4 between all elements):\n * labelGap = gap between label row and input box\n * helperGap = gap between input box and helper/error text\n */\nconst sizeTokens = {\n sm: {\n inputHeight: 32,\n labelFontSize: 12, labelLineHeight: 18,\n inputFontSize: 14, inputLineHeight: 20,\n helperFontSize: 12, helperLineHeight: 18,\n paddingX: 12,\n iconSize: 16,\n labelIconSize: 12,\n labelGap: 4, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 8, leadingPr: 4, leadingPy: 6,\n chevronSize: 14,\n counterPadding: '1px 4px',\n counterRadius: 4,\n counterFontSize: 12, counterLineHeight: 18,\n skeletonLabelH: 18, skeletonInputH: 32,\n },\n md: {\n inputHeight: 40,\n labelFontSize: 14, labelLineHeight: 20,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 14,\n labelGap: 6, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 12, leadingPr: 8, leadingPy: 8,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 20, skeletonInputH: 40,\n },\n lg: {\n inputHeight: 48,\n labelFontSize: 16, labelLineHeight: 24,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 16,\n labelGap: 8, // label row → input\n helperGap: 6, // input → helper text\n leadingPl: 16, leadingPr: 8, leadingPy: 12,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 24, skeletonInputH: 48,\n },\n} as const;\n\n// ─── State helpers ────────────────────────────────────────────────────────────\n\nconst focusRingStyle = `0 0 0 2px ${interactive.focusRing}`;\n\nconst getStateFlags = (state: InputFieldState | undefined) => {\n const s = state ?? 'Idle';\n const isInvalid = s.includes('invalid');\n const isHover = s.includes('hover');\n const isActive = s === 'Active' || s === 'Keyboard focus' || s.endsWith('active');\n const isDisabled = s === 'Disable';\n const isSkeleton = s === 'Skeleton';\n const isFilled = s.includes('Filled');\n const isKeyboardFocus = s === 'Keyboard focus';\n return { s, isInvalid, isHover, isActive, isDisabled, isSkeleton, isFilled, isKeyboardFocus };\n};\n\n// ─── Trailing icon map → Lucide ───────────────────────────────────────────────\n\nconst TRAILING_ICON_MAP = {\n clear: XCircle,\n search: Search,\n password: Eye,\n} as const;\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const InputField = ({\n label,\n required = false,\n labelRemark,\n placeholder = 'Placeholder',\n value,\n onChange: _onChange,\n helperText,\n errorText,\n state = 'Idle',\n size = 'md',\n leadingDropdownText,\n leadingIcon,\n counter,\n unit,\n trailingIcon,\n trailingIcons,\n trailingIconSeparator = false,\n}: InputFieldProps) => {\n const { isInvalid, isHover, isActive, isDisabled, isSkeleton, isKeyboardFocus } =\n getStateFlags(state);\n\n const t = sizeTokens[size];\n\n // ── Colors — mapped to Semantic/Gray-Neutral tokens ─────────────────────\n const borderColor = isInvalid\n ? interactive.invalidBorder // status.error #DB1439\n : isActive || isKeyboardFocus\n ? interactive.activeBorder // oePrimary.fgLow #5273A1\n : isHover\n ? interactive.hoverBorder // #3B82F6\n : grayNeutral.borderMidgray; // #CFD1D9\n\n const background = isDisabled\n ? grayNeutral.bgDisabled // #F3F4F6\n : isHover\n ? grayNeutral.bgLightgray // #F8F8F9\n : grayNeutral.bgWhite; // #FFFFFF\n\n // Label text → fg/mid-on-white (disabled → fg/low)\n const labelColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n // Placeholder → fg/low-on-white (same whether disabled or not)\n const placeholderColor = grayNeutral.fgLow; // #9A9DAD\n\n // Typed value → fg/high (disabled → fg/low)\n const valueColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh; // #1B1D22\n\n // ── Icon colors (Figma: Semantic/Gray-Neutral/fg/high for input icons) ───\n // Input leading/trailing icons → fg/high (#1B1D22)\n const inputIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh;\n // Label info icon → fg/mid (same as label text, #6A6E83)\n const labelIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n const helperColor = isInvalid ? status.error : grayNeutral.fgMid; // #6A6E83\n\n // ── Skeleton ─────────────────────────────────────────────────────────────\n if (isSkeleton) {\n return (\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.labelGap }}>\n <div style={{ height: t.skeletonLabelH, background: grayNeutral.bgSkeleton, borderRadius: 6 }} />\n <div style={{ height: t.skeletonInputH, background: grayNeutral.bgSkeleton, border: `1px solid ${grayNeutral.bgSkeleton}`, borderRadius: 24 }} />\n </div>\n );\n }\n\n // ── Leading icon resolve ──────────────────────────────────────────────────\n // true → Circle (Figma default \"Icon/circle\"), component → custom, false → none\n const LeadingIconComponent: React.ElementType | null =\n leadingIcon === true\n ? Circle\n : leadingIcon\n ? (leadingIcon as React.ElementType)\n : null;\n\n // ── Trailing icons ────────────────────────────────────────────────────────\n const iconsToRender: InputFieldTrailingIcon[] =\n trailingIcons?.length ? trailingIcons : trailingIcon ? [trailingIcon] : [];\n\n // ── Text below input ──────────────────────────────────────────────────────\n const showText = isInvalid ? errorText : helperText;\n\n // ── Shared font style ─────────────────────────────────────────────────────\n const baseFont: React.CSSProperties = { fontFamily: font, fontWeight: 500 };\n\n return (\n /*\n * Outer wrapper — two-level gap structure matching Figma:\n * Level 1 (helperGap): separates [label + input block] from [helper text]\n * Level 2 (labelGap): separates [label row] from [input box]\n */\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.helperGap }}>\n\n {/* ── Level 1: label + input block ────────────────────────────────── */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: t.labelGap, width: '100%' }}>\n\n {/* Label row */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, width: '100%' }}>\n {/* Left: label text + info icon */}\n <div style={{ display: 'flex', flex: '1 0 0', alignItems: 'center', gap: t.labelIconSize === 12 ? 4 : 6, minWidth: 0 }}>\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {label}\n </span>\n {/* Info icon — fg/mid-on-white (same shade as label text) */}\n <Info\n size={t.labelIconSize}\n color={labelIconColor}\n strokeWidth={1.8}\n style={{ flexShrink: 0 }}\n />\n </div>\n\n {/* Right: remark or required marker */}\n {labelRemark && (\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n }}\n >\n {labelRemark}\n </span>\n )}\n {required && (\n <span style={{ color: status.error, fontWeight: 800, flexShrink: 0 }}>*</span>\n )}\n </div>\n\n {/* Input box */}\n <div\n style={{\n background,\n border: `1px solid ${borderColor}`,\n height: t.inputHeight,\n width: '100%',\n borderRadius: 24,\n display: 'flex',\n alignItems: leadingDropdownText ? 'stretch' : 'center',\n ...(leadingDropdownText ? {} : { gap: 8, padding: `0 ${t.paddingX}px` }),\n overflow: 'hidden',\n boxShadow: isActive || isKeyboardFocus ? focusRingStyle : 'none',\n opacity: isDisabled ? 0.7 : 1,\n boxSizing: 'border-box',\n }}\n >\n {/* Leading: dropdown prefix OR icon */}\n {leadingDropdownText ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n background: grayNeutral.bgWhite,\n padding: `${t.leadingPy}px ${t.leadingPr}px ${t.leadingPy}px ${t.leadingPl}px`,\n flexShrink: 0,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n }}\n >\n {leadingDropdownText}\n </span>\n <svg width={t.chevronSize} height={t.chevronSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M4 6L8 10L12 6\" stroke={grayNeutral.fgHigh} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n ) : LeadingIconComponent ? (\n /* Leading icon in input → fg/high (#1B1D22) per Figma */\n <LeadingIconComponent\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n ) : null}\n\n {/* Text + accessories area */}\n <div\n style={{\n flex: '1 0 0',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n height: '100%',\n minWidth: 0,\n ...(leadingDropdownText\n ? { borderLeft: `1px solid ${grayNeutral.borderLight}`, padding: `0 12px` }\n : {}),\n }}\n >\n {/* Placeholder / Value text */}\n <div\n style={{\n flex: '1 0 0',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: value ? valueColor : placeholderColor,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n display: 'block',\n width: '100%',\n }}\n >\n {value || placeholder}\n </span>\n </div>\n\n {/* Counter pill */}\n {counter && (\n <div\n style={{\n background: grayNeutral.bgLightgray,\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n justifyContent: 'center',\n padding: t.counterPadding,\n borderRadius: t.counterRadius,\n flexShrink: 0,\n opacity: isDisabled ? 0.7 : 1,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgHigh,\n }}\n >\n {counter.value}\n </span>\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgMid,\n }}\n >\n / {counter.max}\n </span>\n </div>\n )}\n\n {/* Unit text */}\n {unit && (\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n maxWidth: 64,\n overflow: 'hidden',\n }}\n >\n {unit}\n </span>\n )}\n\n {/* Trailing icons */}\n {iconsToRender.length > 0 && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n {iconsToRender.map((ic, idx) => {\n const TrailingIcon = TRAILING_ICON_MAP[ic];\n return (\n <React.Fragment key={`${ic}-${idx}`}>\n {trailingIconSeparator && idx > 0 && (\n <div\n style={{\n width: 1,\n height: t.iconSize,\n background: grayNeutral.gray300,\n flexShrink: 0,\n alignSelf: 'center',\n }}\n />\n )}\n {/* Trailing icon → fg/high (#1B1D22) per Figma */}\n <TrailingIcon\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n </React.Fragment>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Level 1: helper / error text ────────────────────────────────── */}\n {/*\n * No extra margin here — the outer helperGap (4px sm / 4px md / 6px lg)\n * from the flex container already provides the correct spacing from Figma.\n */}\n {showText && (\n <p\n style={{\n ...baseFont,\n margin: 0,\n fontSize: t.helperFontSize,\n lineHeight: `${t.helperLineHeight}px`,\n color: helperColor,\n width: '100%',\n }}\n >\n {showText}\n </p>\n )}\n </div>\n );\n};\n","// ─── Senestia Design System — Public API ─────────────────────────────────────\n//\n// import { Badge, InputField, tokens } from '@senestia/ui'\n//\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ── Components ────────────────────────────────────────────────────────────────\nexport { Badge } from './stories/Badge';\nexport { InputField } from './stories/InputField';\n\n// ── Component types ───────────────────────────────────────────────────────────\nexport type { BadgeProps, BadgeColor, BadgeSize, BadgeType } from './stories/Badge';\nexport type {\n InputFieldProps,\n InputFieldState,\n InputFieldSize,\n InputFieldTrailingIcon,\n InputFieldCounter,\n} from './stories/InputField';\n\n// ── Design Tokens ─────────────────────────────────────────────────────────────\nexport {\n // Colors\n grayNeutral,\n status,\n ciPrimary,\n oePrimary,\n interactive,\n // Spacing\n padding,\n radius,\n // Typography\n font,\n} from './stories/tokens';\n\n// ── Tokens namespace (for tree-shaking friendly usage) ────────────────────────\nimport * as _tokens from './stories/tokens';\nexport const tokens = _tokens;\n"],"mappings":"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"}
1
+ {"version":3,"file":"senestia-ui.es.js","names":[],"sources":["../src/stories/Badge.tsx","../src/stories/tokens.ts","../src/stories/InputField.tsx","../src/index.ts"],"sourcesContent":["import React from 'react';\nimport { X } from 'lucide-react';\n\n// ─── Design System Font ──────────────────────────────────────────────────────\nconst font = 'Sarabun, sans-serif';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type BadgeColor =\n | 'Gray'\n | 'Primary'\n | 'Error'\n | 'Warning'\n | 'Success'\n | 'Blue light'\n | 'Blue'\n | 'Indigo'\n | 'Purple'\n | 'Pink'\n | 'Orange'\n | 'Gray blue';\n\nexport type BadgeSize = 'sm' | 'md' | 'lg';\n\nexport type BadgeType = 'Idle' | 'Status Dot' | 'Closable' | 'Pill color';\n\nexport interface BadgeProps {\n /** Badge label text */\n label?: string;\n /** Color variant */\n color?: BadgeColor;\n /** Size variant */\n size?: BadgeSize;\n /** Type / style variant */\n type?: BadgeType;\n /** Icon to render inside Pill color type (Lucide icon component) */\n icon?: React.ElementType;\n /** Called when close button is clicked (Closable type) */\n onClose?: () => void;\n}\n\n// ─── Color Tokens ────────────────────────────────────────────────────────────\n\nconst COLOR_TOKENS: Record<\n BadgeColor,\n { bg: string; border: string; text: string; dot: string }\n> = {\n Gray: { bg: '#f9fafb', border: '#eaecf0', text: '#06080b', dot: '#667085' },\n Primary: { bg: '#f4f6f9', border: '#e6ebf2', text: '#1e2b3b', dot: '#6c8fbe' },\n Error: { bg: '#fef0ef', border: '#fbd2d0', text: '#cc1a11', dot: '#f04438' },\n Warning: { bg: '#fff9ee', border: '#ffedcc', text: '#db8f02', dot: '#f79009' },\n Success: { bg: '#f0fdfa', border: '#d2f9f1', text: '#15a686', dot: '#12b76a' },\n 'Blue light': { bg: '#f0f9ff', border: '#b9e6fe', text: '#026aa2', dot: '#0ba5ec' },\n Blue: { bg: '#eff8ff', border: '#b2ddff', text: '#175cd3', dot: '#2e90fa' },\n Indigo: { bg: '#eef4ff', border: '#c7d7fe', text: '#3538cd', dot: '#6172f3' },\n Purple: { bg: '#f4f3ff', border: '#d9d6fe', text: '#5925dc', dot: '#7a5af8' },\n Pink: { bg: '#fef6fb', border: '#fce7f6', text: '#c11574', dot: '#ee46bc' },\n Orange: { bg: '#fef6ee', border: '#ffd6ae', text: '#b93815', dot: '#ef6820' },\n 'Gray blue':{ bg: '#f8f9fc', border: '#d5d9eb', text: '#363f72', dot: '#717bbc' },\n};\n\n// ─── Size Tokens ─────────────────────────────────────────────────────────────\n\nconst SIZE_TOKENS: Record<\n BadgeSize,\n {\n paddingX: number;\n paddingY: number;\n paddingXClose: { left: number; right: number };\n paddingXDot: { left: number; right: number };\n paddingPill: number;\n fontSize: number;\n lineHeight: number;\n dotSize: number;\n iconSize: number;\n closeSize: number;\n }\n> = {\n sm: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 5,\n fontSize: 12, lineHeight: 18,\n dotSize: 6, iconSize: 12, closeSize: 12,\n },\n md: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 6,\n fontSize: 14, lineHeight: 20,\n dotSize: 6, iconSize: 14, closeSize: 14,\n },\n lg: {\n paddingX: 12, paddingY: 4,\n paddingXClose: { left: 12, right: 6 },\n paddingXDot: { left: 8, right: 12 },\n paddingPill: 8,\n fontSize: 14, lineHeight: 20,\n dotSize: 8, iconSize: 16, closeSize: 16,\n },\n};\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const Badge: React.FC<BadgeProps> = ({\n label = 'Label',\n color = 'Gray',\n size = 'sm',\n type = 'Idle',\n icon: IconComponent,\n onClose,\n}) => {\n const c = COLOR_TOKENS[color];\n const s = SIZE_TOKENS[size];\n\n // ── Shared wrapper style ──────────────────────────────────────────────────\n const baseWrapper: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: c.bg,\n border: `1px solid ${c.border}`,\n borderRadius: 16,\n boxSizing: 'border-box',\n width: 'fit-content',\n fontFamily: font,\n };\n\n // ── Text style ────────────────────────────────────────────────────────────\n const textStyle: React.CSSProperties = {\n fontSize: s.fontSize,\n lineHeight: `${s.lineHeight}px`,\n fontWeight: 500,\n color: c.text,\n whiteSpace: 'nowrap',\n fontFamily: font,\n margin: 0,\n };\n\n // ── Idle ─────────────────────────────────────────────────────────────────\n if (type === 'Idle') {\n return (\n <span\n style={{\n ...baseWrapper,\n padding: `${s.paddingY}px ${s.paddingX}px`,\n }}\n >\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Status Dot ────────────────────────────────────────────────────────────\n if (type === 'Status Dot') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 4,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXDot.left,\n paddingRight: s.paddingXDot.right,\n }}\n >\n {/* Dot */}\n <span\n style={{\n display: 'inline-block',\n width: s.dotSize,\n height: s.dotSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n flexShrink: 0,\n }}\n />\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Closable ──────────────────────────────────────────────────────────────\n if (type === 'Closable') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 2,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXClose.left,\n paddingRight: s.paddingXClose.right,\n }}\n >\n <span style={textStyle}>{label}</span>\n <button\n onClick={onClose}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n padding: 2,\n borderRadius: 3,\n cursor: 'pointer',\n color: c.text,\n flexShrink: 0,\n lineHeight: 1,\n }}\n aria-label=\"Remove\"\n >\n <X size={s.closeSize} strokeWidth={2.5} />\n </button>\n </span>\n );\n }\n\n // ── Pill color (icon only) ────────────────────────────────────────────────\n if (type === 'Pill color') {\n const PillIcon = IconComponent;\n return (\n <span\n style={{\n ...baseWrapper,\n padding: s.paddingPill,\n }}\n >\n {PillIcon ? (\n <PillIcon size={s.iconSize} color={c.dot} strokeWidth={2} />\n ) : (\n // Default: colored circle dot\n <span\n style={{\n display: 'inline-block',\n width: s.iconSize,\n height: s.iconSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n }}\n />\n )}\n </span>\n );\n }\n\n return null;\n};\n","/**\n * Senestia Design System — Semantic Color Tokens\n *\n * ┌─────────────────────────────────────────────────────────────┐\n * │ Source: Figma DS-01 · Foundation → Semantic Color │\n * │ Use these tokens in components instead of raw hex values. │\n * └─────────────────────────────────────────────────────────────┘\n */\n\n// ─── Gray-Neutral ─────────────────────────────────────────────────────────────\n\nexport const grayNeutral = {\n /** Semantic/Gray-Neutral/fg/high — primary text, dark icons */\n fgHigh: '#1B1D22',\n /** Semantic/Gray-Neutral/fg/mid-on-white — label text, helper text, secondary icons */\n fgMid: '#6A6E83',\n /** Semantic/Gray-Neutral/fg/low-on-white — placeholder, disabled text */\n fgLow: '#9A9DAD',\n\n /** Semantic/Gray-Neutral/bg/white */\n bgWhite: '#FFFFFF',\n /** Semantic/Gray-Neutral/bg/lightgray — counter pill, subtle backgrounds */\n bgLightgray: '#F8F8F9',\n /** Semantic/Gray-Neutral/bg/disabled */\n bgDisabled: '#F3F4F6',\n\n /** Semantic/Gray-Neutral/border/midgray — default input border */\n borderMidgray: '#CFD1D9',\n /** Semantic/Gray-Neutral/border/light — dividers, card borders */\n borderLight: '#EBECEF',\n /** Disabled border (checkbox, input) */\n borderDisabled: '#E5EAF1',\n\n /** Gray/300 — icon separators */\n gray300: '#D0D5DD',\n /** Skeleton loading shimmer */\n bgSkeleton: '#EEF0F3',\n /** Strong disabled background (checkbox) */\n bgDisabledStrong: '#EBECEF',\n} as const;\n\n// ─── Status ───────────────────────────────────────────────────────────────────\n\nexport const status = {\n /** Error / invalid state */\n error: '#DB1439',\n /** Warning */\n warning: '#DB8F02',\n /** Success */\n success: '#15A686',\n} as const;\n\n// ─── CI Primary (Senestia brand purple) ───────────────────────────────────────\n\nexport const ciPrimary = {\n fgLow: '#C4B3F6',\n fgHigh: '#802CEB',\n bgLow: '#D4C9F6',\n bgMid: '#802CEB',\n bgHigh: '#5A1DA9',\n borderMid: '#996CF3',\n borderHigh: '#802CEB',\n} as const;\n\n// ─── OE Theme (OE brand blue) ─────────────────────────────────────────────────\n\nexport const oePrimary = {\n fgLow: '#5273A1',\n fgHigh: '#3A5274',\n bgLowest: '#EFF2F6', // selected item background in pickers\n bgLow: '#6E90BF',\n bgMid: '#5273A1',\n bgHigh: '#3A5274',\n borderLowest:'#C6D2E3', // focused item border\n borderLow: '#9CB3D2',\n borderMid: '#5273A1',\n /** Primary/300 — supporting/helper text on blue-tinted UI */\n p300: '#809BBF',\n /** Indigo/300 — \"Set to now\" link color */\n linkBlue: '#3C5BD5',\n} as const;\n\n// ─── Interactive states ───────────────────────────────────────────────────────\n\nexport const interactive = {\n /** Active / focused border */\n activeBorder: oePrimary.fgLow, // #5273A1\n /** Hover border */\n hoverBorder: '#3B82F6',\n /** Focus ring shadow */\n focusRing: '#D7DFEA',\n /** Invalid border */\n invalidBorder: status.error,\n} as const;\n\n// ─── Padding tokens (PD) ─────────────────────────────────────────────────────\n\nexport const padding = {\n 'PD-0': 0,\n 'PD-1': 1,\n 'PD-2': 2,\n 'PD-3': 4,\n 'PD-4': 6,\n 'PD-5': 8,\n 'PD-6': 12,\n 'PD-7': 16,\n 'PD-8': 24,\n 'PD-9': 32,\n 'PD-10': 40,\n 'PD-11': 48,\n 'PD-12': 56,\n 'PD-13': 64,\n 'PD-14': 72,\n 'PD-15': 80,\n} as const;\n\n// ─── Corner Radius tokens (CR) ───────────────────────────────────────────────\n\nexport const radius = {\n 'CR-0': 0,\n 'CR-1': 2,\n 'CR-2': 4,\n 'CR-3': 8,\n 'CR-4': 12,\n 'CR-5': 16,\n 'CR-6': 20,\n 'CR-7': 24,\n 'CR-8': 32,\n 'CR-9': 48,\n 'CR-10': 100,\n} as const;\n\n// ─── Typography ───────────────────────────────────────────────────────────────\n\nexport const font = 'Sarabun, sans-serif';\n","import React from 'react';\nimport { Circle, Info, XCircle, Search, Eye } from 'lucide-react';\nimport { grayNeutral, status, interactive, font } from './tokens';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type InputFieldState =\n | 'Idle'\n | 'Idle hover'\n | 'Active'\n | 'Idle invalid'\n | 'Idle invalid hover'\n | 'Idle invalid active'\n | 'Filled'\n | 'Filled hover'\n | 'Filled active'\n | 'Filled invalid'\n | 'Filled invalid hover'\n | 'Filled invalid active'\n | 'Disable'\n | 'Keyboard focus'\n | 'Skeleton';\n\nexport type InputFieldSize = 'sm' | 'md' | 'lg';\n\nexport type InputFieldTrailingIcon = 'clear' | 'password' | 'search';\n\nexport type InputFieldCounter = {\n value: number;\n max: number;\n};\n\nexport interface InputFieldProps {\n /** Label text displayed above the input */\n label: string;\n /** Show required asterisk (*) */\n required?: boolean;\n /** Remark text next to label e.g. \"(optional)\" */\n labelRemark?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Current value */\n value?: string;\n /** Called when value changes */\n onChange?: (value: string) => void;\n /** Helper text below the input (hidden when invalid) */\n helperText?: string;\n /** Error message below the input (shown when invalid state) */\n errorText?: string;\n /** Visual state from Figma */\n state?: InputFieldState;\n /** Input size — affects height, font, and padding */\n size?: InputFieldSize;\n /** Leading dropdown prefix text */\n leadingDropdownText?: string;\n /**\n * Leading icon inside the input (left side).\n * - `true` → default Circle icon\n * - `React.ElementType` → custom Lucide icon\n * - `false/undefined` → no icon\n */\n leadingIcon?: React.ElementType | boolean;\n /** Counter pill e.g. `{ value: 0, max: 20 }` */\n counter?: InputFieldCounter;\n /** Unit text inside the input */\n unit?: string;\n /** Single trailing icon */\n trailingIcon?: InputFieldTrailingIcon;\n /** Multiple trailing icons (overrides trailingIcon) */\n trailingIcons?: InputFieldTrailingIcon[];\n /** Show separator between trailing icons */\n trailingIconSeparator?: boolean;\n}\n\n// ─── Design tokens (from Figma) ──────────────────────────────────────────────\n\n/**\n * Size tokens — matched to Figma nodes:\n * sm (Sm-32): label C5 12/18 · input C4 14/20 · helper C5 12/18\n * md (Md-40): label C4 14/20 · input C3 16/24 · helper C4 14/20\n * lg (Lg-48): label C3 16/24 · input C3 16/24 · helper C4 14/20\n *\n * Spacing (per Figma sm node — gap-4 between all elements):\n * labelGap = gap between label row and input box\n * helperGap = gap between input box and helper/error text\n */\nconst sizeTokens = {\n sm: {\n inputHeight: 32,\n labelFontSize: 12, labelLineHeight: 18,\n inputFontSize: 14, inputLineHeight: 20,\n helperFontSize: 12, helperLineHeight: 18,\n paddingX: 12,\n iconSize: 16,\n labelIconSize: 12,\n labelGap: 4, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 8, leadingPr: 4, leadingPy: 6,\n chevronSize: 14,\n counterPadding: '1px 4px',\n counterRadius: 4,\n counterFontSize: 12, counterLineHeight: 18,\n skeletonLabelH: 18, skeletonInputH: 32,\n },\n md: {\n inputHeight: 40,\n labelFontSize: 14, labelLineHeight: 20,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 14,\n labelGap: 6, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 12, leadingPr: 8, leadingPy: 8,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 20, skeletonInputH: 40,\n },\n lg: {\n inputHeight: 48,\n labelFontSize: 16, labelLineHeight: 24,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 16,\n labelGap: 8, // label row → input\n helperGap: 6, // input → helper text\n leadingPl: 16, leadingPr: 8, leadingPy: 12,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 24, skeletonInputH: 48,\n },\n} as const;\n\n// ─── State helpers ────────────────────────────────────────────────────────────\n\nconst focusRingStyle = `0 0 0 2px ${interactive.focusRing}`;\n\nconst getStateFlags = (state: InputFieldState | undefined) => {\n const s = state ?? 'Idle';\n const isInvalid = s.includes('invalid');\n const isHover = s.includes('hover');\n const isActive = s === 'Active' || s === 'Keyboard focus' || s.endsWith('active');\n const isDisabled = s === 'Disable';\n const isSkeleton = s === 'Skeleton';\n const isFilled = s.includes('Filled');\n const isKeyboardFocus = s === 'Keyboard focus';\n return { s, isInvalid, isHover, isActive, isDisabled, isSkeleton, isFilled, isKeyboardFocus };\n};\n\n// ─── Trailing icon map → Lucide ───────────────────────────────────────────────\n\nconst TRAILING_ICON_MAP = {\n clear: XCircle,\n search: Search,\n password: Eye,\n} as const;\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const InputField = ({\n label,\n required = false,\n labelRemark,\n placeholder = 'Placeholder',\n value,\n onChange: _onChange,\n helperText,\n errorText,\n state = 'Idle',\n size = 'md',\n leadingDropdownText,\n leadingIcon,\n counter,\n unit,\n trailingIcon,\n trailingIcons,\n trailingIconSeparator = false,\n}: InputFieldProps) => {\n const { isInvalid, isHover, isActive, isDisabled, isSkeleton, isKeyboardFocus } =\n getStateFlags(state);\n\n const t = sizeTokens[size];\n\n // ── Colors — mapped to Semantic/Gray-Neutral tokens ─────────────────────\n const borderColor = isInvalid\n ? interactive.invalidBorder // status.error #DB1439\n : isActive || isKeyboardFocus\n ? interactive.activeBorder // oePrimary.fgLow #5273A1\n : isHover\n ? interactive.hoverBorder // #3B82F6\n : grayNeutral.borderMidgray; // #CFD1D9\n\n const background = isDisabled\n ? grayNeutral.bgDisabled // #F3F4F6\n : isHover\n ? grayNeutral.bgLightgray // #F8F8F9\n : grayNeutral.bgWhite; // #FFFFFF\n\n // Label text → fg/mid-on-white (disabled → fg/low)\n const labelColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n // Typed value → fg/high (disabled → fg/low)\n const valueColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh; // #1B1D22\n\n // ── Icon colors (Figma: Semantic/Gray-Neutral/fg/high for input icons) ───\n // Input leading/trailing icons → fg/high (#1B1D22)\n const inputIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh;\n // Label info icon → fg/mid (same as label text, #6A6E83)\n const labelIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n const helperColor = isInvalid ? status.error : grayNeutral.fgMid; // #6A6E83\n\n // ── Skeleton ─────────────────────────────────────────────────────────────\n if (isSkeleton) {\n return (\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.labelGap }}>\n <div style={{ height: t.skeletonLabelH, background: grayNeutral.bgSkeleton, borderRadius: 6 }} />\n <div style={{ height: t.skeletonInputH, background: grayNeutral.bgSkeleton, border: `1px solid ${grayNeutral.bgSkeleton}`, borderRadius: 24 }} />\n </div>\n );\n }\n\n // ── Leading icon resolve ──────────────────────────────────────────────────\n // true → Circle (Figma default \"Icon/circle\"), component → custom, false → none\n const LeadingIconComponent: React.ElementType | null =\n leadingIcon === true\n ? Circle\n : leadingIcon\n ? (leadingIcon as React.ElementType)\n : null;\n\n // ── Trailing icons ────────────────────────────────────────────────────────\n const iconsToRender: InputFieldTrailingIcon[] =\n trailingIcons?.length ? trailingIcons : trailingIcon ? [trailingIcon] : [];\n\n // ── Text below input ──────────────────────────────────────────────────────\n const showText = isInvalid ? errorText : helperText;\n\n // ── Shared font style ─────────────────────────────────────────────────────\n const baseFont: React.CSSProperties = { fontFamily: font, fontWeight: 500 };\n\n return (\n /*\n * Outer wrapper — two-level gap structure matching Figma:\n * Level 1 (helperGap): separates [label + input block] from [helper text]\n * Level 2 (labelGap): separates [label row] from [input box]\n */\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.helperGap }}>\n\n {/* ── Level 1: label + input block ────────────────────────────────── */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: t.labelGap, width: '100%' }}>\n\n {/* Label row */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, width: '100%' }}>\n {/* Left: label text + info icon */}\n <div style={{ display: 'flex', flex: '1 0 0', alignItems: 'center', gap: t.labelIconSize === 12 ? 4 : 6, minWidth: 0 }}>\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {label}\n </span>\n {/* Info icon — fg/mid-on-white (same shade as label text) */}\n <Info\n size={t.labelIconSize}\n color={labelIconColor}\n strokeWidth={1.8}\n style={{ flexShrink: 0 }}\n />\n </div>\n\n {/* Right: remark or required marker */}\n {labelRemark && (\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n }}\n >\n {labelRemark}\n </span>\n )}\n {required && (\n <span style={{ color: status.error, fontWeight: 800, flexShrink: 0 }}>*</span>\n )}\n </div>\n\n {/* Input box */}\n <div\n style={{\n background,\n border: `1px solid ${borderColor}`,\n height: t.inputHeight,\n width: '100%',\n borderRadius: 24,\n display: 'flex',\n alignItems: leadingDropdownText ? 'stretch' : 'center',\n ...(leadingDropdownText ? {} : { gap: 8, padding: `0 ${t.paddingX}px` }),\n overflow: 'hidden',\n boxShadow: isActive || isKeyboardFocus ? focusRingStyle : 'none',\n opacity: isDisabled ? 0.7 : 1,\n boxSizing: 'border-box',\n }}\n >\n {/* Leading: dropdown prefix OR icon */}\n {leadingDropdownText ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n background: grayNeutral.bgWhite,\n padding: `${t.leadingPy}px ${t.leadingPr}px ${t.leadingPy}px ${t.leadingPl}px`,\n flexShrink: 0,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n }}\n >\n {leadingDropdownText}\n </span>\n <svg width={t.chevronSize} height={t.chevronSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M4 6L8 10L12 6\" stroke={grayNeutral.fgHigh} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n ) : LeadingIconComponent ? (\n /* Leading icon in input → fg/high (#1B1D22) per Figma */\n <LeadingIconComponent\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n ) : null}\n\n {/* Text + accessories area */}\n <div\n style={{\n flex: '1 0 0',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n height: '100%',\n minWidth: 0,\n ...(leadingDropdownText\n ? { borderLeft: `1px solid ${grayNeutral.borderLight}`, padding: `0 12px` }\n : {}),\n }}\n >\n {/* Input */}\n <input\n type=\"text\"\n value={value ?? ''}\n onChange={e => _onChange?.(e.target.value)}\n placeholder={placeholder}\n disabled={isDisabled}\n style={{\n ...baseFont,\n flex: '1 0 0',\n border: 'none',\n outline: 'none',\n background: 'transparent',\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: valueColor,\n width: '100%',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n cursor: isDisabled ? 'not-allowed' : 'text',\n }}\n />\n\n {/* Counter pill */}\n {counter && (\n <div\n style={{\n background: grayNeutral.bgLightgray,\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n justifyContent: 'center',\n padding: t.counterPadding,\n borderRadius: t.counterRadius,\n flexShrink: 0,\n opacity: isDisabled ? 0.7 : 1,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgHigh,\n }}\n >\n {counter.value}\n </span>\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgMid,\n }}\n >\n / {counter.max}\n </span>\n </div>\n )}\n\n {/* Unit text */}\n {unit && (\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n maxWidth: 64,\n overflow: 'hidden',\n }}\n >\n {unit}\n </span>\n )}\n\n {/* Trailing icons */}\n {iconsToRender.length > 0 && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n {iconsToRender.map((ic, idx) => {\n const TrailingIcon = TRAILING_ICON_MAP[ic];\n return (\n <React.Fragment key={`${ic}-${idx}`}>\n {trailingIconSeparator && idx > 0 && (\n <div\n style={{\n width: 1,\n height: t.iconSize,\n background: grayNeutral.gray300,\n flexShrink: 0,\n alignSelf: 'center',\n }}\n />\n )}\n {/* Trailing icon → fg/high (#1B1D22) per Figma */}\n <TrailingIcon\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n </React.Fragment>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Level 1: helper / error text ────────────────────────────────── */}\n {/*\n * No extra margin here — the outer helperGap (4px sm / 4px md / 6px lg)\n * from the flex container already provides the correct spacing from Figma.\n */}\n {showText && (\n <p\n style={{\n ...baseFont,\n margin: 0,\n fontSize: t.helperFontSize,\n lineHeight: `${t.helperLineHeight}px`,\n color: helperColor,\n width: '100%',\n }}\n >\n {showText}\n </p>\n )}\n </div>\n );\n};\n","// ─── Senestia Design System — Public API ─────────────────────────────────────\n//\n// import { Badge, InputField, tokens } from '@senestia/ui'\n//\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ── Components ────────────────────────────────────────────────────────────────\nexport { Badge } from './stories/Badge';\nexport { InputField } from './stories/InputField';\n\n// ── Component types ───────────────────────────────────────────────────────────\nexport type { BadgeProps, BadgeColor, BadgeSize, BadgeType } from './stories/Badge';\nexport type {\n InputFieldProps,\n InputFieldState,\n InputFieldSize,\n InputFieldTrailingIcon,\n InputFieldCounter,\n} from './stories/InputField';\n\n// ── Design Tokens ─────────────────────────────────────────────────────────────\nexport {\n // Colors\n grayNeutral,\n status,\n ciPrimary,\n oePrimary,\n interactive,\n // Spacing\n padding,\n radius,\n // Typography\n font,\n} from './stories/tokens';\n\n// ── Tokens namespace (for tree-shaking friendly usage) ────────────────────────\nimport * as _tokens from './stories/tokens';\nexport const tokens = _tokens;\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`react`),require(`lucide-react`),require(`react/jsx-runtime`)):typeof define==`function`&&define.amd?define([`exports`,`react`,`lucide-react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.SenestiaUI={},e.React,e.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t)=>{let n={};for(var r in e)a(n,r,{get:e[r],enumerable:!0});return t||a(n,Symbol.toStringTag,{value:`Module`}),n},d=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:i(c(e)),d(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e)))(t);var f=`Sarabun, sans-serif`,p={Gray:{bg:`#f9fafb`,border:`#eaecf0`,text:`#06080b`,dot:`#667085`},Primary:{bg:`#f4f6f9`,border:`#e6ebf2`,text:`#1e2b3b`,dot:`#6c8fbe`},Error:{bg:`#fef0ef`,border:`#fbd2d0`,text:`#cc1a11`,dot:`#f04438`},Warning:{bg:`#fff9ee`,border:`#ffedcc`,text:`#db8f02`,dot:`#f79009`},Success:{bg:`#f0fdfa`,border:`#d2f9f1`,text:`#15a686`,dot:`#12b76a`},"Blue light":{bg:`#f0f9ff`,border:`#b9e6fe`,text:`#026aa2`,dot:`#0ba5ec`},Blue:{bg:`#eff8ff`,border:`#b2ddff`,text:`#175cd3`,dot:`#2e90fa`},Indigo:{bg:`#eef4ff`,border:`#c7d7fe`,text:`#3538cd`,dot:`#6172f3`},Purple:{bg:`#f4f3ff`,border:`#d9d6fe`,text:`#5925dc`,dot:`#7a5af8`},Pink:{bg:`#fef6fb`,border:`#fce7f6`,text:`#c11574`,dot:`#ee46bc`},Orange:{bg:`#fef6ee`,border:`#ffd6ae`,text:`#b93815`,dot:`#ef6820`},"Gray blue":{bg:`#f8f9fc`,border:`#d5d9eb`,text:`#363f72`,dot:`#717bbc`}},m={sm:{paddingX:8,paddingY:2,paddingXClose:{left:8,right:4},paddingXDot:{left:6,right:8},paddingPill:5,fontSize:12,lineHeight:18,dotSize:6,iconSize:12,closeSize:12},md:{paddingX:8,paddingY:2,paddingXClose:{left:8,right:4},paddingXDot:{left:6,right:8},paddingPill:6,fontSize:14,lineHeight:20,dotSize:6,iconSize:14,closeSize:14},lg:{paddingX:12,paddingY:4,paddingXClose:{left:12,right:6},paddingXDot:{left:8,right:12},paddingPill:8,fontSize:14,lineHeight:20,dotSize:8,iconSize:16,closeSize:16}},h=({label:e=`Label`,color:t=`Gray`,size:i=`sm`,type:a=`Idle`,icon:o,onClose:s})=>{let c=p[t],l=m[i],u={display:`inline-flex`,alignItems:`center`,backgroundColor:c.bg,border:`1px solid ${c.border}`,borderRadius:16,boxSizing:`border-box`,width:`fit-content`,fontFamily:f},d={fontSize:l.fontSize,lineHeight:`${l.lineHeight}px`,fontWeight:500,color:c.text,whiteSpace:`nowrap`,fontFamily:f,margin:0};if(a===`Idle`)return(0,r.jsx)(`span`,{style:{...u,padding:`${l.paddingY}px ${l.paddingX}px`},children:(0,r.jsx)(`span`,{style:d,children:e})});if(a===`Status Dot`)return(0,r.jsxs)(`span`,{style:{...u,gap:4,paddingTop:l.paddingY,paddingBottom:l.paddingY,paddingLeft:l.paddingXDot.left,paddingRight:l.paddingXDot.right},children:[(0,r.jsx)(`span`,{style:{display:`inline-block`,width:l.dotSize,height:l.dotSize,borderRadius:`50%`,backgroundColor:c.dot,flexShrink:0}}),(0,r.jsx)(`span`,{style:d,children:e})]});if(a===`Closable`)return(0,r.jsxs)(`span`,{style:{...u,gap:2,paddingTop:l.paddingY,paddingBottom:l.paddingY,paddingLeft:l.paddingXClose.left,paddingRight:l.paddingXClose.right},children:[(0,r.jsx)(`span`,{style:d,children:e}),(0,r.jsx)(`button`,{onClick:s,style:{display:`inline-flex`,alignItems:`center`,justifyContent:`center`,background:`none`,border:`none`,padding:2,borderRadius:3,cursor:`pointer`,color:c.text,flexShrink:0,lineHeight:1},"aria-label":`Remove`,children:(0,r.jsx)(n.X,{size:l.closeSize,strokeWidth:2.5})})]});if(a===`Pill color`){let e=o;return(0,r.jsx)(`span`,{style:{...u,padding:l.paddingPill},children:e?(0,r.jsx)(e,{size:l.iconSize,color:c.dot,strokeWidth:2}):(0,r.jsx)(`span`,{style:{display:`inline-block`,width:l.iconSize,height:l.iconSize,borderRadius:`50%`,backgroundColor:c.dot}})})}return null},g=u({ciPrimary:()=>y,font:()=>w,grayNeutral:()=>_,interactive:()=>x,oePrimary:()=>b,padding:()=>S,radius:()=>C,status:()=>v}),_={fgHigh:`#1B1D22`,fgMid:`#6A6E83`,fgLow:`#9A9DAD`,bgWhite:`#FFFFFF`,bgLightgray:`#F8F8F9`,bgDisabled:`#F3F4F6`,borderMidgray:`#CFD1D9`,borderLight:`#EBECEF`,borderDisabled:`#E5EAF1`,gray300:`#D0D5DD`,bgSkeleton:`#EEF0F3`,bgDisabledStrong:`#EBECEF`},v={error:`#DB1439`,warning:`#DB8F02`,success:`#15A686`},y={fgLow:`#C4B3F6`,fgHigh:`#802CEB`,bgLow:`#D4C9F6`,bgMid:`#802CEB`,bgHigh:`#5A1DA9`,borderMid:`#996CF3`,borderHigh:`#802CEB`},b={fgLow:`#5273A1`,fgHigh:`#3A5274`,bgLowest:`#EFF2F6`,bgLow:`#6E90BF`,bgMid:`#5273A1`,bgHigh:`#3A5274`,borderLowest:`#C6D2E3`,borderLow:`#9CB3D2`,borderMid:`#5273A1`,p300:`#809BBF`,linkBlue:`#3C5BD5`},x={activeBorder:b.fgLow,hoverBorder:`#3B82F6`,focusRing:`#D7DFEA`,invalidBorder:v.error},S={"PD-0":0,"PD-1":1,"PD-2":2,"PD-3":4,"PD-4":6,"PD-5":8,"PD-6":12,"PD-7":16,"PD-8":24,"PD-9":32,"PD-10":40,"PD-11":48,"PD-12":56,"PD-13":64,"PD-14":72,"PD-15":80},C={"CR-0":0,"CR-1":2,"CR-2":4,"CR-3":8,"CR-4":12,"CR-5":16,"CR-6":20,"CR-7":24,"CR-8":32,"CR-9":48,"CR-10":100},w=`Sarabun, sans-serif`,T={sm:{inputHeight:32,labelFontSize:12,labelLineHeight:18,inputFontSize:14,inputLineHeight:20,helperFontSize:12,helperLineHeight:18,paddingX:12,iconSize:16,labelIconSize:12,labelGap:4,helperGap:4,leadingPl:8,leadingPr:4,leadingPy:6,chevronSize:14,counterPadding:`1px 4px`,counterRadius:4,counterFontSize:12,counterLineHeight:18,skeletonLabelH:18,skeletonInputH:32},md:{inputHeight:40,labelFontSize:14,labelLineHeight:20,inputFontSize:16,inputLineHeight:24,helperFontSize:14,helperLineHeight:20,paddingX:16,iconSize:20,labelIconSize:14,labelGap:6,helperGap:4,leadingPl:12,leadingPr:8,leadingPy:8,chevronSize:16,counterPadding:`2px 8px`,counterRadius:8,counterFontSize:14,counterLineHeight:20,skeletonLabelH:20,skeletonInputH:40},lg:{inputHeight:48,labelFontSize:16,labelLineHeight:24,inputFontSize:16,inputLineHeight:24,helperFontSize:14,helperLineHeight:20,paddingX:16,iconSize:20,labelIconSize:16,labelGap:8,helperGap:6,leadingPl:16,leadingPr:8,leadingPy:12,chevronSize:16,counterPadding:`2px 8px`,counterRadius:8,counterFontSize:14,counterLineHeight:20,skeletonLabelH:24,skeletonInputH:48}},E=`0 0 0 2px ${x.focusRing}`,D=e=>{let t=e??`Idle`;return{s:t,isInvalid:t.includes(`invalid`),isHover:t.includes(`hover`),isActive:t===`Active`||t===`Keyboard focus`||t.endsWith(`active`),isDisabled:t===`Disable`,isSkeleton:t===`Skeleton`,isFilled:t.includes(`Filled`),isKeyboardFocus:t===`Keyboard focus`}},O={clear:n.XCircle,search:n.Search,password:n.Eye},k=({label:e,required:i=!1,labelRemark:a,placeholder:o=`Placeholder`,value:s,onChange:c,helperText:l,errorText:u,state:d=`Idle`,size:f=`md`,leadingDropdownText:p,leadingIcon:m,counter:h,unit:g,trailingIcon:y,trailingIcons:b,trailingIconSeparator:S=!1})=>{let{isInvalid:C,isHover:k,isActive:A,isDisabled:j,isSkeleton:M,isKeyboardFocus:N}=D(d),P=T[f],F=C?x.invalidBorder:A||N?x.activeBorder:k?x.hoverBorder:_.borderMidgray,I=j?_.bgDisabled:k?_.bgLightgray:_.bgWhite,L=j?_.fgLow:_.fgMid,R=_.fgLow,z=j?_.fgLow:_.fgHigh,B=j?_.fgLow:_.fgHigh,V=j?_.fgLow:_.fgMid,H=C?v.error:_.fgMid;if(M)return(0,r.jsxs)(`div`,{style:{width:320,display:`flex`,flexDirection:`column`,gap:P.labelGap},children:[(0,r.jsx)(`div`,{style:{height:P.skeletonLabelH,background:_.bgSkeleton,borderRadius:6}}),(0,r.jsx)(`div`,{style:{height:P.skeletonInputH,background:_.bgSkeleton,border:`1px solid ${_.bgSkeleton}`,borderRadius:24}})]});let U=m===!0?n.Circle:m||null,W=b?.length?b:y?[y]:[],G=C?u:l,K={fontFamily:w,fontWeight:500};return(0,r.jsxs)(`div`,{style:{width:320,display:`flex`,flexDirection:`column`,gap:P.helperGap},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:P.labelGap,width:`100%`},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,width:`100%`},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,flex:`1 0 0`,alignItems:`center`,gap:P.labelIconSize===12?4:6,minWidth:0},children:[(0,r.jsx)(`span`,{style:{...K,fontSize:P.labelFontSize,lineHeight:`${P.labelLineHeight}px`,color:L,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e}),(0,r.jsx)(n.Info,{size:P.labelIconSize,color:V,strokeWidth:1.8,style:{flexShrink:0}})]}),a&&(0,r.jsx)(`span`,{style:{...K,fontSize:P.labelFontSize,lineHeight:`${P.labelLineHeight}px`,color:L,whiteSpace:`nowrap`,flexShrink:0},children:a}),i&&(0,r.jsx)(`span`,{style:{color:v.error,fontWeight:800,flexShrink:0},children:`*`})]}),(0,r.jsxs)(`div`,{style:{background:I,border:`1px solid ${F}`,height:P.inputHeight,width:`100%`,borderRadius:24,display:`flex`,alignItems:p?`stretch`:`center`,...p?{}:{gap:8,padding:`0 ${P.paddingX}px`},overflow:`hidden`,boxShadow:A||N?E:`none`,opacity:j?.7:1,boxSizing:`border-box`},children:[p?(0,r.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,background:_.bgWhite,padding:`${P.leadingPy}px ${P.leadingPr}px ${P.leadingPy}px ${P.leadingPl}px`,flexShrink:0},children:[(0,r.jsx)(`span`,{style:{...K,fontSize:P.inputFontSize,lineHeight:`${P.inputLineHeight}px`,color:_.fgHigh,whiteSpace:`nowrap`},children:p}),(0,r.jsx)(`svg`,{width:P.chevronSize,height:P.chevronSize,viewBox:`0 0 16 16`,fill:`none`,children:(0,r.jsx)(`path`,{d:`M4 6L8 10L12 6`,stroke:_.fgHigh,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}):U?(0,r.jsx)(U,{size:P.iconSize,color:B,strokeWidth:1.6,style:{flexShrink:0}}):null,(0,r.jsxs)(`div`,{style:{flex:`1 0 0`,display:`flex`,alignItems:`center`,gap:8,height:`100%`,minWidth:0,...p?{borderLeft:`1px solid ${_.borderLight}`,padding:`0 12px`}:{}},children:[(0,r.jsx)(`div`,{style:{flex:`1 0 0`,overflow:`hidden`,display:`flex`,alignItems:`center`},children:(0,r.jsx)(`span`,{style:{...K,fontSize:P.inputFontSize,lineHeight:`${P.inputLineHeight}px`,color:s?z:R,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`,display:`block`,width:`100%`},children:s||o})}),h&&(0,r.jsxs)(`div`,{style:{background:_.bgLightgray,display:`flex`,gap:2,alignItems:`center`,justifyContent:`center`,padding:P.counterPadding,borderRadius:P.counterRadius,flexShrink:0,opacity:j?.7:1},children:[(0,r.jsx)(`span`,{style:{...K,fontSize:P.counterFontSize,lineHeight:`${P.counterLineHeight}px`,color:_.fgHigh},children:h.value}),(0,r.jsxs)(`span`,{style:{...K,fontSize:P.counterFontSize,lineHeight:`${P.counterLineHeight}px`,color:_.fgMid},children:[`/ `,h.max]})]}),g&&(0,r.jsx)(`span`,{style:{...K,fontSize:P.inputFontSize,lineHeight:`${P.inputLineHeight}px`,color:_.fgHigh,whiteSpace:`nowrap`,flexShrink:0,maxWidth:64,overflow:`hidden`},children:g}),W.length>0&&(0,r.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:W.map((e,n)=>{let i=O[e];return(0,r.jsxs)(t.default.Fragment,{children:[S&&n>0&&(0,r.jsx)(`div`,{style:{width:1,height:P.iconSize,background:_.gray300,flexShrink:0,alignSelf:`center`}}),(0,r.jsx)(i,{size:P.iconSize,color:B,strokeWidth:1.6,style:{flexShrink:0}})]},`${e}-${n}`)})})]})]})]}),G&&(0,r.jsx)(`p`,{style:{...K,margin:0,fontSize:P.helperFontSize,lineHeight:`${P.helperLineHeight}px`,color:H,width:`100%`},children:G})]})},A=g;e.Badge=h,e.InputField=k,e.ciPrimary=y,e.font=w,e.grayNeutral=_,e.interactive=x,e.oePrimary=b,e.padding=S,e.radius=C,e.status=v,e.tokens=A});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`react`),require(`lucide-react`),require(`react/jsx-runtime`)):typeof define==`function`&&define.amd?define([`exports`,`react`,`lucide-react`,`react/jsx-runtime`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.SenestiaUI={},e.React,e.LucideReact,e.react_jsx_runtime))})(this,function(e,t,n,r){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t)=>{let n={};for(var r in e)a(n,r,{get:e[r],enumerable:!0});return t||a(n,Symbol.toStringTag,{value:`Module`}),n},d=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e};t=((e,t,n)=>(n=e==null?{}:i(c(e)),d(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e)))(t);var f=`Sarabun, sans-serif`,p={Gray:{bg:`#f9fafb`,border:`#eaecf0`,text:`#06080b`,dot:`#667085`},Primary:{bg:`#f4f6f9`,border:`#e6ebf2`,text:`#1e2b3b`,dot:`#6c8fbe`},Error:{bg:`#fef0ef`,border:`#fbd2d0`,text:`#cc1a11`,dot:`#f04438`},Warning:{bg:`#fff9ee`,border:`#ffedcc`,text:`#db8f02`,dot:`#f79009`},Success:{bg:`#f0fdfa`,border:`#d2f9f1`,text:`#15a686`,dot:`#12b76a`},"Blue light":{bg:`#f0f9ff`,border:`#b9e6fe`,text:`#026aa2`,dot:`#0ba5ec`},Blue:{bg:`#eff8ff`,border:`#b2ddff`,text:`#175cd3`,dot:`#2e90fa`},Indigo:{bg:`#eef4ff`,border:`#c7d7fe`,text:`#3538cd`,dot:`#6172f3`},Purple:{bg:`#f4f3ff`,border:`#d9d6fe`,text:`#5925dc`,dot:`#7a5af8`},Pink:{bg:`#fef6fb`,border:`#fce7f6`,text:`#c11574`,dot:`#ee46bc`},Orange:{bg:`#fef6ee`,border:`#ffd6ae`,text:`#b93815`,dot:`#ef6820`},"Gray blue":{bg:`#f8f9fc`,border:`#d5d9eb`,text:`#363f72`,dot:`#717bbc`}},m={sm:{paddingX:8,paddingY:2,paddingXClose:{left:8,right:4},paddingXDot:{left:6,right:8},paddingPill:5,fontSize:12,lineHeight:18,dotSize:6,iconSize:12,closeSize:12},md:{paddingX:8,paddingY:2,paddingXClose:{left:8,right:4},paddingXDot:{left:6,right:8},paddingPill:6,fontSize:14,lineHeight:20,dotSize:6,iconSize:14,closeSize:14},lg:{paddingX:12,paddingY:4,paddingXClose:{left:12,right:6},paddingXDot:{left:8,right:12},paddingPill:8,fontSize:14,lineHeight:20,dotSize:8,iconSize:16,closeSize:16}},h=({label:e=`Label`,color:t=`Gray`,size:i=`sm`,type:a=`Idle`,icon:o,onClose:s})=>{let c=p[t],l=m[i],u={display:`inline-flex`,alignItems:`center`,backgroundColor:c.bg,border:`1px solid ${c.border}`,borderRadius:16,boxSizing:`border-box`,width:`fit-content`,fontFamily:f},d={fontSize:l.fontSize,lineHeight:`${l.lineHeight}px`,fontWeight:500,color:c.text,whiteSpace:`nowrap`,fontFamily:f,margin:0};if(a===`Idle`)return(0,r.jsx)(`span`,{style:{...u,padding:`${l.paddingY}px ${l.paddingX}px`},children:(0,r.jsx)(`span`,{style:d,children:e})});if(a===`Status Dot`)return(0,r.jsxs)(`span`,{style:{...u,gap:4,paddingTop:l.paddingY,paddingBottom:l.paddingY,paddingLeft:l.paddingXDot.left,paddingRight:l.paddingXDot.right},children:[(0,r.jsx)(`span`,{style:{display:`inline-block`,width:l.dotSize,height:l.dotSize,borderRadius:`50%`,backgroundColor:c.dot,flexShrink:0}}),(0,r.jsx)(`span`,{style:d,children:e})]});if(a===`Closable`)return(0,r.jsxs)(`span`,{style:{...u,gap:2,paddingTop:l.paddingY,paddingBottom:l.paddingY,paddingLeft:l.paddingXClose.left,paddingRight:l.paddingXClose.right},children:[(0,r.jsx)(`span`,{style:d,children:e}),(0,r.jsx)(`button`,{onClick:s,style:{display:`inline-flex`,alignItems:`center`,justifyContent:`center`,background:`none`,border:`none`,padding:2,borderRadius:3,cursor:`pointer`,color:c.text,flexShrink:0,lineHeight:1},"aria-label":`Remove`,children:(0,r.jsx)(n.X,{size:l.closeSize,strokeWidth:2.5})})]});if(a===`Pill color`){let e=o;return(0,r.jsx)(`span`,{style:{...u,padding:l.paddingPill},children:e?(0,r.jsx)(e,{size:l.iconSize,color:c.dot,strokeWidth:2}):(0,r.jsx)(`span`,{style:{display:`inline-block`,width:l.iconSize,height:l.iconSize,borderRadius:`50%`,backgroundColor:c.dot}})})}return null},g=u({ciPrimary:()=>y,font:()=>w,grayNeutral:()=>_,interactive:()=>x,oePrimary:()=>b,padding:()=>S,radius:()=>C,status:()=>v}),_={fgHigh:`#1B1D22`,fgMid:`#6A6E83`,fgLow:`#9A9DAD`,bgWhite:`#FFFFFF`,bgLightgray:`#F8F8F9`,bgDisabled:`#F3F4F6`,borderMidgray:`#CFD1D9`,borderLight:`#EBECEF`,borderDisabled:`#E5EAF1`,gray300:`#D0D5DD`,bgSkeleton:`#EEF0F3`,bgDisabledStrong:`#EBECEF`},v={error:`#DB1439`,warning:`#DB8F02`,success:`#15A686`},y={fgLow:`#C4B3F6`,fgHigh:`#802CEB`,bgLow:`#D4C9F6`,bgMid:`#802CEB`,bgHigh:`#5A1DA9`,borderMid:`#996CF3`,borderHigh:`#802CEB`},b={fgLow:`#5273A1`,fgHigh:`#3A5274`,bgLowest:`#EFF2F6`,bgLow:`#6E90BF`,bgMid:`#5273A1`,bgHigh:`#3A5274`,borderLowest:`#C6D2E3`,borderLow:`#9CB3D2`,borderMid:`#5273A1`,p300:`#809BBF`,linkBlue:`#3C5BD5`},x={activeBorder:b.fgLow,hoverBorder:`#3B82F6`,focusRing:`#D7DFEA`,invalidBorder:v.error},S={"PD-0":0,"PD-1":1,"PD-2":2,"PD-3":4,"PD-4":6,"PD-5":8,"PD-6":12,"PD-7":16,"PD-8":24,"PD-9":32,"PD-10":40,"PD-11":48,"PD-12":56,"PD-13":64,"PD-14":72,"PD-15":80},C={"CR-0":0,"CR-1":2,"CR-2":4,"CR-3":8,"CR-4":12,"CR-5":16,"CR-6":20,"CR-7":24,"CR-8":32,"CR-9":48,"CR-10":100},w=`Sarabun, sans-serif`,T={sm:{inputHeight:32,labelFontSize:12,labelLineHeight:18,inputFontSize:14,inputLineHeight:20,helperFontSize:12,helperLineHeight:18,paddingX:12,iconSize:16,labelIconSize:12,labelGap:4,helperGap:4,leadingPl:8,leadingPr:4,leadingPy:6,chevronSize:14,counterPadding:`1px 4px`,counterRadius:4,counterFontSize:12,counterLineHeight:18,skeletonLabelH:18,skeletonInputH:32},md:{inputHeight:40,labelFontSize:14,labelLineHeight:20,inputFontSize:16,inputLineHeight:24,helperFontSize:14,helperLineHeight:20,paddingX:16,iconSize:20,labelIconSize:14,labelGap:6,helperGap:4,leadingPl:12,leadingPr:8,leadingPy:8,chevronSize:16,counterPadding:`2px 8px`,counterRadius:8,counterFontSize:14,counterLineHeight:20,skeletonLabelH:20,skeletonInputH:40},lg:{inputHeight:48,labelFontSize:16,labelLineHeight:24,inputFontSize:16,inputLineHeight:24,helperFontSize:14,helperLineHeight:20,paddingX:16,iconSize:20,labelIconSize:16,labelGap:8,helperGap:6,leadingPl:16,leadingPr:8,leadingPy:12,chevronSize:16,counterPadding:`2px 8px`,counterRadius:8,counterFontSize:14,counterLineHeight:20,skeletonLabelH:24,skeletonInputH:48}},E=`0 0 0 2px ${x.focusRing}`,D=e=>{let t=e??`Idle`;return{s:t,isInvalid:t.includes(`invalid`),isHover:t.includes(`hover`),isActive:t===`Active`||t===`Keyboard focus`||t.endsWith(`active`),isDisabled:t===`Disable`,isSkeleton:t===`Skeleton`,isFilled:t.includes(`Filled`),isKeyboardFocus:t===`Keyboard focus`}},O={clear:n.XCircle,search:n.Search,password:n.Eye},k=({label:e,required:i=!1,labelRemark:a,placeholder:o=`Placeholder`,value:s,onChange:c,helperText:l,errorText:u,state:d=`Idle`,size:f=`md`,leadingDropdownText:p,leadingIcon:m,counter:h,unit:g,trailingIcon:y,trailingIcons:b,trailingIconSeparator:S=!1})=>{let{isInvalid:C,isHover:k,isActive:A,isDisabled:j,isSkeleton:M,isKeyboardFocus:N}=D(d),P=T[f],F=C?x.invalidBorder:A||N?x.activeBorder:k?x.hoverBorder:_.borderMidgray,I=j?_.bgDisabled:k?_.bgLightgray:_.bgWhite,L=j?_.fgLow:_.fgMid,R=j?_.fgLow:_.fgHigh,z=j?_.fgLow:_.fgHigh,B=j?_.fgLow:_.fgMid,V=C?v.error:_.fgMid;if(M)return(0,r.jsxs)(`div`,{style:{width:320,display:`flex`,flexDirection:`column`,gap:P.labelGap},children:[(0,r.jsx)(`div`,{style:{height:P.skeletonLabelH,background:_.bgSkeleton,borderRadius:6}}),(0,r.jsx)(`div`,{style:{height:P.skeletonInputH,background:_.bgSkeleton,border:`1px solid ${_.bgSkeleton}`,borderRadius:24}})]});let H=m===!0?n.Circle:m||null,U=b?.length?b:y?[y]:[],W=C?u:l,G={fontFamily:w,fontWeight:500};return(0,r.jsxs)(`div`,{style:{width:320,display:`flex`,flexDirection:`column`,gap:P.helperGap},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:P.labelGap,width:`100%`},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,width:`100%`},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,flex:`1 0 0`,alignItems:`center`,gap:P.labelIconSize===12?4:6,minWidth:0},children:[(0,r.jsx)(`span`,{style:{...G,fontSize:P.labelFontSize,lineHeight:`${P.labelLineHeight}px`,color:L,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e}),(0,r.jsx)(n.Info,{size:P.labelIconSize,color:B,strokeWidth:1.8,style:{flexShrink:0}})]}),a&&(0,r.jsx)(`span`,{style:{...G,fontSize:P.labelFontSize,lineHeight:`${P.labelLineHeight}px`,color:L,whiteSpace:`nowrap`,flexShrink:0},children:a}),i&&(0,r.jsx)(`span`,{style:{color:v.error,fontWeight:800,flexShrink:0},children:`*`})]}),(0,r.jsxs)(`div`,{style:{background:I,border:`1px solid ${F}`,height:P.inputHeight,width:`100%`,borderRadius:24,display:`flex`,alignItems:p?`stretch`:`center`,...p?{}:{gap:8,padding:`0 ${P.paddingX}px`},overflow:`hidden`,boxShadow:A||N?E:`none`,opacity:j?.7:1,boxSizing:`border-box`},children:[p?(0,r.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,background:_.bgWhite,padding:`${P.leadingPy}px ${P.leadingPr}px ${P.leadingPy}px ${P.leadingPl}px`,flexShrink:0},children:[(0,r.jsx)(`span`,{style:{...G,fontSize:P.inputFontSize,lineHeight:`${P.inputLineHeight}px`,color:_.fgHigh,whiteSpace:`nowrap`},children:p}),(0,r.jsx)(`svg`,{width:P.chevronSize,height:P.chevronSize,viewBox:`0 0 16 16`,fill:`none`,children:(0,r.jsx)(`path`,{d:`M4 6L8 10L12 6`,stroke:_.fgHigh,strokeWidth:`1.5`,strokeLinecap:`round`,strokeLinejoin:`round`})})]}):H?(0,r.jsx)(H,{size:P.iconSize,color:z,strokeWidth:1.6,style:{flexShrink:0}}):null,(0,r.jsxs)(`div`,{style:{flex:`1 0 0`,display:`flex`,alignItems:`center`,gap:8,height:`100%`,minWidth:0,...p?{borderLeft:`1px solid ${_.borderLight}`,padding:`0 12px`}:{}},children:[(0,r.jsx)(`input`,{type:`text`,value:s??``,onChange:e=>c?.(e.target.value),placeholder:o,disabled:j,style:{...G,flex:`1 0 0`,border:`none`,outline:`none`,background:`transparent`,fontSize:P.inputFontSize,lineHeight:`${P.inputLineHeight}px`,color:R,width:`100%`,minWidth:0,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`,cursor:j?`not-allowed`:`text`}}),h&&(0,r.jsxs)(`div`,{style:{background:_.bgLightgray,display:`flex`,gap:2,alignItems:`center`,justifyContent:`center`,padding:P.counterPadding,borderRadius:P.counterRadius,flexShrink:0,opacity:j?.7:1},children:[(0,r.jsx)(`span`,{style:{...G,fontSize:P.counterFontSize,lineHeight:`${P.counterLineHeight}px`,color:_.fgHigh},children:h.value}),(0,r.jsxs)(`span`,{style:{...G,fontSize:P.counterFontSize,lineHeight:`${P.counterLineHeight}px`,color:_.fgMid},children:[`/ `,h.max]})]}),g&&(0,r.jsx)(`span`,{style:{...G,fontSize:P.inputFontSize,lineHeight:`${P.inputLineHeight}px`,color:_.fgHigh,whiteSpace:`nowrap`,flexShrink:0,maxWidth:64,overflow:`hidden`},children:g}),U.length>0&&(0,r.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:U.map((e,n)=>{let i=O[e];return(0,r.jsxs)(t.default.Fragment,{children:[S&&n>0&&(0,r.jsx)(`div`,{style:{width:1,height:P.iconSize,background:_.gray300,flexShrink:0,alignSelf:`center`}}),(0,r.jsx)(i,{size:P.iconSize,color:z,strokeWidth:1.6,style:{flexShrink:0}})]},`${e}-${n}`)})})]})]})]}),W&&(0,r.jsx)(`p`,{style:{...G,margin:0,fontSize:P.helperFontSize,lineHeight:`${P.helperLineHeight}px`,color:V,width:`100%`},children:W})]})},A=g;e.Badge=h,e.InputField=k,e.ciPrimary=y,e.font=w,e.grayNeutral=_,e.interactive=x,e.oePrimary=b,e.padding=S,e.radius=C,e.status=v,e.tokens=A});
2
2
  //# sourceMappingURL=senestia-ui.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"senestia-ui.umd.js","names":[],"sources":["../src/stories/Badge.tsx","../src/stories/tokens.ts","../src/stories/InputField.tsx","../src/index.ts"],"sourcesContent":["import React from 'react';\nimport { X } from 'lucide-react';\n\n// ─── Design System Font ──────────────────────────────────────────────────────\nconst font = 'Sarabun, sans-serif';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type BadgeColor =\n | 'Gray'\n | 'Primary'\n | 'Error'\n | 'Warning'\n | 'Success'\n | 'Blue light'\n | 'Blue'\n | 'Indigo'\n | 'Purple'\n | 'Pink'\n | 'Orange'\n | 'Gray blue';\n\nexport type BadgeSize = 'sm' | 'md' | 'lg';\n\nexport type BadgeType = 'Idle' | 'Status Dot' | 'Closable' | 'Pill color';\n\nexport interface BadgeProps {\n /** Badge label text */\n label?: string;\n /** Color variant */\n color?: BadgeColor;\n /** Size variant */\n size?: BadgeSize;\n /** Type / style variant */\n type?: BadgeType;\n /** Icon to render inside Pill color type (Lucide icon component) */\n icon?: React.ElementType;\n /** Called when close button is clicked (Closable type) */\n onClose?: () => void;\n}\n\n// ─── Color Tokens ────────────────────────────────────────────────────────────\n\nconst COLOR_TOKENS: Record<\n BadgeColor,\n { bg: string; border: string; text: string; dot: string }\n> = {\n Gray: { bg: '#f9fafb', border: '#eaecf0', text: '#06080b', dot: '#667085' },\n Primary: { bg: '#f4f6f9', border: '#e6ebf2', text: '#1e2b3b', dot: '#6c8fbe' },\n Error: { bg: '#fef0ef', border: '#fbd2d0', text: '#cc1a11', dot: '#f04438' },\n Warning: { bg: '#fff9ee', border: '#ffedcc', text: '#db8f02', dot: '#f79009' },\n Success: { bg: '#f0fdfa', border: '#d2f9f1', text: '#15a686', dot: '#12b76a' },\n 'Blue light': { bg: '#f0f9ff', border: '#b9e6fe', text: '#026aa2', dot: '#0ba5ec' },\n Blue: { bg: '#eff8ff', border: '#b2ddff', text: '#175cd3', dot: '#2e90fa' },\n Indigo: { bg: '#eef4ff', border: '#c7d7fe', text: '#3538cd', dot: '#6172f3' },\n Purple: { bg: '#f4f3ff', border: '#d9d6fe', text: '#5925dc', dot: '#7a5af8' },\n Pink: { bg: '#fef6fb', border: '#fce7f6', text: '#c11574', dot: '#ee46bc' },\n Orange: { bg: '#fef6ee', border: '#ffd6ae', text: '#b93815', dot: '#ef6820' },\n 'Gray blue':{ bg: '#f8f9fc', border: '#d5d9eb', text: '#363f72', dot: '#717bbc' },\n};\n\n// ─── Size Tokens ─────────────────────────────────────────────────────────────\n\nconst SIZE_TOKENS: Record<\n BadgeSize,\n {\n paddingX: number;\n paddingY: number;\n paddingXClose: { left: number; right: number };\n paddingXDot: { left: number; right: number };\n paddingPill: number;\n fontSize: number;\n lineHeight: number;\n dotSize: number;\n iconSize: number;\n closeSize: number;\n }\n> = {\n sm: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 5,\n fontSize: 12, lineHeight: 18,\n dotSize: 6, iconSize: 12, closeSize: 12,\n },\n md: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 6,\n fontSize: 14, lineHeight: 20,\n dotSize: 6, iconSize: 14, closeSize: 14,\n },\n lg: {\n paddingX: 12, paddingY: 4,\n paddingXClose: { left: 12, right: 6 },\n paddingXDot: { left: 8, right: 12 },\n paddingPill: 8,\n fontSize: 14, lineHeight: 20,\n dotSize: 8, iconSize: 16, closeSize: 16,\n },\n};\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const Badge: React.FC<BadgeProps> = ({\n label = 'Label',\n color = 'Gray',\n size = 'sm',\n type = 'Idle',\n icon: IconComponent,\n onClose,\n}) => {\n const c = COLOR_TOKENS[color];\n const s = SIZE_TOKENS[size];\n\n // ── Shared wrapper style ──────────────────────────────────────────────────\n const baseWrapper: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: c.bg,\n border: `1px solid ${c.border}`,\n borderRadius: 16,\n boxSizing: 'border-box',\n width: 'fit-content',\n fontFamily: font,\n };\n\n // ── Text style ────────────────────────────────────────────────────────────\n const textStyle: React.CSSProperties = {\n fontSize: s.fontSize,\n lineHeight: `${s.lineHeight}px`,\n fontWeight: 500,\n color: c.text,\n whiteSpace: 'nowrap',\n fontFamily: font,\n margin: 0,\n };\n\n // ── Idle ─────────────────────────────────────────────────────────────────\n if (type === 'Idle') {\n return (\n <span\n style={{\n ...baseWrapper,\n padding: `${s.paddingY}px ${s.paddingX}px`,\n }}\n >\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Status Dot ────────────────────────────────────────────────────────────\n if (type === 'Status Dot') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 4,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXDot.left,\n paddingRight: s.paddingXDot.right,\n }}\n >\n {/* Dot */}\n <span\n style={{\n display: 'inline-block',\n width: s.dotSize,\n height: s.dotSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n flexShrink: 0,\n }}\n />\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Closable ──────────────────────────────────────────────────────────────\n if (type === 'Closable') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 2,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXClose.left,\n paddingRight: s.paddingXClose.right,\n }}\n >\n <span style={textStyle}>{label}</span>\n <button\n onClick={onClose}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n padding: 2,\n borderRadius: 3,\n cursor: 'pointer',\n color: c.text,\n flexShrink: 0,\n lineHeight: 1,\n }}\n aria-label=\"Remove\"\n >\n <X size={s.closeSize} strokeWidth={2.5} />\n </button>\n </span>\n );\n }\n\n // ── Pill color (icon only) ────────────────────────────────────────────────\n if (type === 'Pill color') {\n const PillIcon = IconComponent;\n return (\n <span\n style={{\n ...baseWrapper,\n padding: s.paddingPill,\n }}\n >\n {PillIcon ? (\n <PillIcon size={s.iconSize} color={c.dot} strokeWidth={2} />\n ) : (\n // Default: colored circle dot\n <span\n style={{\n display: 'inline-block',\n width: s.iconSize,\n height: s.iconSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n }}\n />\n )}\n </span>\n );\n }\n\n return null;\n};\n","/**\n * Senestia Design System — Semantic Color Tokens\n *\n * ┌─────────────────────────────────────────────────────────────┐\n * │ Source: Figma DS-01 · Foundation → Semantic Color │\n * │ Use these tokens in components instead of raw hex values. │\n * └─────────────────────────────────────────────────────────────┘\n */\n\n// ─── Gray-Neutral ─────────────────────────────────────────────────────────────\n\nexport const grayNeutral = {\n /** Semantic/Gray-Neutral/fg/high — primary text, dark icons */\n fgHigh: '#1B1D22',\n /** Semantic/Gray-Neutral/fg/mid-on-white — label text, helper text, secondary icons */\n fgMid: '#6A6E83',\n /** Semantic/Gray-Neutral/fg/low-on-white — placeholder, disabled text */\n fgLow: '#9A9DAD',\n\n /** Semantic/Gray-Neutral/bg/white */\n bgWhite: '#FFFFFF',\n /** Semantic/Gray-Neutral/bg/lightgray — counter pill, subtle backgrounds */\n bgLightgray: '#F8F8F9',\n /** Semantic/Gray-Neutral/bg/disabled */\n bgDisabled: '#F3F4F6',\n\n /** Semantic/Gray-Neutral/border/midgray — default input border */\n borderMidgray: '#CFD1D9',\n /** Semantic/Gray-Neutral/border/light — dividers, card borders */\n borderLight: '#EBECEF',\n /** Disabled border (checkbox, input) */\n borderDisabled: '#E5EAF1',\n\n /** Gray/300 — icon separators */\n gray300: '#D0D5DD',\n /** Skeleton loading shimmer */\n bgSkeleton: '#EEF0F3',\n /** Strong disabled background (checkbox) */\n bgDisabledStrong: '#EBECEF',\n} as const;\n\n// ─── Status ───────────────────────────────────────────────────────────────────\n\nexport const status = {\n /** Error / invalid state */\n error: '#DB1439',\n /** Warning */\n warning: '#DB8F02',\n /** Success */\n success: '#15A686',\n} as const;\n\n// ─── CI Primary (Senestia brand purple) ───────────────────────────────────────\n\nexport const ciPrimary = {\n fgLow: '#C4B3F6',\n fgHigh: '#802CEB',\n bgLow: '#D4C9F6',\n bgMid: '#802CEB',\n bgHigh: '#5A1DA9',\n borderMid: '#996CF3',\n borderHigh: '#802CEB',\n} as const;\n\n// ─── OE Theme (OE brand blue) ─────────────────────────────────────────────────\n\nexport const oePrimary = {\n fgLow: '#5273A1',\n fgHigh: '#3A5274',\n bgLowest: '#EFF2F6', // selected item background in pickers\n bgLow: '#6E90BF',\n bgMid: '#5273A1',\n bgHigh: '#3A5274',\n borderLowest:'#C6D2E3', // focused item border\n borderLow: '#9CB3D2',\n borderMid: '#5273A1',\n /** Primary/300 — supporting/helper text on blue-tinted UI */\n p300: '#809BBF',\n /** Indigo/300 — \"Set to now\" link color */\n linkBlue: '#3C5BD5',\n} as const;\n\n// ─── Interactive states ───────────────────────────────────────────────────────\n\nexport const interactive = {\n /** Active / focused border */\n activeBorder: oePrimary.fgLow, // #5273A1\n /** Hover border */\n hoverBorder: '#3B82F6',\n /** Focus ring shadow */\n focusRing: '#D7DFEA',\n /** Invalid border */\n invalidBorder: status.error,\n} as const;\n\n// ─── Padding tokens (PD) ─────────────────────────────────────────────────────\n\nexport const padding = {\n 'PD-0': 0,\n 'PD-1': 1,\n 'PD-2': 2,\n 'PD-3': 4,\n 'PD-4': 6,\n 'PD-5': 8,\n 'PD-6': 12,\n 'PD-7': 16,\n 'PD-8': 24,\n 'PD-9': 32,\n 'PD-10': 40,\n 'PD-11': 48,\n 'PD-12': 56,\n 'PD-13': 64,\n 'PD-14': 72,\n 'PD-15': 80,\n} as const;\n\n// ─── Corner Radius tokens (CR) ───────────────────────────────────────────────\n\nexport const radius = {\n 'CR-0': 0,\n 'CR-1': 2,\n 'CR-2': 4,\n 'CR-3': 8,\n 'CR-4': 12,\n 'CR-5': 16,\n 'CR-6': 20,\n 'CR-7': 24,\n 'CR-8': 32,\n 'CR-9': 48,\n 'CR-10': 100,\n} as const;\n\n// ─── Typography ───────────────────────────────────────────────────────────────\n\nexport const font = 'Sarabun, sans-serif';\n","import React from 'react';\nimport { Circle, Info, XCircle, Search, Eye } from 'lucide-react';\nimport { grayNeutral, status, interactive, font } from './tokens';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type InputFieldState =\n | 'Idle'\n | 'Idle hover'\n | 'Active'\n | 'Idle invalid'\n | 'Idle invalid hover'\n | 'Idle invalid active'\n | 'Filled'\n | 'Filled hover'\n | 'Filled active'\n | 'Filled invalid'\n | 'Filled invalid hover'\n | 'Filled invalid active'\n | 'Disable'\n | 'Keyboard focus'\n | 'Skeleton';\n\nexport type InputFieldSize = 'sm' | 'md' | 'lg';\n\nexport type InputFieldTrailingIcon = 'clear' | 'password' | 'search';\n\nexport type InputFieldCounter = {\n value: number;\n max: number;\n};\n\nexport interface InputFieldProps {\n /** Label text displayed above the input */\n label: string;\n /** Show required asterisk (*) */\n required?: boolean;\n /** Remark text next to label e.g. \"(optional)\" */\n labelRemark?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Current value */\n value?: string;\n /** Called when value changes */\n onChange?: (value: string) => void;\n /** Helper text below the input (hidden when invalid) */\n helperText?: string;\n /** Error message below the input (shown when invalid state) */\n errorText?: string;\n /** Visual state from Figma */\n state?: InputFieldState;\n /** Input size — affects height, font, and padding */\n size?: InputFieldSize;\n /** Leading dropdown prefix text */\n leadingDropdownText?: string;\n /**\n * Leading icon inside the input (left side).\n * - `true` → default Circle icon\n * - `React.ElementType` → custom Lucide icon\n * - `false/undefined` → no icon\n */\n leadingIcon?: React.ElementType | boolean;\n /** Counter pill e.g. `{ value: 0, max: 20 }` */\n counter?: InputFieldCounter;\n /** Unit text inside the input */\n unit?: string;\n /** Single trailing icon */\n trailingIcon?: InputFieldTrailingIcon;\n /** Multiple trailing icons (overrides trailingIcon) */\n trailingIcons?: InputFieldTrailingIcon[];\n /** Show separator between trailing icons */\n trailingIconSeparator?: boolean;\n}\n\n// ─── Design tokens (from Figma) ──────────────────────────────────────────────\n\n/**\n * Size tokens — matched to Figma nodes:\n * sm (Sm-32): label C5 12/18 · input C4 14/20 · helper C5 12/18\n * md (Md-40): label C4 14/20 · input C3 16/24 · helper C4 14/20\n * lg (Lg-48): label C3 16/24 · input C3 16/24 · helper C4 14/20\n *\n * Spacing (per Figma sm node — gap-4 between all elements):\n * labelGap = gap between label row and input box\n * helperGap = gap between input box and helper/error text\n */\nconst sizeTokens = {\n sm: {\n inputHeight: 32,\n labelFontSize: 12, labelLineHeight: 18,\n inputFontSize: 14, inputLineHeight: 20,\n helperFontSize: 12, helperLineHeight: 18,\n paddingX: 12,\n iconSize: 16,\n labelIconSize: 12,\n labelGap: 4, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 8, leadingPr: 4, leadingPy: 6,\n chevronSize: 14,\n counterPadding: '1px 4px',\n counterRadius: 4,\n counterFontSize: 12, counterLineHeight: 18,\n skeletonLabelH: 18, skeletonInputH: 32,\n },\n md: {\n inputHeight: 40,\n labelFontSize: 14, labelLineHeight: 20,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 14,\n labelGap: 6, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 12, leadingPr: 8, leadingPy: 8,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 20, skeletonInputH: 40,\n },\n lg: {\n inputHeight: 48,\n labelFontSize: 16, labelLineHeight: 24,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 16,\n labelGap: 8, // label row → input\n helperGap: 6, // input → helper text\n leadingPl: 16, leadingPr: 8, leadingPy: 12,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 24, skeletonInputH: 48,\n },\n} as const;\n\n// ─── State helpers ────────────────────────────────────────────────────────────\n\nconst focusRingStyle = `0 0 0 2px ${interactive.focusRing}`;\n\nconst getStateFlags = (state: InputFieldState | undefined) => {\n const s = state ?? 'Idle';\n const isInvalid = s.includes('invalid');\n const isHover = s.includes('hover');\n const isActive = s === 'Active' || s === 'Keyboard focus' || s.endsWith('active');\n const isDisabled = s === 'Disable';\n const isSkeleton = s === 'Skeleton';\n const isFilled = s.includes('Filled');\n const isKeyboardFocus = s === 'Keyboard focus';\n return { s, isInvalid, isHover, isActive, isDisabled, isSkeleton, isFilled, isKeyboardFocus };\n};\n\n// ─── Trailing icon map → Lucide ───────────────────────────────────────────────\n\nconst TRAILING_ICON_MAP = {\n clear: XCircle,\n search: Search,\n password: Eye,\n} as const;\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const InputField = ({\n label,\n required = false,\n labelRemark,\n placeholder = 'Placeholder',\n value,\n onChange: _onChange,\n helperText,\n errorText,\n state = 'Idle',\n size = 'md',\n leadingDropdownText,\n leadingIcon,\n counter,\n unit,\n trailingIcon,\n trailingIcons,\n trailingIconSeparator = false,\n}: InputFieldProps) => {\n const { isInvalid, isHover, isActive, isDisabled, isSkeleton, isKeyboardFocus } =\n getStateFlags(state);\n\n const t = sizeTokens[size];\n\n // ── Colors — mapped to Semantic/Gray-Neutral tokens ─────────────────────\n const borderColor = isInvalid\n ? interactive.invalidBorder // status.error #DB1439\n : isActive || isKeyboardFocus\n ? interactive.activeBorder // oePrimary.fgLow #5273A1\n : isHover\n ? interactive.hoverBorder // #3B82F6\n : grayNeutral.borderMidgray; // #CFD1D9\n\n const background = isDisabled\n ? grayNeutral.bgDisabled // #F3F4F6\n : isHover\n ? grayNeutral.bgLightgray // #F8F8F9\n : grayNeutral.bgWhite; // #FFFFFF\n\n // Label text → fg/mid-on-white (disabled → fg/low)\n const labelColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n // Placeholder → fg/low-on-white (same whether disabled or not)\n const placeholderColor = grayNeutral.fgLow; // #9A9DAD\n\n // Typed value → fg/high (disabled → fg/low)\n const valueColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh; // #1B1D22\n\n // ── Icon colors (Figma: Semantic/Gray-Neutral/fg/high for input icons) ───\n // Input leading/trailing icons → fg/high (#1B1D22)\n const inputIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh;\n // Label info icon → fg/mid (same as label text, #6A6E83)\n const labelIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n const helperColor = isInvalid ? status.error : grayNeutral.fgMid; // #6A6E83\n\n // ── Skeleton ─────────────────────────────────────────────────────────────\n if (isSkeleton) {\n return (\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.labelGap }}>\n <div style={{ height: t.skeletonLabelH, background: grayNeutral.bgSkeleton, borderRadius: 6 }} />\n <div style={{ height: t.skeletonInputH, background: grayNeutral.bgSkeleton, border: `1px solid ${grayNeutral.bgSkeleton}`, borderRadius: 24 }} />\n </div>\n );\n }\n\n // ── Leading icon resolve ──────────────────────────────────────────────────\n // true → Circle (Figma default \"Icon/circle\"), component → custom, false → none\n const LeadingIconComponent: React.ElementType | null =\n leadingIcon === true\n ? Circle\n : leadingIcon\n ? (leadingIcon as React.ElementType)\n : null;\n\n // ── Trailing icons ────────────────────────────────────────────────────────\n const iconsToRender: InputFieldTrailingIcon[] =\n trailingIcons?.length ? trailingIcons : trailingIcon ? [trailingIcon] : [];\n\n // ── Text below input ──────────────────────────────────────────────────────\n const showText = isInvalid ? errorText : helperText;\n\n // ── Shared font style ─────────────────────────────────────────────────────\n const baseFont: React.CSSProperties = { fontFamily: font, fontWeight: 500 };\n\n return (\n /*\n * Outer wrapper — two-level gap structure matching Figma:\n * Level 1 (helperGap): separates [label + input block] from [helper text]\n * Level 2 (labelGap): separates [label row] from [input box]\n */\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.helperGap }}>\n\n {/* ── Level 1: label + input block ────────────────────────────────── */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: t.labelGap, width: '100%' }}>\n\n {/* Label row */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, width: '100%' }}>\n {/* Left: label text + info icon */}\n <div style={{ display: 'flex', flex: '1 0 0', alignItems: 'center', gap: t.labelIconSize === 12 ? 4 : 6, minWidth: 0 }}>\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {label}\n </span>\n {/* Info icon — fg/mid-on-white (same shade as label text) */}\n <Info\n size={t.labelIconSize}\n color={labelIconColor}\n strokeWidth={1.8}\n style={{ flexShrink: 0 }}\n />\n </div>\n\n {/* Right: remark or required marker */}\n {labelRemark && (\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n }}\n >\n {labelRemark}\n </span>\n )}\n {required && (\n <span style={{ color: status.error, fontWeight: 800, flexShrink: 0 }}>*</span>\n )}\n </div>\n\n {/* Input box */}\n <div\n style={{\n background,\n border: `1px solid ${borderColor}`,\n height: t.inputHeight,\n width: '100%',\n borderRadius: 24,\n display: 'flex',\n alignItems: leadingDropdownText ? 'stretch' : 'center',\n ...(leadingDropdownText ? {} : { gap: 8, padding: `0 ${t.paddingX}px` }),\n overflow: 'hidden',\n boxShadow: isActive || isKeyboardFocus ? focusRingStyle : 'none',\n opacity: isDisabled ? 0.7 : 1,\n boxSizing: 'border-box',\n }}\n >\n {/* Leading: dropdown prefix OR icon */}\n {leadingDropdownText ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n background: grayNeutral.bgWhite,\n padding: `${t.leadingPy}px ${t.leadingPr}px ${t.leadingPy}px ${t.leadingPl}px`,\n flexShrink: 0,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n }}\n >\n {leadingDropdownText}\n </span>\n <svg width={t.chevronSize} height={t.chevronSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M4 6L8 10L12 6\" stroke={grayNeutral.fgHigh} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n ) : LeadingIconComponent ? (\n /* Leading icon in input → fg/high (#1B1D22) per Figma */\n <LeadingIconComponent\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n ) : null}\n\n {/* Text + accessories area */}\n <div\n style={{\n flex: '1 0 0',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n height: '100%',\n minWidth: 0,\n ...(leadingDropdownText\n ? { borderLeft: `1px solid ${grayNeutral.borderLight}`, padding: `0 12px` }\n : {}),\n }}\n >\n {/* Placeholder / Value text */}\n <div\n style={{\n flex: '1 0 0',\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: value ? valueColor : placeholderColor,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n display: 'block',\n width: '100%',\n }}\n >\n {value || placeholder}\n </span>\n </div>\n\n {/* Counter pill */}\n {counter && (\n <div\n style={{\n background: grayNeutral.bgLightgray,\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n justifyContent: 'center',\n padding: t.counterPadding,\n borderRadius: t.counterRadius,\n flexShrink: 0,\n opacity: isDisabled ? 0.7 : 1,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgHigh,\n }}\n >\n {counter.value}\n </span>\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgMid,\n }}\n >\n / {counter.max}\n </span>\n </div>\n )}\n\n {/* Unit text */}\n {unit && (\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n maxWidth: 64,\n overflow: 'hidden',\n }}\n >\n {unit}\n </span>\n )}\n\n {/* Trailing icons */}\n {iconsToRender.length > 0 && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n {iconsToRender.map((ic, idx) => {\n const TrailingIcon = TRAILING_ICON_MAP[ic];\n return (\n <React.Fragment key={`${ic}-${idx}`}>\n {trailingIconSeparator && idx > 0 && (\n <div\n style={{\n width: 1,\n height: t.iconSize,\n background: grayNeutral.gray300,\n flexShrink: 0,\n alignSelf: 'center',\n }}\n />\n )}\n {/* Trailing icon → fg/high (#1B1D22) per Figma */}\n <TrailingIcon\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n </React.Fragment>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Level 1: helper / error text ────────────────────────────────── */}\n {/*\n * No extra margin here — the outer helperGap (4px sm / 4px md / 6px lg)\n * from the flex container already provides the correct spacing from Figma.\n */}\n {showText && (\n <p\n style={{\n ...baseFont,\n margin: 0,\n fontSize: t.helperFontSize,\n lineHeight: `${t.helperLineHeight}px`,\n color: helperColor,\n width: '100%',\n }}\n >\n {showText}\n </p>\n )}\n </div>\n );\n};\n","// ─── Senestia Design System — Public API ─────────────────────────────────────\n//\n// import { Badge, InputField, tokens } from '@senestia/ui'\n//\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ── Components ────────────────────────────────────────────────────────────────\nexport { Badge } from './stories/Badge';\nexport { InputField } from './stories/InputField';\n\n// ── Component types ───────────────────────────────────────────────────────────\nexport type { BadgeProps, BadgeColor, BadgeSize, BadgeType } from './stories/Badge';\nexport type {\n InputFieldProps,\n InputFieldState,\n InputFieldSize,\n InputFieldTrailingIcon,\n InputFieldCounter,\n} from './stories/InputField';\n\n// ── Design Tokens ─────────────────────────────────────────────────────────────\nexport {\n // Colors\n grayNeutral,\n status,\n ciPrimary,\n oePrimary,\n interactive,\n // Spacing\n padding,\n radius,\n // Typography\n font,\n} from './stories/tokens';\n\n// ── Tokens namespace (for tree-shaking friendly usage) ────────────────────────\nimport * as _tokens from './stories/tokens';\nexport const tokens = _tokens;\n"],"mappings":"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"}
1
+ {"version":3,"file":"senestia-ui.umd.js","names":[],"sources":["../src/stories/Badge.tsx","../src/stories/tokens.ts","../src/stories/InputField.tsx","../src/index.ts"],"sourcesContent":["import React from 'react';\nimport { X } from 'lucide-react';\n\n// ─── Design System Font ──────────────────────────────────────────────────────\nconst font = 'Sarabun, sans-serif';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type BadgeColor =\n | 'Gray'\n | 'Primary'\n | 'Error'\n | 'Warning'\n | 'Success'\n | 'Blue light'\n | 'Blue'\n | 'Indigo'\n | 'Purple'\n | 'Pink'\n | 'Orange'\n | 'Gray blue';\n\nexport type BadgeSize = 'sm' | 'md' | 'lg';\n\nexport type BadgeType = 'Idle' | 'Status Dot' | 'Closable' | 'Pill color';\n\nexport interface BadgeProps {\n /** Badge label text */\n label?: string;\n /** Color variant */\n color?: BadgeColor;\n /** Size variant */\n size?: BadgeSize;\n /** Type / style variant */\n type?: BadgeType;\n /** Icon to render inside Pill color type (Lucide icon component) */\n icon?: React.ElementType;\n /** Called when close button is clicked (Closable type) */\n onClose?: () => void;\n}\n\n// ─── Color Tokens ────────────────────────────────────────────────────────────\n\nconst COLOR_TOKENS: Record<\n BadgeColor,\n { bg: string; border: string; text: string; dot: string }\n> = {\n Gray: { bg: '#f9fafb', border: '#eaecf0', text: '#06080b', dot: '#667085' },\n Primary: { bg: '#f4f6f9', border: '#e6ebf2', text: '#1e2b3b', dot: '#6c8fbe' },\n Error: { bg: '#fef0ef', border: '#fbd2d0', text: '#cc1a11', dot: '#f04438' },\n Warning: { bg: '#fff9ee', border: '#ffedcc', text: '#db8f02', dot: '#f79009' },\n Success: { bg: '#f0fdfa', border: '#d2f9f1', text: '#15a686', dot: '#12b76a' },\n 'Blue light': { bg: '#f0f9ff', border: '#b9e6fe', text: '#026aa2', dot: '#0ba5ec' },\n Blue: { bg: '#eff8ff', border: '#b2ddff', text: '#175cd3', dot: '#2e90fa' },\n Indigo: { bg: '#eef4ff', border: '#c7d7fe', text: '#3538cd', dot: '#6172f3' },\n Purple: { bg: '#f4f3ff', border: '#d9d6fe', text: '#5925dc', dot: '#7a5af8' },\n Pink: { bg: '#fef6fb', border: '#fce7f6', text: '#c11574', dot: '#ee46bc' },\n Orange: { bg: '#fef6ee', border: '#ffd6ae', text: '#b93815', dot: '#ef6820' },\n 'Gray blue':{ bg: '#f8f9fc', border: '#d5d9eb', text: '#363f72', dot: '#717bbc' },\n};\n\n// ─── Size Tokens ─────────────────────────────────────────────────────────────\n\nconst SIZE_TOKENS: Record<\n BadgeSize,\n {\n paddingX: number;\n paddingY: number;\n paddingXClose: { left: number; right: number };\n paddingXDot: { left: number; right: number };\n paddingPill: number;\n fontSize: number;\n lineHeight: number;\n dotSize: number;\n iconSize: number;\n closeSize: number;\n }\n> = {\n sm: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 5,\n fontSize: 12, lineHeight: 18,\n dotSize: 6, iconSize: 12, closeSize: 12,\n },\n md: {\n paddingX: 8, paddingY: 2,\n paddingXClose: { left: 8, right: 4 },\n paddingXDot: { left: 6, right: 8 },\n paddingPill: 6,\n fontSize: 14, lineHeight: 20,\n dotSize: 6, iconSize: 14, closeSize: 14,\n },\n lg: {\n paddingX: 12, paddingY: 4,\n paddingXClose: { left: 12, right: 6 },\n paddingXDot: { left: 8, right: 12 },\n paddingPill: 8,\n fontSize: 14, lineHeight: 20,\n dotSize: 8, iconSize: 16, closeSize: 16,\n },\n};\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const Badge: React.FC<BadgeProps> = ({\n label = 'Label',\n color = 'Gray',\n size = 'sm',\n type = 'Idle',\n icon: IconComponent,\n onClose,\n}) => {\n const c = COLOR_TOKENS[color];\n const s = SIZE_TOKENS[size];\n\n // ── Shared wrapper style ──────────────────────────────────────────────────\n const baseWrapper: React.CSSProperties = {\n display: 'inline-flex',\n alignItems: 'center',\n backgroundColor: c.bg,\n border: `1px solid ${c.border}`,\n borderRadius: 16,\n boxSizing: 'border-box',\n width: 'fit-content',\n fontFamily: font,\n };\n\n // ── Text style ────────────────────────────────────────────────────────────\n const textStyle: React.CSSProperties = {\n fontSize: s.fontSize,\n lineHeight: `${s.lineHeight}px`,\n fontWeight: 500,\n color: c.text,\n whiteSpace: 'nowrap',\n fontFamily: font,\n margin: 0,\n };\n\n // ── Idle ─────────────────────────────────────────────────────────────────\n if (type === 'Idle') {\n return (\n <span\n style={{\n ...baseWrapper,\n padding: `${s.paddingY}px ${s.paddingX}px`,\n }}\n >\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Status Dot ────────────────────────────────────────────────────────────\n if (type === 'Status Dot') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 4,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXDot.left,\n paddingRight: s.paddingXDot.right,\n }}\n >\n {/* Dot */}\n <span\n style={{\n display: 'inline-block',\n width: s.dotSize,\n height: s.dotSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n flexShrink: 0,\n }}\n />\n <span style={textStyle}>{label}</span>\n </span>\n );\n }\n\n // ── Closable ──────────────────────────────────────────────────────────────\n if (type === 'Closable') {\n return (\n <span\n style={{\n ...baseWrapper,\n gap: 2,\n paddingTop: s.paddingY,\n paddingBottom: s.paddingY,\n paddingLeft: s.paddingXClose.left,\n paddingRight: s.paddingXClose.right,\n }}\n >\n <span style={textStyle}>{label}</span>\n <button\n onClick={onClose}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n background: 'none',\n border: 'none',\n padding: 2,\n borderRadius: 3,\n cursor: 'pointer',\n color: c.text,\n flexShrink: 0,\n lineHeight: 1,\n }}\n aria-label=\"Remove\"\n >\n <X size={s.closeSize} strokeWidth={2.5} />\n </button>\n </span>\n );\n }\n\n // ── Pill color (icon only) ────────────────────────────────────────────────\n if (type === 'Pill color') {\n const PillIcon = IconComponent;\n return (\n <span\n style={{\n ...baseWrapper,\n padding: s.paddingPill,\n }}\n >\n {PillIcon ? (\n <PillIcon size={s.iconSize} color={c.dot} strokeWidth={2} />\n ) : (\n // Default: colored circle dot\n <span\n style={{\n display: 'inline-block',\n width: s.iconSize,\n height: s.iconSize,\n borderRadius: '50%',\n backgroundColor: c.dot,\n }}\n />\n )}\n </span>\n );\n }\n\n return null;\n};\n","/**\n * Senestia Design System — Semantic Color Tokens\n *\n * ┌─────────────────────────────────────────────────────────────┐\n * │ Source: Figma DS-01 · Foundation → Semantic Color │\n * │ Use these tokens in components instead of raw hex values. │\n * └─────────────────────────────────────────────────────────────┘\n */\n\n// ─── Gray-Neutral ─────────────────────────────────────────────────────────────\n\nexport const grayNeutral = {\n /** Semantic/Gray-Neutral/fg/high — primary text, dark icons */\n fgHigh: '#1B1D22',\n /** Semantic/Gray-Neutral/fg/mid-on-white — label text, helper text, secondary icons */\n fgMid: '#6A6E83',\n /** Semantic/Gray-Neutral/fg/low-on-white — placeholder, disabled text */\n fgLow: '#9A9DAD',\n\n /** Semantic/Gray-Neutral/bg/white */\n bgWhite: '#FFFFFF',\n /** Semantic/Gray-Neutral/bg/lightgray — counter pill, subtle backgrounds */\n bgLightgray: '#F8F8F9',\n /** Semantic/Gray-Neutral/bg/disabled */\n bgDisabled: '#F3F4F6',\n\n /** Semantic/Gray-Neutral/border/midgray — default input border */\n borderMidgray: '#CFD1D9',\n /** Semantic/Gray-Neutral/border/light — dividers, card borders */\n borderLight: '#EBECEF',\n /** Disabled border (checkbox, input) */\n borderDisabled: '#E5EAF1',\n\n /** Gray/300 — icon separators */\n gray300: '#D0D5DD',\n /** Skeleton loading shimmer */\n bgSkeleton: '#EEF0F3',\n /** Strong disabled background (checkbox) */\n bgDisabledStrong: '#EBECEF',\n} as const;\n\n// ─── Status ───────────────────────────────────────────────────────────────────\n\nexport const status = {\n /** Error / invalid state */\n error: '#DB1439',\n /** Warning */\n warning: '#DB8F02',\n /** Success */\n success: '#15A686',\n} as const;\n\n// ─── CI Primary (Senestia brand purple) ───────────────────────────────────────\n\nexport const ciPrimary = {\n fgLow: '#C4B3F6',\n fgHigh: '#802CEB',\n bgLow: '#D4C9F6',\n bgMid: '#802CEB',\n bgHigh: '#5A1DA9',\n borderMid: '#996CF3',\n borderHigh: '#802CEB',\n} as const;\n\n// ─── OE Theme (OE brand blue) ─────────────────────────────────────────────────\n\nexport const oePrimary = {\n fgLow: '#5273A1',\n fgHigh: '#3A5274',\n bgLowest: '#EFF2F6', // selected item background in pickers\n bgLow: '#6E90BF',\n bgMid: '#5273A1',\n bgHigh: '#3A5274',\n borderLowest:'#C6D2E3', // focused item border\n borderLow: '#9CB3D2',\n borderMid: '#5273A1',\n /** Primary/300 — supporting/helper text on blue-tinted UI */\n p300: '#809BBF',\n /** Indigo/300 — \"Set to now\" link color */\n linkBlue: '#3C5BD5',\n} as const;\n\n// ─── Interactive states ───────────────────────────────────────────────────────\n\nexport const interactive = {\n /** Active / focused border */\n activeBorder: oePrimary.fgLow, // #5273A1\n /** Hover border */\n hoverBorder: '#3B82F6',\n /** Focus ring shadow */\n focusRing: '#D7DFEA',\n /** Invalid border */\n invalidBorder: status.error,\n} as const;\n\n// ─── Padding tokens (PD) ─────────────────────────────────────────────────────\n\nexport const padding = {\n 'PD-0': 0,\n 'PD-1': 1,\n 'PD-2': 2,\n 'PD-3': 4,\n 'PD-4': 6,\n 'PD-5': 8,\n 'PD-6': 12,\n 'PD-7': 16,\n 'PD-8': 24,\n 'PD-9': 32,\n 'PD-10': 40,\n 'PD-11': 48,\n 'PD-12': 56,\n 'PD-13': 64,\n 'PD-14': 72,\n 'PD-15': 80,\n} as const;\n\n// ─── Corner Radius tokens (CR) ───────────────────────────────────────────────\n\nexport const radius = {\n 'CR-0': 0,\n 'CR-1': 2,\n 'CR-2': 4,\n 'CR-3': 8,\n 'CR-4': 12,\n 'CR-5': 16,\n 'CR-6': 20,\n 'CR-7': 24,\n 'CR-8': 32,\n 'CR-9': 48,\n 'CR-10': 100,\n} as const;\n\n// ─── Typography ───────────────────────────────────────────────────────────────\n\nexport const font = 'Sarabun, sans-serif';\n","import React from 'react';\nimport { Circle, Info, XCircle, Search, Eye } from 'lucide-react';\nimport { grayNeutral, status, interactive, font } from './tokens';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport type InputFieldState =\n | 'Idle'\n | 'Idle hover'\n | 'Active'\n | 'Idle invalid'\n | 'Idle invalid hover'\n | 'Idle invalid active'\n | 'Filled'\n | 'Filled hover'\n | 'Filled active'\n | 'Filled invalid'\n | 'Filled invalid hover'\n | 'Filled invalid active'\n | 'Disable'\n | 'Keyboard focus'\n | 'Skeleton';\n\nexport type InputFieldSize = 'sm' | 'md' | 'lg';\n\nexport type InputFieldTrailingIcon = 'clear' | 'password' | 'search';\n\nexport type InputFieldCounter = {\n value: number;\n max: number;\n};\n\nexport interface InputFieldProps {\n /** Label text displayed above the input */\n label: string;\n /** Show required asterisk (*) */\n required?: boolean;\n /** Remark text next to label e.g. \"(optional)\" */\n labelRemark?: string;\n /** Placeholder text */\n placeholder?: string;\n /** Current value */\n value?: string;\n /** Called when value changes */\n onChange?: (value: string) => void;\n /** Helper text below the input (hidden when invalid) */\n helperText?: string;\n /** Error message below the input (shown when invalid state) */\n errorText?: string;\n /** Visual state from Figma */\n state?: InputFieldState;\n /** Input size — affects height, font, and padding */\n size?: InputFieldSize;\n /** Leading dropdown prefix text */\n leadingDropdownText?: string;\n /**\n * Leading icon inside the input (left side).\n * - `true` → default Circle icon\n * - `React.ElementType` → custom Lucide icon\n * - `false/undefined` → no icon\n */\n leadingIcon?: React.ElementType | boolean;\n /** Counter pill e.g. `{ value: 0, max: 20 }` */\n counter?: InputFieldCounter;\n /** Unit text inside the input */\n unit?: string;\n /** Single trailing icon */\n trailingIcon?: InputFieldTrailingIcon;\n /** Multiple trailing icons (overrides trailingIcon) */\n trailingIcons?: InputFieldTrailingIcon[];\n /** Show separator between trailing icons */\n trailingIconSeparator?: boolean;\n}\n\n// ─── Design tokens (from Figma) ──────────────────────────────────────────────\n\n/**\n * Size tokens — matched to Figma nodes:\n * sm (Sm-32): label C5 12/18 · input C4 14/20 · helper C5 12/18\n * md (Md-40): label C4 14/20 · input C3 16/24 · helper C4 14/20\n * lg (Lg-48): label C3 16/24 · input C3 16/24 · helper C4 14/20\n *\n * Spacing (per Figma sm node — gap-4 between all elements):\n * labelGap = gap between label row and input box\n * helperGap = gap between input box and helper/error text\n */\nconst sizeTokens = {\n sm: {\n inputHeight: 32,\n labelFontSize: 12, labelLineHeight: 18,\n inputFontSize: 14, inputLineHeight: 20,\n helperFontSize: 12, helperLineHeight: 18,\n paddingX: 12,\n iconSize: 16,\n labelIconSize: 12,\n labelGap: 4, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 8, leadingPr: 4, leadingPy: 6,\n chevronSize: 14,\n counterPadding: '1px 4px',\n counterRadius: 4,\n counterFontSize: 12, counterLineHeight: 18,\n skeletonLabelH: 18, skeletonInputH: 32,\n },\n md: {\n inputHeight: 40,\n labelFontSize: 14, labelLineHeight: 20,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 14,\n labelGap: 6, // label row → input\n helperGap: 4, // input → helper text\n leadingPl: 12, leadingPr: 8, leadingPy: 8,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 20, skeletonInputH: 40,\n },\n lg: {\n inputHeight: 48,\n labelFontSize: 16, labelLineHeight: 24,\n inputFontSize: 16, inputLineHeight: 24,\n helperFontSize: 14, helperLineHeight: 20,\n paddingX: 16,\n iconSize: 20,\n labelIconSize: 16,\n labelGap: 8, // label row → input\n helperGap: 6, // input → helper text\n leadingPl: 16, leadingPr: 8, leadingPy: 12,\n chevronSize: 16,\n counterPadding: '2px 8px',\n counterRadius: 8,\n counterFontSize: 14, counterLineHeight: 20,\n skeletonLabelH: 24, skeletonInputH: 48,\n },\n} as const;\n\n// ─── State helpers ────────────────────────────────────────────────────────────\n\nconst focusRingStyle = `0 0 0 2px ${interactive.focusRing}`;\n\nconst getStateFlags = (state: InputFieldState | undefined) => {\n const s = state ?? 'Idle';\n const isInvalid = s.includes('invalid');\n const isHover = s.includes('hover');\n const isActive = s === 'Active' || s === 'Keyboard focus' || s.endsWith('active');\n const isDisabled = s === 'Disable';\n const isSkeleton = s === 'Skeleton';\n const isFilled = s.includes('Filled');\n const isKeyboardFocus = s === 'Keyboard focus';\n return { s, isInvalid, isHover, isActive, isDisabled, isSkeleton, isFilled, isKeyboardFocus };\n};\n\n// ─── Trailing icon map → Lucide ───────────────────────────────────────────────\n\nconst TRAILING_ICON_MAP = {\n clear: XCircle,\n search: Search,\n password: Eye,\n} as const;\n\n// ─── Component ───────────────────────────────────────────────────────────────\n\nexport const InputField = ({\n label,\n required = false,\n labelRemark,\n placeholder = 'Placeholder',\n value,\n onChange: _onChange,\n helperText,\n errorText,\n state = 'Idle',\n size = 'md',\n leadingDropdownText,\n leadingIcon,\n counter,\n unit,\n trailingIcon,\n trailingIcons,\n trailingIconSeparator = false,\n}: InputFieldProps) => {\n const { isInvalid, isHover, isActive, isDisabled, isSkeleton, isKeyboardFocus } =\n getStateFlags(state);\n\n const t = sizeTokens[size];\n\n // ── Colors — mapped to Semantic/Gray-Neutral tokens ─────────────────────\n const borderColor = isInvalid\n ? interactive.invalidBorder // status.error #DB1439\n : isActive || isKeyboardFocus\n ? interactive.activeBorder // oePrimary.fgLow #5273A1\n : isHover\n ? interactive.hoverBorder // #3B82F6\n : grayNeutral.borderMidgray; // #CFD1D9\n\n const background = isDisabled\n ? grayNeutral.bgDisabled // #F3F4F6\n : isHover\n ? grayNeutral.bgLightgray // #F8F8F9\n : grayNeutral.bgWhite; // #FFFFFF\n\n // Label text → fg/mid-on-white (disabled → fg/low)\n const labelColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n // Typed value → fg/high (disabled → fg/low)\n const valueColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh; // #1B1D22\n\n // ── Icon colors (Figma: Semantic/Gray-Neutral/fg/high for input icons) ───\n // Input leading/trailing icons → fg/high (#1B1D22)\n const inputIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgHigh;\n // Label info icon → fg/mid (same as label text, #6A6E83)\n const labelIconColor = isDisabled ? grayNeutral.fgLow : grayNeutral.fgMid;\n\n const helperColor = isInvalid ? status.error : grayNeutral.fgMid; // #6A6E83\n\n // ── Skeleton ─────────────────────────────────────────────────────────────\n if (isSkeleton) {\n return (\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.labelGap }}>\n <div style={{ height: t.skeletonLabelH, background: grayNeutral.bgSkeleton, borderRadius: 6 }} />\n <div style={{ height: t.skeletonInputH, background: grayNeutral.bgSkeleton, border: `1px solid ${grayNeutral.bgSkeleton}`, borderRadius: 24 }} />\n </div>\n );\n }\n\n // ── Leading icon resolve ──────────────────────────────────────────────────\n // true → Circle (Figma default \"Icon/circle\"), component → custom, false → none\n const LeadingIconComponent: React.ElementType | null =\n leadingIcon === true\n ? Circle\n : leadingIcon\n ? (leadingIcon as React.ElementType)\n : null;\n\n // ── Trailing icons ────────────────────────────────────────────────────────\n const iconsToRender: InputFieldTrailingIcon[] =\n trailingIcons?.length ? trailingIcons : trailingIcon ? [trailingIcon] : [];\n\n // ── Text below input ──────────────────────────────────────────────────────\n const showText = isInvalid ? errorText : helperText;\n\n // ── Shared font style ─────────────────────────────────────────────────────\n const baseFont: React.CSSProperties = { fontFamily: font, fontWeight: 500 };\n\n return (\n /*\n * Outer wrapper — two-level gap structure matching Figma:\n * Level 1 (helperGap): separates [label + input block] from [helper text]\n * Level 2 (labelGap): separates [label row] from [input box]\n */\n <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: t.helperGap }}>\n\n {/* ── Level 1: label + input block ────────────────────────────────── */}\n <div style={{ display: 'flex', flexDirection: 'column', gap: t.labelGap, width: '100%' }}>\n\n {/* Label row */}\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, width: '100%' }}>\n {/* Left: label text + info icon */}\n <div style={{ display: 'flex', flex: '1 0 0', alignItems: 'center', gap: t.labelIconSize === 12 ? 4 : 6, minWidth: 0 }}>\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n }}\n >\n {label}\n </span>\n {/* Info icon — fg/mid-on-white (same shade as label text) */}\n <Info\n size={t.labelIconSize}\n color={labelIconColor}\n strokeWidth={1.8}\n style={{ flexShrink: 0 }}\n />\n </div>\n\n {/* Right: remark or required marker */}\n {labelRemark && (\n <span\n style={{\n ...baseFont,\n fontSize: t.labelFontSize,\n lineHeight: `${t.labelLineHeight}px`,\n color: labelColor,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n }}\n >\n {labelRemark}\n </span>\n )}\n {required && (\n <span style={{ color: status.error, fontWeight: 800, flexShrink: 0 }}>*</span>\n )}\n </div>\n\n {/* Input box */}\n <div\n style={{\n background,\n border: `1px solid ${borderColor}`,\n height: t.inputHeight,\n width: '100%',\n borderRadius: 24,\n display: 'flex',\n alignItems: leadingDropdownText ? 'stretch' : 'center',\n ...(leadingDropdownText ? {} : { gap: 8, padding: `0 ${t.paddingX}px` }),\n overflow: 'hidden',\n boxShadow: isActive || isKeyboardFocus ? focusRingStyle : 'none',\n opacity: isDisabled ? 0.7 : 1,\n boxSizing: 'border-box',\n }}\n >\n {/* Leading: dropdown prefix OR icon */}\n {leadingDropdownText ? (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n background: grayNeutral.bgWhite,\n padding: `${t.leadingPy}px ${t.leadingPr}px ${t.leadingPy}px ${t.leadingPl}px`,\n flexShrink: 0,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n }}\n >\n {leadingDropdownText}\n </span>\n <svg width={t.chevronSize} height={t.chevronSize} viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M4 6L8 10L12 6\" stroke={grayNeutral.fgHigh} strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </div>\n ) : LeadingIconComponent ? (\n /* Leading icon in input → fg/high (#1B1D22) per Figma */\n <LeadingIconComponent\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n ) : null}\n\n {/* Text + accessories area */}\n <div\n style={{\n flex: '1 0 0',\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n height: '100%',\n minWidth: 0,\n ...(leadingDropdownText\n ? { borderLeft: `1px solid ${grayNeutral.borderLight}`, padding: `0 12px` }\n : {}),\n }}\n >\n {/* Input */}\n <input\n type=\"text\"\n value={value ?? ''}\n onChange={e => _onChange?.(e.target.value)}\n placeholder={placeholder}\n disabled={isDisabled}\n style={{\n ...baseFont,\n flex: '1 0 0',\n border: 'none',\n outline: 'none',\n background: 'transparent',\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: valueColor,\n width: '100%',\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n cursor: isDisabled ? 'not-allowed' : 'text',\n }}\n />\n\n {/* Counter pill */}\n {counter && (\n <div\n style={{\n background: grayNeutral.bgLightgray,\n display: 'flex',\n gap: 2,\n alignItems: 'center',\n justifyContent: 'center',\n padding: t.counterPadding,\n borderRadius: t.counterRadius,\n flexShrink: 0,\n opacity: isDisabled ? 0.7 : 1,\n }}\n >\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgHigh,\n }}\n >\n {counter.value}\n </span>\n <span\n style={{\n ...baseFont,\n fontSize: t.counterFontSize,\n lineHeight: `${t.counterLineHeight}px`,\n color: grayNeutral.fgMid,\n }}\n >\n / {counter.max}\n </span>\n </div>\n )}\n\n {/* Unit text */}\n {unit && (\n <span\n style={{\n ...baseFont,\n fontSize: t.inputFontSize,\n lineHeight: `${t.inputLineHeight}px`,\n color: grayNeutral.fgHigh,\n whiteSpace: 'nowrap',\n flexShrink: 0,\n maxWidth: 64,\n overflow: 'hidden',\n }}\n >\n {unit}\n </span>\n )}\n\n {/* Trailing icons */}\n {iconsToRender.length > 0 && (\n <div style={{ display: 'flex', alignItems: 'center', gap: 4, flexShrink: 0 }}>\n {iconsToRender.map((ic, idx) => {\n const TrailingIcon = TRAILING_ICON_MAP[ic];\n return (\n <React.Fragment key={`${ic}-${idx}`}>\n {trailingIconSeparator && idx > 0 && (\n <div\n style={{\n width: 1,\n height: t.iconSize,\n background: grayNeutral.gray300,\n flexShrink: 0,\n alignSelf: 'center',\n }}\n />\n )}\n {/* Trailing icon → fg/high (#1B1D22) per Figma */}\n <TrailingIcon\n size={t.iconSize}\n color={inputIconColor}\n strokeWidth={1.6}\n style={{ flexShrink: 0 }}\n />\n </React.Fragment>\n );\n })}\n </div>\n )}\n </div>\n </div>\n </div>\n\n {/* ── Level 1: helper / error text ────────────────────────────────── */}\n {/*\n * No extra margin here — the outer helperGap (4px sm / 4px md / 6px lg)\n * from the flex container already provides the correct spacing from Figma.\n */}\n {showText && (\n <p\n style={{\n ...baseFont,\n margin: 0,\n fontSize: t.helperFontSize,\n lineHeight: `${t.helperLineHeight}px`,\n color: helperColor,\n width: '100%',\n }}\n >\n {showText}\n </p>\n )}\n </div>\n );\n};\n","// ─── Senestia Design System — Public API ─────────────────────────────────────\n//\n// import { Badge, InputField, tokens } from '@senestia/ui'\n//\n// ─────────────────────────────────────────────────────────────────────────────\n\n// ── Components ────────────────────────────────────────────────────────────────\nexport { Badge } from './stories/Badge';\nexport { InputField } from './stories/InputField';\n\n// ── Component types ───────────────────────────────────────────────────────────\nexport type { BadgeProps, BadgeColor, BadgeSize, BadgeType } from './stories/Badge';\nexport type {\n InputFieldProps,\n InputFieldState,\n InputFieldSize,\n InputFieldTrailingIcon,\n InputFieldCounter,\n} from './stories/InputField';\n\n// ── Design Tokens ─────────────────────────────────────────────────────────────\nexport {\n // Colors\n grayNeutral,\n status,\n ciPrimary,\n oePrimary,\n interactive,\n // Spacing\n padding,\n radius,\n // Typography\n font,\n} from './stories/tokens';\n\n// ── Tokens namespace (for tree-shaking friendly usage) ────────────────────────\nimport * as _tokens from './stories/tokens';\nexport const tokens = _tokens;\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senestia/ui",
3
- "version": "0.1.0-beta.0190ae9",
3
+ "version": "0.1.0-beta.0c3734c",
4
4
  "type": "module",
5
5
  "description": "Senestia Design System — React component library",
6
6
  "main": "./dist/senestia-ui.umd.js",