@newtonedev/editor 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -338,9 +338,19 @@ function useEditorState({
338
338
  initOverridesFromVariant(sidebarSelection.componentId);
339
339
  }
340
340
  }, [sidebarSelection, initOverridesFromVariant]);
341
- const handlePropOverride = react.useCallback((propName, value) => {
342
- setPropOverrides((prev) => ({ ...prev, [propName]: value }));
343
- }, []);
341
+ const handlePropOverride = react.useCallback(
342
+ (propName, value) => {
343
+ setPropOverrides((prev) => ({ ...prev, [propName]: value }));
344
+ setSidebarSelection((prev) => {
345
+ if (prev !== null) return prev;
346
+ if (previewView.kind === "component") {
347
+ return { scope: "component", componentId: previewView.componentId };
348
+ }
349
+ return prev;
350
+ });
351
+ },
352
+ [previewView]
353
+ );
344
354
  const handleResetOverrides = react.useCallback(() => {
345
355
  if (sidebarSelection?.scope === "variant") {
346
356
  initOverridesFromVariant(
@@ -2024,20 +2034,15 @@ function PresetSelector({
2024
2034
  }
2025
2035
  ),
2026
2036
  /* @__PURE__ */ jsxRuntime.jsx(
2027
- "svg",
2037
+ components.Icon,
2028
2038
  {
2029
- width: 10,
2030
- height: 10,
2031
- viewBox: "0 0 24 24",
2032
- fill: "none",
2033
- stroke: "currentColor",
2034
- strokeWidth: 2,
2039
+ name: "expand_more",
2040
+ size: 14,
2035
2041
  style: {
2036
2042
  transform: isOpen ? "rotate(180deg)" : "none",
2037
2043
  transition: "transform 150ms ease",
2038
2044
  flexShrink: 0
2039
- },
2040
- children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" })
2045
+ }
2041
2046
  }
2042
2047
  )
2043
2048
  ]
@@ -2185,20 +2190,7 @@ function PresetSelector({
2185
2190
  borderRadius: 4,
2186
2191
  flexShrink: 0
2187
2192
  },
2188
- children: /* @__PURE__ */ jsxRuntime.jsxs(
2189
- "svg",
2190
- {
2191
- width: 14,
2192
- height: 14,
2193
- viewBox: "0 0 24 24",
2194
- fill: "currentColor",
2195
- children: [
2196
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: 12, cy: 5, r: 2 }),
2197
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: 12, cy: 12, r: 2 }),
2198
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: 12, cy: 19, r: 2 })
2199
- ]
2200
- }
2201
- )
2193
+ children: /* @__PURE__ */ jsxRuntime.jsx(components.Icon, { name: "more_vert", size: 14, color: textSecondary })
2202
2194
  }
2203
2195
  )
2204
2196
  ] }),
@@ -2317,21 +2309,7 @@ function PresetSelector({
2317
2309
  cursor: "pointer"
2318
2310
  },
2319
2311
  children: [
2320
- /* @__PURE__ */ jsxRuntime.jsxs(
2321
- "svg",
2322
- {
2323
- width: 14,
2324
- height: 14,
2325
- viewBox: "0 0 24 24",
2326
- fill: "none",
2327
- stroke: "currentColor",
2328
- strokeWidth: 2,
2329
- children: [
2330
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: 12, y1: 5, x2: 12, y2: 19 }),
2331
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: 5, y1: 12, x2: 19, y2: 12 })
2332
- ]
2333
- }
2334
- ),
2312
+ /* @__PURE__ */ jsxRuntime.jsx(components.Icon, { name: "add", size: 14, color: textSecondary }),
2335
2313
  "New preset"
2336
2314
  ]
2337
2315
  }
