@senestia/ui 0.1.0-beta.a139ab8 → 0.1.0-beta.b22ef5a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/senestia-ui.es.js +187 -184
- package/dist/senestia-ui.es.js.map +1 -1
- package/dist/senestia-ui.umd.js +1 -1
- package/dist/senestia-ui.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/senestia-ui.es.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import e from "react";
|
|
2
|
-
import { Circle as
|
|
3
|
-
import { jsx as
|
|
1
|
+
import e, { useState as t } from "react";
|
|
2
|
+
import { Circle as n, Eye as r, Info as i, Search as a, X as o, XCircle as s } from "lucide-react";
|
|
3
|
+
import { jsx as c, jsxs as l } from "react/jsx-runtime";
|
|
4
4
|
//#region \0rolldown/runtime.js
|
|
5
|
-
var
|
|
5
|
+
var u = Object.defineProperty, d = (e, t) => {
|
|
6
6
|
let n = {};
|
|
7
|
-
for (var r in e)
|
|
7
|
+
for (var r in e) u(n, r, {
|
|
8
8
|
get: e[r],
|
|
9
9
|
enumerable: !0
|
|
10
10
|
});
|
|
11
|
-
return t ||
|
|
12
|
-
},
|
|
11
|
+
return t || u(n, Symbol.toStringTag, { value: "Module" }), n;
|
|
12
|
+
}, f = "Sarabun, sans-serif", p = {
|
|
13
13
|
Gray: {
|
|
14
14
|
bg: "#f9fafb",
|
|
15
15
|
border: "#eaecf0",
|
|
@@ -82,7 +82,7 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
82
82
|
text: "#363f72",
|
|
83
83
|
dot: "#717bbc"
|
|
84
84
|
}
|
|
85
|
-
},
|
|
85
|
+
}, m = {
|
|
86
86
|
sm: {
|
|
87
87
|
paddingX: 8,
|
|
88
88
|
paddingY: 2,
|
|
@@ -137,70 +137,70 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
137
137
|
iconSize: 16,
|
|
138
138
|
closeSize: 16
|
|
139
139
|
}
|
|
140
|
-
},
|
|
141
|
-
let
|
|
140
|
+
}, h = ({ label: e = "Label", color: t = "Gray", size: n = "sm", type: r = "Idle", icon: i, onClose: a }) => {
|
|
141
|
+
let s = p[t], u = m[n], d = {
|
|
142
142
|
display: "inline-flex",
|
|
143
143
|
alignItems: "center",
|
|
144
|
-
backgroundColor:
|
|
145
|
-
border: `1px solid ${
|
|
144
|
+
backgroundColor: s.bg,
|
|
145
|
+
border: `1px solid ${s.border}`,
|
|
146
146
|
borderRadius: 16,
|
|
147
147
|
boxSizing: "border-box",
|
|
148
148
|
width: "fit-content",
|
|
149
|
-
fontFamily:
|
|
149
|
+
fontFamily: f
|
|
150
150
|
}, h = {
|
|
151
151
|
fontSize: u.fontSize,
|
|
152
152
|
lineHeight: `${u.lineHeight}px`,
|
|
153
153
|
fontWeight: 500,
|
|
154
|
-
color:
|
|
154
|
+
color: s.text,
|
|
155
155
|
whiteSpace: "nowrap",
|
|
156
|
-
fontFamily:
|
|
156
|
+
fontFamily: f,
|
|
157
157
|
margin: 0
|
|
158
158
|
};
|
|
159
|
-
if (r === "Idle") return /* @__PURE__ */
|
|
159
|
+
if (r === "Idle") return /* @__PURE__ */ c("span", {
|
|
160
160
|
style: {
|
|
161
|
-
...
|
|
161
|
+
...d,
|
|
162
162
|
padding: `${u.paddingY}px ${u.paddingX}px`
|
|
163
163
|
},
|
|
164
|
-
children: /* @__PURE__ */
|
|
164
|
+
children: /* @__PURE__ */ c("span", {
|
|
165
165
|
style: h,
|
|
166
166
|
children: e
|
|
167
167
|
})
|
|
168
168
|
});
|
|
169
|
-
if (r === "Status Dot") return /* @__PURE__ */
|
|
169
|
+
if (r === "Status Dot") return /* @__PURE__ */ l("span", {
|
|
170
170
|
style: {
|
|
171
|
-
...
|
|
171
|
+
...d,
|
|
172
172
|
gap: 4,
|
|
173
173
|
paddingTop: u.paddingY,
|
|
174
174
|
paddingBottom: u.paddingY,
|
|
175
175
|
paddingLeft: u.paddingXDot.left,
|
|
176
176
|
paddingRight: u.paddingXDot.right
|
|
177
177
|
},
|
|
178
|
-
children: [/* @__PURE__ */
|
|
178
|
+
children: [/* @__PURE__ */ c("span", { style: {
|
|
179
179
|
display: "inline-block",
|
|
180
180
|
width: u.dotSize,
|
|
181
181
|
height: u.dotSize,
|
|
182
182
|
borderRadius: "50%",
|
|
183
|
-
backgroundColor:
|
|
183
|
+
backgroundColor: s.dot,
|
|
184
184
|
flexShrink: 0
|
|
185
|
-
} }), /* @__PURE__ */
|
|
185
|
+
} }), /* @__PURE__ */ c("span", {
|
|
186
186
|
style: h,
|
|
187
187
|
children: e
|
|
188
188
|
})]
|
|
189
189
|
});
|
|
190
|
-
if (r === "Closable") return /* @__PURE__ */
|
|
190
|
+
if (r === "Closable") return /* @__PURE__ */ l("span", {
|
|
191
191
|
style: {
|
|
192
|
-
...
|
|
192
|
+
...d,
|
|
193
193
|
gap: 2,
|
|
194
194
|
paddingTop: u.paddingY,
|
|
195
195
|
paddingBottom: u.paddingY,
|
|
196
196
|
paddingLeft: u.paddingXClose.left,
|
|
197
197
|
paddingRight: u.paddingXClose.right
|
|
198
198
|
},
|
|
199
|
-
children: [/* @__PURE__ */
|
|
199
|
+
children: [/* @__PURE__ */ c("span", {
|
|
200
200
|
style: h,
|
|
201
201
|
children: e
|
|
202
|
-
}), /* @__PURE__ */
|
|
203
|
-
onClick:
|
|
202
|
+
}), /* @__PURE__ */ c("button", {
|
|
203
|
+
onClick: a,
|
|
204
204
|
style: {
|
|
205
205
|
display: "inline-flex",
|
|
206
206
|
alignItems: "center",
|
|
@@ -210,12 +210,12 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
210
210
|
padding: 2,
|
|
211
211
|
borderRadius: 3,
|
|
212
212
|
cursor: "pointer",
|
|
213
|
-
color:
|
|
213
|
+
color: s.text,
|
|
214
214
|
flexShrink: 0,
|
|
215
215
|
lineHeight: 1
|
|
216
216
|
},
|
|
217
217
|
"aria-label": "Remove",
|
|
218
|
-
children: /* @__PURE__ */
|
|
218
|
+
children: /* @__PURE__ */ c(o, {
|
|
219
219
|
size: u.closeSize,
|
|
220
220
|
strokeWidth: 2.5
|
|
221
221
|
})
|
|
@@ -223,35 +223,35 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
223
223
|
});
|
|
224
224
|
if (r === "Pill color") {
|
|
225
225
|
let e = i;
|
|
226
|
-
return /* @__PURE__ */
|
|
226
|
+
return /* @__PURE__ */ c("span", {
|
|
227
227
|
style: {
|
|
228
|
-
...
|
|
228
|
+
...d,
|
|
229
229
|
padding: u.paddingPill
|
|
230
230
|
},
|
|
231
|
-
children: e ? /* @__PURE__ */
|
|
231
|
+
children: e ? /* @__PURE__ */ c(e, {
|
|
232
232
|
size: u.iconSize,
|
|
233
|
-
color:
|
|
233
|
+
color: s.dot,
|
|
234
234
|
strokeWidth: 2
|
|
235
|
-
}) : /* @__PURE__ */
|
|
235
|
+
}) : /* @__PURE__ */ c("span", { style: {
|
|
236
236
|
display: "inline-block",
|
|
237
237
|
width: u.iconSize,
|
|
238
238
|
height: u.iconSize,
|
|
239
239
|
borderRadius: "50%",
|
|
240
|
-
backgroundColor:
|
|
240
|
+
backgroundColor: s.dot
|
|
241
241
|
} })
|
|
242
242
|
});
|
|
243
243
|
}
|
|
244
244
|
return null;
|
|
245
|
-
},
|
|
246
|
-
ciPrimary: () =>
|
|
247
|
-
font: () =>
|
|
248
|
-
grayNeutral: () =>
|
|
249
|
-
interactive: () =>
|
|
250
|
-
oePrimary: () =>
|
|
251
|
-
padding: () =>
|
|
252
|
-
radius: () =>
|
|
253
|
-
status: () =>
|
|
254
|
-
}),
|
|
245
|
+
}, g = /* @__PURE__ */ d({
|
|
246
|
+
ciPrimary: () => y,
|
|
247
|
+
font: () => w,
|
|
248
|
+
grayNeutral: () => _,
|
|
249
|
+
interactive: () => x,
|
|
250
|
+
oePrimary: () => b,
|
|
251
|
+
padding: () => S,
|
|
252
|
+
radius: () => C,
|
|
253
|
+
status: () => v
|
|
254
|
+
}), _ = {
|
|
255
255
|
fgHigh: "#1B1D22",
|
|
256
256
|
fgMid: "#6A6E83",
|
|
257
257
|
fgLow: "#9A9DAD",
|
|
@@ -264,11 +264,11 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
264
264
|
gray300: "#D0D5DD",
|
|
265
265
|
bgSkeleton: "#EEF0F3",
|
|
266
266
|
bgDisabledStrong: "#EBECEF"
|
|
267
|
-
},
|
|
267
|
+
}, v = {
|
|
268
268
|
error: "#DB1439",
|
|
269
269
|
warning: "#DB8F02",
|
|
270
270
|
success: "#15A686"
|
|
271
|
-
},
|
|
271
|
+
}, y = {
|
|
272
272
|
fgLow: "#C4B3F6",
|
|
273
273
|
fgHigh: "#802CEB",
|
|
274
274
|
bgLow: "#D4C9F6",
|
|
@@ -276,7 +276,7 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
276
276
|
bgHigh: "#5A1DA9",
|
|
277
277
|
borderMid: "#996CF3",
|
|
278
278
|
borderHigh: "#802CEB"
|
|
279
|
-
},
|
|
279
|
+
}, b = {
|
|
280
280
|
fgLow: "#5273A1",
|
|
281
281
|
fgHigh: "#3A5274",
|
|
282
282
|
bgLowest: "#EFF2F6",
|
|
@@ -288,12 +288,12 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
288
288
|
borderMid: "#5273A1",
|
|
289
289
|
p300: "#809BBF",
|
|
290
290
|
linkBlue: "#3C5BD5"
|
|
291
|
-
},
|
|
292
|
-
activeBorder:
|
|
291
|
+
}, x = {
|
|
292
|
+
activeBorder: b.fgLow,
|
|
293
293
|
hoverBorder: "#3B82F6",
|
|
294
294
|
focusRing: "#D7DFEA",
|
|
295
|
-
invalidBorder:
|
|
296
|
-
},
|
|
295
|
+
invalidBorder: v.error
|
|
296
|
+
}, S = {
|
|
297
297
|
"PD-0": 0,
|
|
298
298
|
"PD-1": 1,
|
|
299
299
|
"PD-2": 2,
|
|
@@ -310,7 +310,7 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
310
310
|
"PD-13": 64,
|
|
311
311
|
"PD-14": 72,
|
|
312
312
|
"PD-15": 80
|
|
313
|
-
},
|
|
313
|
+
}, C = {
|
|
314
314
|
"CR-0": 0,
|
|
315
315
|
"CR-1": 2,
|
|
316
316
|
"CR-2": 4,
|
|
@@ -322,7 +322,7 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
322
322
|
"CR-8": 32,
|
|
323
323
|
"CR-9": 48,
|
|
324
324
|
"CR-10": 100
|
|
325
|
-
},
|
|
325
|
+
}, w = "Sarabun, sans-serif", T = {
|
|
326
326
|
sm: {
|
|
327
327
|
inputHeight: 32,
|
|
328
328
|
labelFontSize: 12,
|
|
@@ -395,7 +395,7 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
395
395
|
skeletonLabelH: 24,
|
|
396
396
|
skeletonInputH: 48
|
|
397
397
|
}
|
|
398
|
-
},
|
|
398
|
+
}, E = `0 0 0 2px ${x.focusRing}`, D = (e) => {
|
|
399
399
|
let t = e ?? "Idle";
|
|
400
400
|
return {
|
|
401
401
|
s: t,
|
|
@@ -407,49 +407,51 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
407
407
|
isFilled: t.includes("Filled"),
|
|
408
408
|
isKeyboardFocus: t === "Keyboard focus"
|
|
409
409
|
};
|
|
410
|
-
},
|
|
411
|
-
clear:
|
|
412
|
-
search:
|
|
413
|
-
password:
|
|
414
|
-
},
|
|
415
|
-
let
|
|
416
|
-
|
|
410
|
+
}, O = {
|
|
411
|
+
clear: s,
|
|
412
|
+
search: a,
|
|
413
|
+
password: r
|
|
414
|
+
}, k = ({ label: r, required: a = !1, labelRemark: o, placeholder: s = "Placeholder", value: u, onChange: d, helperText: f, errorText: p, state: m = "Idle", size: h = "md", leadingDropdownText: g, leadingIcon: y, counter: b, unit: S, trailingIcon: C, trailingIcons: k, trailingIconSeparator: A = !1 }) => {
|
|
415
|
+
let [j, M] = t(u ?? ""), N = (e) => {
|
|
416
|
+
M(e), d?.(e);
|
|
417
|
+
}, { isInvalid: P, isHover: F, isActive: I, isDisabled: L, isSkeleton: R, isKeyboardFocus: z } = D(m), B = T[h], V = P ? x.invalidBorder : I || z ? x.activeBorder : F ? x.hoverBorder : _.borderMidgray, H = L ? _.bgDisabled : F ? _.bgLightgray : _.bgWhite, U = L ? _.fgLow : _.fgMid, W = L ? _.fgLow : _.fgHigh, G = L ? _.fgLow : _.fgHigh, K = L ? _.fgLow : _.fgMid, q = P ? v.error : _.fgMid;
|
|
418
|
+
if (R) return /* @__PURE__ */ l("div", {
|
|
417
419
|
style: {
|
|
418
420
|
width: 320,
|
|
419
421
|
display: "flex",
|
|
420
422
|
flexDirection: "column",
|
|
421
|
-
gap:
|
|
423
|
+
gap: B.labelGap
|
|
422
424
|
},
|
|
423
|
-
children: [/* @__PURE__ */
|
|
424
|
-
height:
|
|
425
|
-
background:
|
|
425
|
+
children: [/* @__PURE__ */ c("div", { style: {
|
|
426
|
+
height: B.skeletonLabelH,
|
|
427
|
+
background: _.bgSkeleton,
|
|
426
428
|
borderRadius: 6
|
|
427
|
-
} }), /* @__PURE__ */
|
|
428
|
-
height:
|
|
429
|
-
background:
|
|
430
|
-
border: `1px solid ${
|
|
429
|
+
} }), /* @__PURE__ */ c("div", { style: {
|
|
430
|
+
height: B.skeletonInputH,
|
|
431
|
+
background: _.bgSkeleton,
|
|
432
|
+
border: `1px solid ${_.bgSkeleton}`,
|
|
431
433
|
borderRadius: 24
|
|
432
434
|
} })]
|
|
433
435
|
});
|
|
434
|
-
let
|
|
435
|
-
fontFamily:
|
|
436
|
+
let J = y === !0 ? n : y || null, Y = k?.length ? k : C ? [C] : [], X = P ? p : f, Z = {
|
|
437
|
+
fontFamily: w,
|
|
436
438
|
fontWeight: 500
|
|
437
439
|
};
|
|
438
|
-
return /* @__PURE__ */
|
|
440
|
+
return /* @__PURE__ */ l("div", {
|
|
439
441
|
style: {
|
|
440
442
|
width: 320,
|
|
441
443
|
display: "flex",
|
|
442
444
|
flexDirection: "column",
|
|
443
|
-
gap:
|
|
445
|
+
gap: B.helperGap
|
|
444
446
|
},
|
|
445
|
-
children: [/* @__PURE__ */
|
|
447
|
+
children: [/* @__PURE__ */ l("div", {
|
|
446
448
|
style: {
|
|
447
449
|
display: "flex",
|
|
448
450
|
flexDirection: "column",
|
|
449
|
-
gap:
|
|
451
|
+
gap: B.labelGap,
|
|
450
452
|
width: "100%"
|
|
451
453
|
},
|
|
452
|
-
children: [/* @__PURE__ */
|
|
454
|
+
children: [/* @__PURE__ */ l("div", {
|
|
453
455
|
style: {
|
|
454
456
|
display: "flex",
|
|
455
457
|
alignItems: "center",
|
|
@@ -457,107 +459,107 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
457
459
|
width: "100%"
|
|
458
460
|
},
|
|
459
461
|
children: [
|
|
460
|
-
/* @__PURE__ */
|
|
462
|
+
/* @__PURE__ */ l("div", {
|
|
461
463
|
style: {
|
|
462
464
|
display: "flex",
|
|
463
465
|
flex: "1 0 0",
|
|
464
466
|
alignItems: "center",
|
|
465
|
-
gap:
|
|
467
|
+
gap: B.labelIconSize === 12 ? 4 : 6,
|
|
466
468
|
minWidth: 0
|
|
467
469
|
},
|
|
468
|
-
children: [/* @__PURE__ */
|
|
470
|
+
children: [/* @__PURE__ */ c("span", {
|
|
469
471
|
style: {
|
|
470
|
-
...
|
|
471
|
-
fontSize:
|
|
472
|
-
lineHeight: `${
|
|
473
|
-
color:
|
|
472
|
+
...Z,
|
|
473
|
+
fontSize: B.labelFontSize,
|
|
474
|
+
lineHeight: `${B.labelLineHeight}px`,
|
|
475
|
+
color: U,
|
|
474
476
|
whiteSpace: "nowrap",
|
|
475
477
|
overflow: "hidden",
|
|
476
478
|
textOverflow: "ellipsis"
|
|
477
479
|
},
|
|
478
|
-
children:
|
|
479
|
-
}), /* @__PURE__ */
|
|
480
|
-
size:
|
|
481
|
-
color:
|
|
480
|
+
children: r
|
|
481
|
+
}), /* @__PURE__ */ c(i, {
|
|
482
|
+
size: B.labelIconSize,
|
|
483
|
+
color: K,
|
|
482
484
|
strokeWidth: 1.8,
|
|
483
485
|
style: { flexShrink: 0 }
|
|
484
486
|
})]
|
|
485
487
|
}),
|
|
486
|
-
|
|
488
|
+
o && /* @__PURE__ */ c("span", {
|
|
487
489
|
style: {
|
|
488
|
-
...
|
|
489
|
-
fontSize:
|
|
490
|
-
lineHeight: `${
|
|
491
|
-
color:
|
|
490
|
+
...Z,
|
|
491
|
+
fontSize: B.labelFontSize,
|
|
492
|
+
lineHeight: `${B.labelLineHeight}px`,
|
|
493
|
+
color: U,
|
|
492
494
|
whiteSpace: "nowrap",
|
|
493
495
|
flexShrink: 0
|
|
494
496
|
},
|
|
495
|
-
children:
|
|
497
|
+
children: o
|
|
496
498
|
}),
|
|
497
|
-
|
|
499
|
+
a && /* @__PURE__ */ c("span", {
|
|
498
500
|
style: {
|
|
499
|
-
color:
|
|
501
|
+
color: v.error,
|
|
500
502
|
fontWeight: 800,
|
|
501
503
|
flexShrink: 0
|
|
502
504
|
},
|
|
503
505
|
children: "*"
|
|
504
506
|
})
|
|
505
507
|
]
|
|
506
|
-
}), /* @__PURE__ */
|
|
508
|
+
}), /* @__PURE__ */ l("div", {
|
|
507
509
|
style: {
|
|
508
|
-
background:
|
|
509
|
-
border: `1px solid ${
|
|
510
|
-
height:
|
|
510
|
+
background: H,
|
|
511
|
+
border: `1px solid ${V}`,
|
|
512
|
+
height: B.inputHeight,
|
|
511
513
|
width: "100%",
|
|
512
514
|
borderRadius: 24,
|
|
513
515
|
display: "flex",
|
|
514
|
-
alignItems:
|
|
515
|
-
...
|
|
516
|
+
alignItems: g ? "stretch" : "center",
|
|
517
|
+
...g ? {} : {
|
|
516
518
|
gap: 8,
|
|
517
|
-
padding: `0 ${
|
|
519
|
+
padding: `0 ${B.paddingX}px`
|
|
518
520
|
},
|
|
519
521
|
overflow: "hidden",
|
|
520
|
-
boxShadow:
|
|
521
|
-
opacity:
|
|
522
|
+
boxShadow: I || z ? E : "none",
|
|
523
|
+
opacity: L ? .7 : 1,
|
|
522
524
|
boxSizing: "border-box"
|
|
523
525
|
},
|
|
524
|
-
children: [
|
|
526
|
+
children: [g ? /* @__PURE__ */ l("div", {
|
|
525
527
|
style: {
|
|
526
528
|
display: "flex",
|
|
527
529
|
alignItems: "center",
|
|
528
530
|
gap: 4,
|
|
529
|
-
background:
|
|
530
|
-
padding: `${
|
|
531
|
+
background: _.bgWhite,
|
|
532
|
+
padding: `${B.leadingPy}px ${B.leadingPr}px ${B.leadingPy}px ${B.leadingPl}px`,
|
|
531
533
|
flexShrink: 0
|
|
532
534
|
},
|
|
533
|
-
children: [/* @__PURE__ */
|
|
535
|
+
children: [/* @__PURE__ */ c("span", {
|
|
534
536
|
style: {
|
|
535
|
-
...
|
|
536
|
-
fontSize:
|
|
537
|
-
lineHeight: `${
|
|
538
|
-
color:
|
|
537
|
+
...Z,
|
|
538
|
+
fontSize: B.inputFontSize,
|
|
539
|
+
lineHeight: `${B.inputLineHeight}px`,
|
|
540
|
+
color: _.fgHigh,
|
|
539
541
|
whiteSpace: "nowrap"
|
|
540
542
|
},
|
|
541
|
-
children:
|
|
542
|
-
}), /* @__PURE__ */
|
|
543
|
-
width:
|
|
544
|
-
height:
|
|
543
|
+
children: g
|
|
544
|
+
}), /* @__PURE__ */ c("svg", {
|
|
545
|
+
width: B.chevronSize,
|
|
546
|
+
height: B.chevronSize,
|
|
545
547
|
viewBox: "0 0 16 16",
|
|
546
548
|
fill: "none",
|
|
547
|
-
children: /* @__PURE__ */
|
|
549
|
+
children: /* @__PURE__ */ c("path", {
|
|
548
550
|
d: "M4 6L8 10L12 6",
|
|
549
|
-
stroke:
|
|
551
|
+
stroke: _.fgHigh,
|
|
550
552
|
strokeWidth: "1.5",
|
|
551
553
|
strokeLinecap: "round",
|
|
552
554
|
strokeLinejoin: "round"
|
|
553
555
|
})
|
|
554
556
|
})]
|
|
555
|
-
}) :
|
|
556
|
-
size:
|
|
557
|
-
color:
|
|
557
|
+
}) : J ? /* @__PURE__ */ c(J, {
|
|
558
|
+
size: B.iconSize,
|
|
559
|
+
color: G,
|
|
558
560
|
strokeWidth: 1.6,
|
|
559
561
|
style: { flexShrink: 0 }
|
|
560
|
-
}) : null, /* @__PURE__ */
|
|
562
|
+
}) : null, /* @__PURE__ */ l("div", {
|
|
561
563
|
style: {
|
|
562
564
|
flex: "1 0 0",
|
|
563
565
|
display: "flex",
|
|
@@ -565,95 +567,96 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
565
567
|
gap: 8,
|
|
566
568
|
height: "100%",
|
|
567
569
|
minWidth: 0,
|
|
568
|
-
...
|
|
569
|
-
borderLeft: `1px solid ${
|
|
570
|
+
...g ? {
|
|
571
|
+
borderLeft: `1px solid ${_.borderLight}`,
|
|
570
572
|
padding: "0 12px"
|
|
571
573
|
} : {}
|
|
572
574
|
},
|
|
573
575
|
children: [
|
|
574
|
-
/* @__PURE__ */
|
|
576
|
+
/* @__PURE__ */ c("input", {
|
|
577
|
+
type: "text",
|
|
578
|
+
value: j,
|
|
579
|
+
onChange: (e) => N(e.target.value),
|
|
580
|
+
placeholder: s,
|
|
581
|
+
disabled: L,
|
|
575
582
|
style: {
|
|
583
|
+
...Z,
|
|
576
584
|
flex: "1 0 0",
|
|
585
|
+
border: "none",
|
|
586
|
+
outline: "none",
|
|
587
|
+
background: "transparent",
|
|
588
|
+
fontSize: B.inputFontSize,
|
|
589
|
+
lineHeight: `${B.inputLineHeight}px`,
|
|
590
|
+
color: W,
|
|
591
|
+
width: "100%",
|
|
592
|
+
minWidth: 0,
|
|
577
593
|
overflow: "hidden",
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
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
|
-
})
|
|
594
|
+
textOverflow: "ellipsis",
|
|
595
|
+
whiteSpace: "nowrap",
|
|
596
|
+
cursor: L ? "not-allowed" : "text"
|
|
597
|
+
}
|
|
595
598
|
}),
|
|
596
|
-
|
|
599
|
+
b && /* @__PURE__ */ l("div", {
|
|
597
600
|
style: {
|
|
598
|
-
background:
|
|
601
|
+
background: _.bgLightgray,
|
|
599
602
|
display: "flex",
|
|
600
603
|
gap: 2,
|
|
601
604
|
alignItems: "center",
|
|
602
605
|
justifyContent: "center",
|
|
603
|
-
padding:
|
|
604
|
-
borderRadius:
|
|
606
|
+
padding: B.counterPadding,
|
|
607
|
+
borderRadius: B.counterRadius,
|
|
605
608
|
flexShrink: 0,
|
|
606
|
-
opacity:
|
|
609
|
+
opacity: L ? .7 : 1
|
|
607
610
|
},
|
|
608
|
-
children: [/* @__PURE__ */
|
|
611
|
+
children: [/* @__PURE__ */ c("span", {
|
|
609
612
|
style: {
|
|
610
|
-
...
|
|
611
|
-
fontSize:
|
|
612
|
-
lineHeight: `${
|
|
613
|
-
color:
|
|
613
|
+
...Z,
|
|
614
|
+
fontSize: B.counterFontSize,
|
|
615
|
+
lineHeight: `${B.counterLineHeight}px`,
|
|
616
|
+
color: _.fgHigh
|
|
614
617
|
},
|
|
615
|
-
children:
|
|
616
|
-
}), /* @__PURE__ */
|
|
618
|
+
children: b.value
|
|
619
|
+
}), /* @__PURE__ */ l("span", {
|
|
617
620
|
style: {
|
|
618
|
-
...
|
|
619
|
-
fontSize:
|
|
620
|
-
lineHeight: `${
|
|
621
|
-
color:
|
|
621
|
+
...Z,
|
|
622
|
+
fontSize: B.counterFontSize,
|
|
623
|
+
lineHeight: `${B.counterLineHeight}px`,
|
|
624
|
+
color: _.fgMid
|
|
622
625
|
},
|
|
623
|
-
children: ["/ ",
|
|
626
|
+
children: ["/ ", b.max]
|
|
624
627
|
})]
|
|
625
628
|
}),
|
|
626
|
-
|
|
629
|
+
S && /* @__PURE__ */ c("span", {
|
|
627
630
|
style: {
|
|
628
|
-
...
|
|
629
|
-
fontSize:
|
|
630
|
-
lineHeight: `${
|
|
631
|
-
color:
|
|
631
|
+
...Z,
|
|
632
|
+
fontSize: B.inputFontSize,
|
|
633
|
+
lineHeight: `${B.inputLineHeight}px`,
|
|
634
|
+
color: _.fgHigh,
|
|
632
635
|
whiteSpace: "nowrap",
|
|
633
636
|
flexShrink: 0,
|
|
634
637
|
maxWidth: 64,
|
|
635
638
|
overflow: "hidden"
|
|
636
639
|
},
|
|
637
|
-
children:
|
|
640
|
+
children: S
|
|
638
641
|
}),
|
|
639
|
-
|
|
642
|
+
Y.length > 0 && /* @__PURE__ */ c("div", {
|
|
640
643
|
style: {
|
|
641
644
|
display: "flex",
|
|
642
645
|
alignItems: "center",
|
|
643
646
|
gap: 4,
|
|
644
647
|
flexShrink: 0
|
|
645
648
|
},
|
|
646
|
-
children:
|
|
647
|
-
let r =
|
|
648
|
-
return /* @__PURE__ */
|
|
649
|
+
children: Y.map((t, n) => {
|
|
650
|
+
let r = O[t];
|
|
651
|
+
return /* @__PURE__ */ l(e.Fragment, { children: [A && n > 0 && /* @__PURE__ */ c("div", { style: {
|
|
649
652
|
width: 1,
|
|
650
|
-
height:
|
|
651
|
-
background:
|
|
653
|
+
height: B.iconSize,
|
|
654
|
+
background: _.gray300,
|
|
652
655
|
flexShrink: 0,
|
|
653
656
|
alignSelf: "center"
|
|
654
|
-
} }), /* @__PURE__ */
|
|
655
|
-
size:
|
|
656
|
-
color:
|
|
657
|
+
} }), /* @__PURE__ */ c(r, {
|
|
658
|
+
size: B.iconSize,
|
|
659
|
+
color: G,
|
|
657
660
|
strokeWidth: 1.6,
|
|
658
661
|
style: { flexShrink: 0 }
|
|
659
662
|
})] }, `${t}-${n}`);
|
|
@@ -662,20 +665,20 @@ var l = Object.defineProperty, u = (e, t) => {
|
|
|
662
665
|
]
|
|
663
666
|
})]
|
|
664
667
|
})]
|
|
665
|
-
}),
|
|
668
|
+
}), X && /* @__PURE__ */ c("p", {
|
|
666
669
|
style: {
|
|
667
|
-
...
|
|
670
|
+
...Z,
|
|
668
671
|
margin: 0,
|
|
669
|
-
fontSize:
|
|
670
|
-
lineHeight: `${
|
|
671
|
-
color:
|
|
672
|
+
fontSize: B.helperFontSize,
|
|
673
|
+
lineHeight: `${B.helperLineHeight}px`,
|
|
674
|
+
color: q,
|
|
672
675
|
width: "100%"
|
|
673
676
|
},
|
|
674
|
-
children:
|
|
677
|
+
children: X
|
|
675
678
|
})]
|
|
676
679
|
});
|
|
677
|
-
},
|
|
680
|
+
}, A = g;
|
|
678
681
|
//#endregion
|
|
679
|
-
export {
|
|
682
|
+
export { h as Badge, k as InputField, y as ciPrimary, w as font, _ as grayNeutral, x as interactive, b as oePrimary, S as padding, C as radius, v as status, A as tokens };
|
|
680
683
|
|
|
681
684
|
//# sourceMappingURL=senestia-ui.es.js.map
|
|
@@ -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, { useState } 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 [internalValue, setInternalValue] = useState(value ?? '');\n\n const handleChange = (val: string) => {\n setInternalValue(val);\n _onChange?.(val);\n };\n\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={internalValue}\n onChange={e => handleChange(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/dist/senestia-ui.umd.js
CHANGED
|
@@ -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[C,k]=(0,t.useState)(s??``),A=e=>{k(e),c?.(e)},{isInvalid:j,isHover:M,isActive:N,isDisabled:P,isSkeleton:F,isKeyboardFocus:I}=D(d),L=T[f],R=j?x.invalidBorder:N||I?x.activeBorder:M?x.hoverBorder:_.borderMidgray,z=P?_.bgDisabled:M?_.bgLightgray:_.bgWhite,B=P?_.fgLow:_.fgMid,V=P?_.fgLow:_.fgHigh,H=P?_.fgLow:_.fgHigh,U=P?_.fgLow:_.fgMid,W=j?v.error:_.fgMid;if(F)return(0,r.jsxs)(`div`,{style:{width:320,display:`flex`,flexDirection:`column`,gap:L.labelGap},children:[(0,r.jsx)(`div`,{style:{height:L.skeletonLabelH,background:_.bgSkeleton,borderRadius:6}}),(0,r.jsx)(`div`,{style:{height:L.skeletonInputH,background:_.bgSkeleton,border:`1px solid ${_.bgSkeleton}`,borderRadius:24}})]});let G=m===!0?n.Circle:m||null,K=b?.length?b:y?[y]:[],q=j?u:l,J={fontFamily:w,fontWeight:500};return(0,r.jsxs)(`div`,{style:{width:320,display:`flex`,flexDirection:`column`,gap:L.helperGap},children:[(0,r.jsxs)(`div`,{style:{display:`flex`,flexDirection:`column`,gap:L.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:L.labelIconSize===12?4:6,minWidth:0},children:[(0,r.jsx)(`span`,{style:{...J,fontSize:L.labelFontSize,lineHeight:`${L.labelLineHeight}px`,color:B,whiteSpace:`nowrap`,overflow:`hidden`,textOverflow:`ellipsis`},children:e}),(0,r.jsx)(n.Info,{size:L.labelIconSize,color:U,strokeWidth:1.8,style:{flexShrink:0}})]}),a&&(0,r.jsx)(`span`,{style:{...J,fontSize:L.labelFontSize,lineHeight:`${L.labelLineHeight}px`,color:B,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:z,border:`1px solid ${R}`,height:L.inputHeight,width:`100%`,borderRadius:24,display:`flex`,alignItems:p?`stretch`:`center`,...p?{}:{gap:8,padding:`0 ${L.paddingX}px`},overflow:`hidden`,boxShadow:N||I?E:`none`,opacity:P?.7:1,boxSizing:`border-box`},children:[p?(0,r.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,background:_.bgWhite,padding:`${L.leadingPy}px ${L.leadingPr}px ${L.leadingPy}px ${L.leadingPl}px`,flexShrink:0},children:[(0,r.jsx)(`span`,{style:{...J,fontSize:L.inputFontSize,lineHeight:`${L.inputLineHeight}px`,color:_.fgHigh,whiteSpace:`nowrap`},children:p}),(0,r.jsx)(`svg`,{width:L.chevronSize,height:L.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`})})]}):G?(0,r.jsx)(G,{size:L.iconSize,color:H,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:C,onChange:e=>A(e.target.value),placeholder:o,disabled:P,style:{...J,flex:`1 0 0`,border:`none`,outline:`none`,background:`transparent`,fontSize:L.inputFontSize,lineHeight:`${L.inputLineHeight}px`,color:V,width:`100%`,minWidth:0,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`,cursor:P?`not-allowed`:`text`}}),h&&(0,r.jsxs)(`div`,{style:{background:_.bgLightgray,display:`flex`,gap:2,alignItems:`center`,justifyContent:`center`,padding:L.counterPadding,borderRadius:L.counterRadius,flexShrink:0,opacity:P?.7:1},children:[(0,r.jsx)(`span`,{style:{...J,fontSize:L.counterFontSize,lineHeight:`${L.counterLineHeight}px`,color:_.fgHigh},children:h.value}),(0,r.jsxs)(`span`,{style:{...J,fontSize:L.counterFontSize,lineHeight:`${L.counterLineHeight}px`,color:_.fgMid},children:[`/ `,h.max]})]}),g&&(0,r.jsx)(`span`,{style:{...J,fontSize:L.inputFontSize,lineHeight:`${L.inputLineHeight}px`,color:_.fgHigh,whiteSpace:`nowrap`,flexShrink:0,maxWidth:64,overflow:`hidden`},children:g}),K.length>0&&(0,r.jsx)(`div`,{style:{display:`flex`,alignItems:`center`,gap:4,flexShrink:0},children:K.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:L.iconSize,background:_.gray300,flexShrink:0,alignSelf:`center`}}),(0,r.jsx)(i,{size:L.iconSize,color:H,strokeWidth:1.6,style:{flexShrink:0}})]},`${e}-${n}`)})})]})]})]}),q&&(0,r.jsx)(`p`,{style:{...J,margin:0,fontSize:L.helperFontSize,lineHeight:`${L.helperLineHeight}px`,color:W,width:`100%`},children:q})]})},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, { useState } 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 [internalValue, setInternalValue] = useState(value ?? '');\n\n const handleChange = (val: string) => {\n setInternalValue(val);\n _onChange?.(val);\n };\n\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={internalValue}\n onChange={e => handleChange(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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"}
|