@@ -2343,67 +2321,12 @@ function PresetSelector({
2343
2321
  }
2344
2322
  var SIDEBAR_WIDTH2 = 360;
2345
2323
  var ACCORDION_SECTIONS = [
2346
- { id: "dynamic-range", label: "Dynamic Range" },
2347
- { id: "colors", label: "Colors" },
2348
- { id: "fonts", label: "Fonts" },
2349
- { id: "icons", label: "Icons" },
2350
- { id: "others", label: "Others" }
2324
+ { id: "dynamic-range", label: "Dynamic Range", icon: "contrast" },
2325
+ { id: "colors", label: "Colors", icon: "palette" },
2326
+ { id: "fonts", label: "Fonts", icon: "text_fields" },
2327
+ { id: "icons", label: "Icons", icon: "grid_view" },
2328
+ { id: "others", label: "Others", icon: "tune" }
2351
2329
  ];
2352
- function SectionIcon({ id }) {
2353
- const props = {
2354
- width: 16,
2355
- height: 16,
2356
- viewBox: "0 0 24 24",
2357
- fill: "none",
2358
- stroke: "currentColor",
2359
- strokeWidth: 2,
2360
- strokeLinecap: "round",
2361
- strokeLinejoin: "round"
2362
- };
2363
- switch (id) {
2364
- case "dynamic-range":
2365
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, children: [
2366
- /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "5" }),
2367
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "1", x2: "12", y2: "3" }),
2368
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "23" }),
2369
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "4.22", x2: "5.64", y2: "5.64" }),
2370
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "18.36", x2: "19.78", y2: "19.78" }),
2371
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "12", x2: "3", y2: "12" }),
2372
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "21", y1: "12", x2: "23", y2: "12" }),
2373
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4.22", y1: "19.78", x2: "5.64", y2: "18.36" }),
2374
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18.36", y1: "5.64", x2: "19.78", y2: "4.22" })
2375
- ] });
2376
- case "colors":
2377
- return /* @__PURE__ */ jsxRuntime.jsx("svg", { ...props, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z" }) });
2378
- case "fonts":
2379
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, children: [
2380
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "4 7 4 4 20 4 20 7" }),
2381
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "9", y1: "20", x2: "15", y2: "20" }),
2382
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "4", x2: "12", y2: "20" })
2383
- ] });
2384
- case "icons":
2385
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, children: [
2386
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "7", height: "7" }),
2387
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "14", y: "3", width: "7", height: "7" }),
2388
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "14", width: "7", height: "7" }),
2389
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "14", y: "14", width: "7", height: "7" })
2390
- ] });
2391
- case "others":
2392
- return /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...props, children: [
2393
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4", y1: "21", x2: "4", y2: "14" }),
2394
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "4", y1: "10", x2: "4", y2: "3" }),
2395
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "21", x2: "12", y2: "12" }),
2396
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "8", x2: "12", y2: "3" }),
2397
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "20", y1: "21", x2: "20", y2: "16" }),
2398
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "20", y1: "12", x2: "20", y2: "3" }),
2399
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "1", y1: "14", x2: "7", y2: "14" }),
2400
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "9", y1: "8", x2: "15", y2: "8" }),
2401
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "17", y1: "16", x2: "23", y2: "16" })
2402
- ] });
2403
- default:
2404
- return null;
2405
- }
2406
- }
2407
2330
  function Sidebar({
2408
2331
  state,
2409
2332
  dispatch,
@@ -2551,23 +2474,18 @@ function Sidebar({
2551
2474
  },
2552
2475
  children: [
2553
2476
  /* @__PURE__ */ jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
2554
- /* @__PURE__ */ jsxRuntime.jsx(SectionIcon, { id: section.id }),
2477
+ /* @__PURE__ */ jsxRuntime.jsx(components.Icon, { name: section.icon, size: 16 }),
2555
2478
  section.label
2556
2479
  ] }),
2557
2480
  /* @__PURE__ */ jsxRuntime.jsx(
2558
- "svg",
2481
+ components.Icon,
2559
2482
  {
2560
- width: 12,
2561
- height: 12,
2562
- viewBox: "0 0 24 24",
2563
- fill: "none",
2564
- stroke: "currentColor",
2565
- strokeWidth: 2,
2483
+ name: "expand_more",
2484
+ size: 16,
2566
2485
  style: {
2567
2486
  transform: isOpen ? "rotate(180deg)" : "none",
2568
2487
  transition: "transform 150ms ease"
2569
- },
2570
- children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" })
2488
+ }
2571
2489
  }
2572
2490
  )
2573
2491
  ]
@@ -3232,16 +3150,238 @@ function CategoryView({
3232
3150
  )
3233
3151
  ] });
3234
3152
  }
3153
+ function IconBrowserView({
3154
+ selectedIconName,
3155
+ onIconSelect
3156
+ }) {
3157
+ const tokens = components.useTokens();
3158
+ const [search, setSearch] = react.useState("");
3159
+ const [hoveredIcon, setHoveredIcon] = react.useState(null);
3160
+ const scrollRef = react.useRef(null);
3161
+ const filteredCategories = react.useMemo(() => {
3162
+ const q = search.toLowerCase().trim();
3163
+ if (!q) return components.ICON_CATALOG;
3164
+ return components.ICON_CATALOG.map((cat) => ({
3165
+ ...cat,
3166
+ icons: cat.icons.filter((name) => name.includes(q))
3167
+ })).filter((cat) => cat.icons.length > 0);
3168
+ }, [search]);
3169
+ react.useEffect(() => {
3170
+ if (!selectedIconName || !scrollRef.current) return;
3171
+ const el = scrollRef.current.querySelector(
3172
+ `[data-icon="${selectedIconName}"]`
3173
+ );
3174
+ if (el) {
3175
+ el.scrollIntoView({ behavior: "smooth", block: "nearest" });
3176
+ }
3177
+ }, [selectedIconName]);
3178
+ const accentColor = newtone.srgbToHex(tokens.accent.fill.srgb);
3179
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3180
+ "div",
3181
+ {
3182
+ style: {
3183
+ display: "flex",
3184
+ flexDirection: "column",
3185
+ height: "100%",
3186
+ minHeight: 0
3187
+ },
3188
+ children: [
3189
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0 32px", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
3190
+ /* @__PURE__ */ jsxRuntime.jsx(
3191
+ components.Icon,
3192
+ {
3193
+ name: "search",
3194
+ size: 18,
3195
+ color: newtone.srgbToHex(tokens.textTertiary.srgb),
3196
+ style: {
3197
+ position: "absolute",
3198
+ left: 10,
3199
+ top: 9,
3200
+ pointerEvents: "none"
3201
+ }
3202
+ }
3203
+ ),
3204
+ /* @__PURE__ */ jsxRuntime.jsx(
3205
+ "input",
3206
+ {
3207
+ type: "text",
3208
+ placeholder: "Search icons...",
3209
+ value: search,
3210
+ onChange: (e) => setSearch(e.target.value),
3211
+ style: {
3212
+ width: "100%",
3213
+ padding: "8px 12px 8px 34px",
3214
+ borderRadius: 8,
3215
+ border: `1px solid ${newtone.srgbToHex(tokens.border.srgb)}`,
3216
+ backgroundColor: newtone.srgbToHex(tokens.backgroundSunken.srgb),
3217
+ color: newtone.srgbToHex(tokens.textPrimary.srgb),
3218
+ fontSize: 13,
3219
+ boxSizing: "border-box",
3220
+ outline: "none"
3221
+ }
3222
+ }
3223
+ )
3224
+ ] }) }),
3225
+ /* @__PURE__ */ jsxRuntime.jsxs(
3226
+ "div",
3227
+ {
3228
+ ref: scrollRef,
3229
+ style: {
3230
+ flex: 1,
3231
+ overflowY: "auto",
3232
+ padding: "16px 32px 32px"
3233
+ },
3234
+ children: [
3235
+ filteredCategories.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(
3236
+ "p",
3237
+ {
3238
+ style: {
3239
+ fontSize: 13,
3240
+ color: newtone.srgbToHex(tokens.textTertiary.srgb),
3241
+ textAlign: "center",
3242
+ marginTop: 32
3243
+ },
3244
+ children: "No icons found"
3245
+ }
3246
+ ),
3247
+ filteredCategories.map((category) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: 24 }, children: [
3248
+ /* @__PURE__ */ jsxRuntime.jsx(
3249
+ "h3",
3250
+ {
3251
+ style: {
3252
+ fontSize: 12,
3253
+ fontWeight: 600,
3254
+ color: newtone.srgbToHex(tokens.textSecondary.srgb),
3255
+ textTransform: "uppercase",
3256
+ letterSpacing: 0.5,
3257
+ margin: "0 0 8px"
3258
+ },
3259
+ children: category.label
3260
+ }
3261
+ ),
3262
+ /* @__PURE__ */ jsxRuntime.jsx(
3263
+ "div",
3264
+ {
3265
+ style: {
3266
+ display: "grid",
3267
+ gridTemplateColumns: "repeat(auto-fill, minmax(80px, 1fr))",
3268
+ gap: 6
3269
+ },
3270
+ children: category.icons.map((name) => {
3271
+ const isSelected = selectedIconName === name;
3272
+ const isHovered = hoveredIcon === name;
3273
+ const borderColor = isSelected ? accentColor : isHovered ? `${accentColor}66` : "transparent";
3274
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3275
+ "button",
3276
+ {
3277
+ "data-icon": name,
3278
+ onClick: () => onIconSelect(name),
3279
+ onMouseEnter: () => setHoveredIcon(name),
3280
+ onMouseLeave: () => setHoveredIcon(null),
3281
+ style: {
3282
+ display: "flex",
3283
+ flexDirection: "column",
3284
+ alignItems: "center",
3285
+ justifyContent: "center",
3286
+ gap: 4,
3287
+ padding: "8px 4px 6px",
3288
+ borderRadius: 8,
3289
+ border: `2px solid ${borderColor}`,
3290
+ backgroundColor: isSelected ? newtone.srgbToHex(tokens.backgroundElevated.srgb) : "transparent",
3291
+ cursor: "pointer",
3292
+ transition: "border-color 150ms ease"
3293
+ },
3294
+ children: [
3295
+ /* @__PURE__ */ jsxRuntime.jsx(components.Icon, { name, size: 40 }),
3296
+ /* @__PURE__ */ jsxRuntime.jsx(
3297
+ "span",
3298
+ {
3299
+ style: {
3300
+ fontSize: 10,
3301
+ color: isSelected ? accentColor : newtone.srgbToHex(tokens.textTertiary.srgb),
3302
+ fontWeight: isSelected ? 600 : 400,
3303
+ maxWidth: "100%",
3304
+ overflow: "hidden",
3305
+ textOverflow: "ellipsis",
3306
+ whiteSpace: "nowrap"
3307
+ },
3308
+ children: name
3309
+ }
3310
+ )
3311
+ ]
3312
+ },
3313
+ name
3314
+ );
3315
+ })
3316
+ }
3317
+ )
3318
+ ] }, category.id))
3319
+ ]
3320
+ }
3321
+ )
3322
+ ]
3323
+ }
3324
+ );
3325
+ }
3235
3326
  function ComponentDetailView({
3236
3327
  componentId,
3237
3328
  selectedVariantId,
3329
+ onSelectVariant,
3238
3330
  propOverrides,
3239
- onSelectVariant
3331
+ onPropOverride
3240
3332
  }) {
3241
3333
  const tokens = components.useTokens();
3242
3334
  const component = components.getComponent(componentId);
3243
3335
  const [hoveredId, setHoveredId] = react.useState(null);
3244
3336
  if (!component) return null;
3337
+ if (componentId === "icon" && propOverrides && onPropOverride) {
3338
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3339
+ "div",
3340
+ {
3341
+ style: {
3342
+ padding: "32px 0 0",
3343
+ height: "100%",
3344
+ display: "flex",
3345
+ flexDirection: "column"
3346
+ },
3347
+ children: [
3348
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "0 32px", marginBottom: 24 }, children: [
3349
+ /* @__PURE__ */ jsxRuntime.jsx(
3350
+ "h2",
3351
+ {
3352
+ style: {
3353
+ fontSize: 22,
3354
+ fontWeight: 700,
3355
+ color: newtone.srgbToHex(tokens.textPrimary.srgb),
3356
+ margin: 0,
3357
+ marginBottom: 4
3358
+ },
3359
+ children: component.name
3360
+ }
3361
+ ),
3362
+ /* @__PURE__ */ jsxRuntime.jsx(
3363
+ "p",
3364
+ {
3365
+ style: {
3366
+ fontSize: 14,
3367
+ color: newtone.srgbToHex(tokens.textSecondary.srgb),
3368
+ margin: 0
3369
+ },
3370
+ children: component.description
3371
+ }
3372
+ )
3373
+ ] }),
3374
+ /* @__PURE__ */ jsxRuntime.jsx(
3375
+ IconBrowserView,
3376
+ {
3377
+ selectedIconName: propOverrides.name ?? "add",
3378
+ onIconSelect: (name) => onPropOverride("name", name)
3379
+ }
3380
+ )
3381
+ ]
3382
+ }
3383
+ );
3384
+ }
3245
3385
  const interactiveColor = newtone.srgbToHex(tokens.accent.fill.srgb);
3246
3386
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: 32 }, children: [
3247
3387
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3317,7 +3457,7 @@ function ComponentDetailView({
3317
3457
  ComponentRenderer,
3318
3458
  {
3319
3459
  componentId,
3320
- props: isSelected && propOverrides ? { ...variant.props, ...propOverrides } : variant.props
3460
+ props: variant.props
3321
3461
  }
3322
3462
  )
3323
3463
  }
@@ -3345,9 +3485,10 @@ function ComponentDetailView({
3345
3485
  function PreviewWindow({
3346
3486
  view,
3347
3487
  selectedVariantId,
3348
- propOverrides,
3349
3488
  onNavigate,
3350
- onSelectVariant
3489
+ onSelectVariant,
3490
+ propOverrides,
3491
+ onPropOverride
3351
3492
  }) {
3352
3493
  const tokens = components.useTokens();
3353
3494
  const handleNavigateToCategory = react.useCallback(
@@ -3387,8 +3528,9 @@ function PreviewWindow({
3387
3528
  {
3388
3529
  componentId: view.componentId,
3389
3530
  selectedVariantId,
3531
+ onSelectVariant,
3390
3532
  propOverrides,
3391
- onSelectVariant
3533
+ onPropOverride
3392
3534
  }
3393
3535
  )
3394
3536
  ] })
@@ -3396,50 +3538,89 @@ function PreviewWindow({
3396
3538
  );
3397
3539
  }
3398
3540
  function CopyButton({ text }) {
3541
+ const tokens = components.useTokens();
3399
3542
  const [copied, setCopied] = react.useState(false);
3400
3543
  const handleCopy = react.useCallback(async () => {
3401
3544
  await navigator.clipboard.writeText(text);
3402
3545
  setCopied(true);
3403
3546
  setTimeout(() => setCopied(false), 2e3);
3404
3547
  }, [text]);
3405
- return /* @__PURE__ */ jsxRuntime.jsx(components.Button, { variant: "tertiary", semantic: "neutral", size: "sm", icon: copied ? "check" : "content_copy", onPress: handleCopy, children: copied ? "Copied!" : "Copy" });
3548
+ return /* @__PURE__ */ jsxRuntime.jsx(
3549
+ "button",
3550
+ {
3551
+ onClick: handleCopy,
3552
+ "aria-label": copied ? "Copied" : "Copy code",
3553
+ style: {
3554
+ background: "none",
3555
+ border: "none",
3556
+ cursor: "pointer",
3557
+ padding: 4,
3558
+ display: "flex",
3559
+ alignItems: "center",
3560
+ justifyContent: "center",
3561
+ color: newtone.srgbToHex(
3562
+ copied ? tokens.accent.fill.srgb : tokens.textTertiary.srgb
3563
+ ),
3564
+ transition: "color 150ms ease"
3565
+ },
3566
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3567
+ components.Icon,
3568
+ {
3569
+ name: copied ? "check" : "content_copy",
3570
+ size: 16,
3571
+ color: newtone.srgbToHex(
3572
+ copied ? tokens.accent.fill.srgb : tokens.textTertiary.srgb
3573
+ )
3574
+ }
3575
+ )
3576
+ }
3577
+ );
3406
3578
  }
3407
3579
  function CodeBlock({
3408
3580
  code
3409
3581
  }) {
3410
3582
  const tokens = components.useTokens();
3411
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative" }, children: [
3412
- /* @__PURE__ */ jsxRuntime.jsx(
3413
- "div",
3414
- {
3415
- style: {
3416
- position: "absolute",
3417
- top: 8,
3418
- right: 8
3419
- },
3420
- children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { text: code })
3421
- }
3422
- ),
3423
- /* @__PURE__ */ jsxRuntime.jsx(
3424
- "pre",
3425
- {
3426
- style: {
3427
- backgroundColor: newtone.srgbToHex(tokens.backgroundSunken.srgb),
3428
- border: `1px solid ${newtone.srgbToHex(tokens.border.srgb)}`,
3429
- borderRadius: 8,
3430
- padding: 16,
3431
- paddingRight: 80,
3432
- overflow: "auto",
3433
- fontSize: 13,
3434
- lineHeight: 1.5,
3435
- fontFamily: "'SF Mono', 'Fira Code', 'Fira Mono', Menlo, monospace",
3436
- color: newtone.srgbToHex(tokens.textPrimary.srgb),
3437
- margin: 0
3438
- },
3439
- children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code })
3440
- }
3441
- )
3442
- ] });
3583
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3584
+ "div",
3585
+ {
3586
+ style: {
3587
+ backgroundColor: newtone.srgbToHex(tokens.backgroundSunken.srgb),
3588
+ border: `1px solid ${newtone.srgbToHex(tokens.border.srgb)}`,
3589
+ borderRadius: 8,
3590
+ overflow: "hidden"
3591
+ },
3592
+ children: [
3593
+ /* @__PURE__ */ jsxRuntime.jsx(
3594
+ "div",
3595
+ {
3596
+ style: {
3597
+ display: "flex",
3598
+ justifyContent: "flex-end",
3599
+ padding: "4px 8px",
3600
+ borderBottom: `1px solid ${newtone.srgbToHex(tokens.border.srgb)}`
3601
+ },
3602
+ children: /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { text: code })
3603
+ }
3604
+ ),
3605
+ /* @__PURE__ */ jsxRuntime.jsx(
3606
+ "pre",
3607
+ {
3608
+ style: {
3609
+ padding: "12px 16px",
3610
+ whiteSpace: "pre-wrap",
3611
+ wordBreak: "break-word",
3612
+ fontSize: 13,
3613
+ lineHeight: 1.5,
3614
+ fontFamily: "'SF Mono', 'Fira Code', 'Fira Mono', Menlo, monospace",
3615
+ color: newtone.srgbToHex(tokens.textPrimary.srgb),
3616
+ margin: 0
3617
+ },
3618
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { children: code })
3619
+ }
3620
+ )
3621
+ ]
3622
+ }
3623
+ );
3443
3624
  }
3444
3625
  function RightSidebar({
3445
3626
  selection,
@@ -3447,7 +3628,9 @@ function RightSidebar({
3447
3628
  onPropOverride,
3448
3629
  onResetOverrides,
3449
3630
  onClose,
3450
- onScopeToComponent
3631
+ onScopeToComponent,
3632
+ previewConfig,
3633
+ colorMode
3451
3634
  }) {
3452
3635
  const tokens = components.useTokens();
3453
3636
  const visible = selection !== null;
@@ -3500,23 +3683,7 @@ function RightSidebar({
3500
3683
  display: "flex",
3501
3684
  alignItems: "center"
3502
3685
  },
3503
- children: /* @__PURE__ */ jsxRuntime.jsxs(
3504
- "svg",
3505
- {
3506
- width: 16,
3507
- height: 16,
3508
- viewBox: "0 0 24 24",
3509
- fill: "none",
3510
- stroke: "currentColor",
3511
- strokeWidth: 2,
3512
- strokeLinecap: "round",
3513
- strokeLinejoin: "round",
3514
- children: [
3515
- /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
3516
- /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "12 19 5 12 12 5" })
3517
- ]
3518
- }
3519
- )
3686
+ children: /* @__PURE__ */ jsxRuntime.jsx(components.Icon, { name: "arrow_back", size: 16, color: newtone.srgbToHex(tokens.textSecondary.srgb) })
3520
3687
  }
3521
3688
  ),
3522
3689
  selection.scope === "variant" && variant ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -3585,6 +3752,32 @@ function RightSidebar({
3585
3752
  padding: 16
3586
3753
  },
3587
3754
  children: [
3755
+ /* @__PURE__ */ jsxRuntime.jsx(
3756
+ "div",
3757
+ {
3758
+ style: {
3759
+ marginBottom: 20,
3760
+ borderRadius: 8,
3761
+ border: `1px solid ${newtone.srgbToHex(tokens.border.srgb)}`,
3762
+ overflow: "hidden"
3763
+ },
3764
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3765
+ components.NewtoneProvider,
3766
+ {
3767
+ config: previewConfig,
3768
+ initialMode: colorMode,
3769
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3770
+ PreviewSurface,
3771
+ {
3772
+ componentId: selection.componentId,
3773
+ propOverrides
3774
+ }
3775
+ )
3776
+ },
3777
+ colorMode
3778
+ )
3779
+ }
3780
+ ),
3588
3781
  /* @__PURE__ */ jsxRuntime.jsx(
3589
3782
  "h3",
3590
3783
  {
@@ -3652,6 +3845,26 @@ function RightSidebar({
3652
3845
  }
3653
3846
  );
3654
3847
  }
3848
+ function PreviewSurface({
3849
+ componentId,
3850
+ propOverrides
3851
+ }) {
3852
+ const previewTokens = components.useTokens();
3853
+ return /* @__PURE__ */ jsxRuntime.jsx(
3854
+ "div",
3855
+ {
3856
+ style: {
3857
+ display: "flex",
3858
+ alignItems: "center",
3859
+ justifyContent: "center",
3860
+ padding: 24,
3861
+ height: 120,
3862
+ backgroundColor: newtone.srgbToHex(previewTokens.backgroundElevated.srgb)
3863
+ },
3864
+ children: /* @__PURE__ */ jsxRuntime.jsx(ComponentRenderer, { componentId, props: propOverrides })
3865
+ }
3866
+ );
3867
+ }
3655
3868
  function PropControl({
3656
3869
  prop,
3657
3870
  value,
@@ -3679,41 +3892,17 @@ function PropControl({
3679
3892
  boxSizing: "border-box"
3680
3893
  };
3681
3894
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3682
- /* @__PURE__ */ jsxRuntime.jsxs(
3683
- "div",
3895
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { marginBottom: 4 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3896
+ "span",
3684
3897
  {
3685
3898
  style: {
3686
- display: "flex",
3687
- alignItems: "center",
3688
- justifyContent: "space-between",
3689
- marginBottom: 4
3899
+ fontSize: 12,
3900
+ fontWeight: 500,
3901
+ color: newtone.srgbToHex(tokens.textPrimary.srgb)
3690
3902
  },
3691
- children: [
3692
- /* @__PURE__ */ jsxRuntime.jsx(
3693
- "span",
3694
- {
3695
- style: {
3696
- fontSize: 12,
3697
- fontWeight: 500,
3698
- color: newtone.srgbToHex(tokens.textPrimary.srgb)
3699
- },
3700
- children: prop.label
3701
- }
3702
- ),
3703
- /* @__PURE__ */ jsxRuntime.jsx(
3704
- "span",
3705
- {
3706
- style: {
3707
- fontSize: 11,
3708
- color: newtone.srgbToHex(tokens.textSecondary.srgb),
3709
- fontFamily: "'SF Mono', 'Fira Code', Menlo, monospace"
3710
- },
3711
- children: prop.control
3712
- }
3713
- )
3714
- ]
3903
+ children: prop.label
3715
3904
  }
3716
- ),
3905
+ ) }),
3717
3906
  prop.control === "select" && prop.options && /* @__PURE__ */ jsxRuntime.jsx(
3718
3907
  components.Select,
3719
3908
  {
@@ -3747,7 +3936,54 @@ function PropControl({
3747
3936
  style: inputStyle
3748
3937
  }
3749
3938
  ),
3750
- prop.control === "toggle" && /* @__PURE__ */ jsxRuntime.jsxs(
3939
+ prop.control === "discrete-slider" && prop.options && (() => {
3940
+ const options = prop.options;
3941
+ const currentIndex = options.findIndex((o) => o.value === value);
3942
+ const idx = currentIndex >= 0 ? currentIndex : 0;
3943
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3944
+ /* @__PURE__ */ jsxRuntime.jsx(
3945
+ "input",
3946
+ {
3947
+ type: "range",
3948
+ min: 0,
3949
+ max: options.length - 1,
3950
+ step: 1,
3951
+ value: idx,
3952
+ onChange: (e) => onChange(options[Number(e.target.value)].value),
3953
+ "aria-label": prop.label,
3954
+ style: {
3955
+ width: "100%",
3956
+ accentColor: newtone.srgbToHex(tokens.accent.fill.srgb),
3957
+ cursor: "pointer"
3958
+ }
3959
+ }
3960
+ ),
3961
+ /* @__PURE__ */ jsxRuntime.jsx(
3962
+ "div",
3963
+ {
3964
+ style: {
3965
+ display: "flex",
3966
+ justifyContent: "space-between",
3967
+ marginTop: 2
3968
+ },
3969
+ children: options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(
3970
+ "span",
3971
+ {
3972
+ style: {
3973
+ fontSize: 11,
3974
+ fontFamily: "'SF Mono', 'Fira Code', Menlo, monospace",
3975
+ color: o.value === value ? newtone.srgbToHex(tokens.textPrimary.srgb) : newtone.srgbToHex(tokens.textTertiary.srgb),
3976
+ fontWeight: o.value === value ? 600 : 400
3977
+ },
3978
+ children: o.label
3979
+ },
3980
+ String(o.value)
3981
+ ))
3982
+ }
3983
+ )
3984
+ ] });
3985
+ })(),
3986
+ prop.control === "toggle" && /* @__PURE__ */ jsxRuntime.jsx(
3751
3987
  "div",
3752
3988
  {
3753
3989
  role: "switch",
@@ -3762,47 +3998,35 @@ function PropControl({
3762
3998
  gap: 8,
3763
3999
  cursor: "pointer"
3764
4000
  },
3765
- children: [
3766
- /* @__PURE__ */ jsxRuntime.jsx(
3767
- "div",
3768
- {
3769
- style: {
3770
- width: 36,
3771
- height: 20,
3772
- borderRadius: 10,
3773
- backgroundColor: value ? newtone.srgbToHex(tokens.accent.fill.srgb) : newtone.srgbToHex(tokens.border.srgb),
3774
- position: "relative",
3775
- transition: "background-color 150ms ease",
3776
- flexShrink: 0
3777
- },
3778
- children: /* @__PURE__ */ jsxRuntime.jsx(
3779
- "div",
3780
- {
3781
- style: {
3782
- width: 16,
3783
- height: 16,
3784
- borderRadius: 8,
3785
- backgroundColor: "#fff",
3786
- position: "absolute",
3787
- top: 2,
3788
- left: value ? 18 : 2,
3789
- transition: "left 150ms ease"
3790
- }
4001
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4002
+ "div",
4003
+ {
4004
+ style: {
4005
+ width: 36,
4006
+ height: 20,
4007
+ borderRadius: 10,
4008
+ backgroundColor: value ? newtone.srgbToHex(tokens.accent.fill.srgb) : newtone.srgbToHex(tokens.border.srgb),
4009
+ position: "relative",
4010
+ transition: "background-color 150ms ease",
4011
+ flexShrink: 0
4012
+ },
4013
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4014
+ "div",
4015
+ {
4016
+ style: {
4017
+ width: 16,
4018
+ height: 16,
4019
+ borderRadius: 8,
4020
+ backgroundColor: "#fff",
4021
+ position: "absolute",
4022
+ top: 2,
4023
+ left: value ? 18 : 2,
4024
+ transition: "left 150ms ease"
3791
4025
  }
3792
- )
3793
- }
3794
- ),
3795
- /* @__PURE__ */ jsxRuntime.jsx(
3796
- "span",
3797
- {
3798
- style: {
3799
- fontSize: 12,
3800
- color: newtone.srgbToHex(tokens.textSecondary.srgb)
3801
- },
3802
- children: value ? "true" : "false"
3803
- }
3804
- )
3805
- ]
4026
+ }
4027
+ )
4028
+ }
4029
+ )
3806
4030
  }
3807
4031
  )
3808
4032
  ] });
@@ -3907,9 +4131,10 @@ function Editor({
3907
4131
  {
3908
4132
  view: editor.previewView,
3909
4133
  selectedVariantId: editor.selectedVariantId,
3910
- propOverrides: editor.propOverrides,
3911
4134
  onNavigate: editor.handlePreviewNavigate,
3912
- onSelectVariant: editor.handleSelectVariant
4135
+ onSelectVariant: editor.handleSelectVariant,
4136
+ propOverrides: editor.propOverrides,
4137
+ onPropOverride: editor.handlePropOverride
3913
4138
  }
3914
4139
  ) })
3915
4140
  },
@@ -3928,7 +4153,9 @@ function Editor({
3928
4153
  onPropOverride: editor.handlePropOverride,
3929
4154
  onResetOverrides: editor.handleResetOverrides,
3930
4155
  onClose: editor.handleCloseSidebar,
3931
- onScopeToComponent: editor.handleScopeToComponent
4156
+ onScopeToComponent: editor.handleScopeToComponent,
4157
+ previewConfig,
4158
+ colorMode: editor.colorMode
3932
4159
  }
3933
4160
  )
3934
4161
  }