canvas-ui-sdk 0.2.0 → 0.3.0

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.d.ts CHANGED
@@ -4670,6 +4670,8 @@ interface ThemeContextValue {
4670
4670
  interface PreviewBrandingContextValue {
4671
4671
  previewBranding: ThemeBranding | null;
4672
4672
  setPreviewBranding: (branding: ThemeBranding | null) => void;
4673
+ previewImages: ThemeImages | null;
4674
+ setPreviewImages: (images: ThemeImages | null) => void;
4673
4675
  }
4674
4676
  declare const ThemeContext: React$1.Context<ThemeContextValue>;
4675
4677
  declare const PreviewBrandingContext: React$1.Context<PreviewBrandingContextValue>;
@@ -4722,6 +4724,8 @@ interface ThemeState {
4722
4724
  exportCSS: () => string;
4723
4725
  exportJSON: () => string;
4724
4726
  importJSON: (json: string) => boolean;
4727
+ save: () => void;
4728
+ discard: () => void;
4725
4729
  branding: BrandingState;
4726
4730
  setBranding: (updates: Partial<BrandingState>) => void;
4727
4731
  images: Record<ImageKey, string>;
package/dist/index.js CHANGED
@@ -3468,10 +3468,15 @@ var ThemeContext = createContext({
3468
3468
  var PreviewBrandingContext = createContext({
3469
3469
  previewBranding: null,
3470
3470
  setPreviewBranding: () => {
3471
+ },
3472
+ previewImages: null,
3473
+ setPreviewImages: () => {
3471
3474
  }
3472
3475
  });
3473
3476
  function useThemeImages() {
3474
- return useContext(ThemeContext).images;
3477
+ const { images } = useContext(ThemeContext);
3478
+ const { previewImages } = useContext(PreviewBrandingContext);
3479
+ return previewImages ?? images;
3475
3480
  }
3476
3481
  function useThemeBranding() {
3477
3482
  const { branding, isMounted } = useContext(ThemeContext);
@@ -3491,6 +3496,7 @@ function ThemeProvider({
3491
3496
  brandAssets = []
3492
3497
  }) {
3493
3498
  const [previewBranding, setPreviewBranding] = useState(null);
3499
+ const [previewImages, setPreviewImages] = useState(null);
3494
3500
  const contextValue = {
3495
3501
  images,
3496
3502
  branding,
@@ -3499,7 +3505,9 @@ function ThemeProvider({
3499
3505
  };
3500
3506
  const previewBrandingValue = {
3501
3507
  previewBranding,
3502
- setPreviewBranding
3508
+ setPreviewBranding,
3509
+ previewImages,
3510
+ setPreviewImages
3503
3511
  };
3504
3512
  return /* @__PURE__ */ jsx(ThemeContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsx(PreviewBrandingContext.Provider, { value: previewBrandingValue, children }) });
3505
3513
  }
@@ -24267,6 +24275,24 @@ var brandColorVars = [
24267
24275
  "--canvas-sidebar-dark-border",
24268
24276
  "--canvas-border-input-focus"
24269
24277
  ];
24278
+ function isEqual(a, b) {
24279
+ if (a === b) return true;
24280
+ if (a == null || b == null) return false;
24281
+ if (typeof a !== typeof b) return false;
24282
+ if (Array.isArray(a) && Array.isArray(b)) {
24283
+ if (a.length !== b.length) return false;
24284
+ return a.every((v, i) => isEqual(v, b[i]));
24285
+ }
24286
+ if (typeof a === "object" && typeof b === "object") {
24287
+ const aObj = a;
24288
+ const bObj = b;
24289
+ const aKeys = Object.keys(aObj);
24290
+ const bKeys = Object.keys(bObj);
24291
+ if (aKeys.length !== bKeys.length) return false;
24292
+ return aKeys.every((k) => isEqual(aObj[k], bObj[k]));
24293
+ }
24294
+ return false;
24295
+ }
24270
24296
  function useThemeState(options) {
24271
24297
  const {
24272
24298
  storageKey = "canvas-ui-theme",
@@ -24275,6 +24301,14 @@ function useThemeState(options) {
24275
24301
  onBrandingChange,
24276
24302
  onImagesChange
24277
24303
  } = options ?? {};
24304
+ const [savedOverrides, setSavedOverrides] = useState(() => {
24305
+ return initialOverrides ?? {};
24306
+ });
24307
+ const [savedBranding, setSavedBranding] = useState({ ...defaultBranding });
24308
+ const [savedImages, setSavedImages] = useState({ ...defaultImages });
24309
+ const [savedCustomButtonStyles, setSavedCustomButtonStyles] = useState([
24310
+ ...defaultCustomButtonStyles
24311
+ ]);
24278
24312
  const [overrides, setOverrides] = useState(() => {
24279
24313
  return initialOverrides ?? {};
24280
24314
  });
@@ -24292,7 +24326,7 @@ function useThemeState(options) {
24292
24326
  onBrandingChangeRef.current = onBrandingChange;
24293
24327
  const onImagesChangeRef = useRef(onImagesChange);
24294
24328
  onImagesChangeRef.current = onImagesChange;
24295
- const persistState = useCallback(
24329
+ const persistToStorage = useCallback(
24296
24330
  (ovr, brd, img, cbs) => {
24297
24331
  try {
24298
24332
  localStorage.setItem(
@@ -24311,16 +24345,20 @@ function useThemeState(options) {
24311
24345
  const parsed = importJSON(stored);
24312
24346
  if (parsed) {
24313
24347
  if (parsed.overrides) {
24348
+ setSavedOverrides(parsed.overrides);
24314
24349
  setOverrides(parsed.overrides);
24315
24350
  setCSSVariables(parsed.overrides);
24316
24351
  }
24317
24352
  if (parsed.branding) {
24353
+ setSavedBranding(parsed.branding);
24318
24354
  setBrandingState(parsed.branding);
24319
24355
  }
24320
24356
  if (parsed.images) {
24357
+ setSavedImages(parsed.images);
24321
24358
  setImagesState(parsed.images);
24322
24359
  }
24323
24360
  if (parsed.customButtonStyles) {
24361
+ setSavedCustomButtonStyles(parsed.customButtonStyles);
24324
24362
  setCustomButtonStyles(parsed.customButtonStyles);
24325
24363
  }
24326
24364
  if (parsed.overrides?.["--canvas-primary"]) {
@@ -24338,13 +24376,12 @@ function useThemeState(options) {
24338
24376
  (name, value) => {
24339
24377
  setOverrides((prev) => {
24340
24378
  const next = { ...prev, [name]: value };
24341
- persistState(next, void 0, void 0, void 0);
24342
24379
  setCSSVariables({ [name]: value });
24343
24380
  onThemeChangeRef.current?.(next);
24344
24381
  return next;
24345
24382
  });
24346
24383
  },
24347
- [persistState]
24384
+ []
24348
24385
  );
24349
24386
  const resetCategory = useCallback(
24350
24387
  (prefix) => {
@@ -24360,7 +24397,6 @@ function useThemeState(options) {
24360
24397
  next[key] = value;
24361
24398
  }
24362
24399
  }
24363
- persistState(next);
24364
24400
  const fontVarsToRemove = FONT_VARS.filter((v) => v.startsWith(prefix));
24365
24401
  if (fontVarsToRemove.length > 0) {
24366
24402
  removeCSSVariables(fontVarsToRemove);
@@ -24372,8 +24408,54 @@ function useThemeState(options) {
24372
24408
  return next;
24373
24409
  });
24374
24410
  },
24375
- [persistState]
24411
+ []
24376
24412
  );
24413
+ const save = useCallback(() => {
24414
+ setOverrides((currentOverrides) => {
24415
+ setBrandingState((currentBranding) => {
24416
+ setImagesState((currentImages) => {
24417
+ setCustomButtonStyles((currentCbs) => {
24418
+ setSavedOverrides(currentOverrides);
24419
+ setSavedBranding(currentBranding);
24420
+ setSavedImages(currentImages);
24421
+ setSavedCustomButtonStyles(currentCbs);
24422
+ persistToStorage(currentOverrides, currentBranding, currentImages, currentCbs);
24423
+ return currentCbs;
24424
+ });
24425
+ return currentImages;
24426
+ });
24427
+ return currentBranding;
24428
+ });
24429
+ return currentOverrides;
24430
+ });
24431
+ }, [persistToStorage]);
24432
+ const discard = useCallback(() => {
24433
+ setSavedOverrides((currentSaved) => {
24434
+ setOverrides(currentSaved);
24435
+ removeCSSVariables(FONT_VARS);
24436
+ setCSSVariables({ ...allDefaults, ...currentSaved });
24437
+ onThemeChangeRef.current?.(currentSaved);
24438
+ if (currentSaved["--canvas-primary"]) {
24439
+ const hsl = hexToHsl2(currentSaved["--canvas-primary"]);
24440
+ setBrandHueState(hsl.h);
24441
+ }
24442
+ return currentSaved;
24443
+ });
24444
+ setSavedBranding((currentSaved) => {
24445
+ setBrandingState(currentSaved);
24446
+ onBrandingChangeRef.current?.(currentSaved);
24447
+ return currentSaved;
24448
+ });
24449
+ setSavedImages((currentSaved) => {
24450
+ setImagesState(currentSaved);
24451
+ onImagesChangeRef.current?.(currentSaved);
24452
+ return currentSaved;
24453
+ });
24454
+ setSavedCustomButtonStyles((currentSaved) => {
24455
+ setCustomButtonStyles(currentSaved);
24456
+ return currentSaved;
24457
+ });
24458
+ }, []);
24377
24459
  const resetAll = useCallback(() => {
24378
24460
  setOverrides({});
24379
24461
  setBrandingState({ ...defaultBranding });
@@ -24381,6 +24463,10 @@ function useThemeState(options) {
24381
24463
  setCustomButtonStyles([...defaultCustomButtonStyles]);
24382
24464
  setBrandHueState(217);
24383
24465
  setBrandVibrancyState(1);
24466
+ setSavedOverrides({});
24467
+ setSavedBranding({ ...defaultBranding });
24468
+ setSavedImages({ ...defaultImages });
24469
+ setSavedCustomButtonStyles([...defaultCustomButtonStyles]);
24384
24470
  try {
24385
24471
  localStorage.removeItem(storageKey);
24386
24472
  } catch {
@@ -24398,60 +24484,47 @@ function useThemeState(options) {
24398
24484
  if (parsed.branding) setBrandingState(parsed.branding);
24399
24485
  if (parsed.images) setImagesState(parsed.images);
24400
24486
  if (parsed.customButtonStyles) setCustomButtonStyles(parsed.customButtonStyles);
24401
- persistState(ovr, parsed.branding, parsed.images, parsed.customButtonStyles);
24402
24487
  removeCSSVariables(FONT_VARS);
24403
24488
  setCSSVariables({ ...allDefaults, ...ovr });
24404
24489
  onThemeChangeRef.current?.(ovr);
24405
24490
  return true;
24406
24491
  },
24407
- [persistState]
24492
+ []
24408
24493
  );
24409
24494
  const setBranding = useCallback(
24410
24495
  (updates) => {
24411
24496
  setBrandingState((prev) => {
24412
24497
  const next = { ...prev, ...updates };
24413
- setOverrides((ovr) => {
24414
- persistState(ovr, next);
24415
- return ovr;
24416
- });
24417
24498
  onBrandingChangeRef.current?.(next);
24418
24499
  return next;
24419
24500
  });
24420
24501
  },
24421
- [persistState]
24502
+ []
24422
24503
  );
24423
24504
  const setImage = useCallback(
24424
24505
  (key, url) => {
24425
24506
  setImagesState((prev) => {
24426
24507
  const next = { ...prev, [key]: url };
24427
- setOverrides((ovr) => {
24428
- persistState(ovr, void 0, next);
24429
- return ovr;
24430
- });
24431
24508
  onImagesChangeRef.current?.(next);
24432
24509
  return next;
24433
24510
  });
24434
24511
  },
24435
- [persistState]
24512
+ []
24436
24513
  );
24437
24514
  const deleteImage = useCallback(
24438
24515
  (key) => {
24439
24516
  setImagesState((prev) => {
24440
24517
  const next = { ...prev, [key]: "" };
24441
- setOverrides((ovr) => {
24442
- persistState(ovr, void 0, next);
24443
- return ovr;
24444
- });
24445
24518
  onImagesChangeRef.current?.(next);
24446
24519
  return next;
24447
24520
  });
24448
24521
  },
24449
- [persistState]
24522
+ []
24450
24523
  );
24451
24524
  const addCustomButtonStyle = useCallback(() => {
24452
24525
  setCustomButtonStyles((prev) => {
24453
24526
  const id = `custom-${Date.now()}`;
24454
- const next = [
24527
+ return [
24455
24528
  ...prev,
24456
24529
  {
24457
24530
  id,
@@ -24465,38 +24538,21 @@ function useThemeState(options) {
24465
24538
  borderHover: "var(--canvas-primary-dark)"
24466
24539
  }
24467
24540
  ];
24468
- setOverrides((ovr) => {
24469
- persistState(ovr, void 0, void 0, next);
24470
- return ovr;
24471
- });
24472
- return next;
24473
24541
  });
24474
- }, [persistState]);
24542
+ }, []);
24475
24543
  const updateCustomButtonStyle = useCallback(
24476
24544
  (id, updates) => {
24477
- setCustomButtonStyles((prev) => {
24478
- const next = prev.map((s) => s.id === id ? { ...s, ...updates } : s);
24479
- setOverrides((ovr) => {
24480
- persistState(ovr, void 0, void 0, next);
24481
- return ovr;
24482
- });
24483
- return next;
24484
- });
24545
+ setCustomButtonStyles(
24546
+ (prev) => prev.map((s) => s.id === id ? { ...s, ...updates } : s)
24547
+ );
24485
24548
  },
24486
- [persistState]
24549
+ []
24487
24550
  );
24488
24551
  const deleteCustomButtonStyle = useCallback(
24489
24552
  (id) => {
24490
- setCustomButtonStyles((prev) => {
24491
- const next = prev.filter((s) => s.id !== id);
24492
- setOverrides((ovr) => {
24493
- persistState(ovr, void 0, void 0, next);
24494
- return ovr;
24495
- });
24496
- return next;
24497
- });
24553
+ setCustomButtonStyles((prev) => prev.filter((s) => s.id !== id));
24498
24554
  },
24499
- [persistState]
24555
+ []
24500
24556
  );
24501
24557
  const applyBrandHueVibrancy = useCallback(
24502
24558
  (hue, vibrancy, skipPrimary = false) => {
@@ -24539,12 +24595,11 @@ function useThemeState(options) {
24539
24595
  document.documentElement.style.setProperty(varName, newHex);
24540
24596
  });
24541
24597
  const next = { ...prev, ...newValues };
24542
- persistState(next);
24543
24598
  onThemeChangeRef.current?.(next);
24544
24599
  return next;
24545
24600
  });
24546
24601
  },
24547
- [persistState]
24602
+ []
24548
24603
  );
24549
24604
  const setBrandHue = useCallback(
24550
24605
  (hue) => {
@@ -24565,11 +24620,24 @@ function useThemeState(options) {
24565
24620
  []
24566
24621
  );
24567
24622
  const variables = useMemo(() => ({ ...allDefaults, ...overrides }), [overrides]);
24568
- const unsavedChangesCount = Object.keys(overrides).length;
24623
+ const isDirty = useMemo(() => {
24624
+ return !isEqual(overrides, savedOverrides) || !isEqual(branding, savedBranding) || !isEqual(images, savedImages) || !isEqual(customButtonStyles, savedCustomButtonStyles);
24625
+ }, [overrides, savedOverrides, branding, savedBranding, images, savedImages, customButtonStyles, savedCustomButtonStyles]);
24626
+ const unsavedChangesCount = useMemo(() => {
24627
+ let count = 0;
24628
+ const allKeys = /* @__PURE__ */ new Set([...Object.keys(overrides), ...Object.keys(savedOverrides)]);
24629
+ for (const key of allKeys) {
24630
+ if (overrides[key] !== savedOverrides[key]) count++;
24631
+ }
24632
+ if (!isEqual(branding, savedBranding)) count++;
24633
+ if (!isEqual(images, savedImages)) count++;
24634
+ if (!isEqual(customButtonStyles, savedCustomButtonStyles)) count++;
24635
+ return count;
24636
+ }, [overrides, savedOverrides, branding, savedBranding, images, savedImages, customButtonStyles, savedCustomButtonStyles]);
24569
24637
  return {
24570
24638
  variables,
24571
24639
  overrides,
24572
- isDirty: unsavedChangesCount > 0,
24640
+ isDirty,
24573
24641
  unsavedChangesCount,
24574
24642
  setVariable,
24575
24643
  resetCategory,
@@ -24577,6 +24645,8 @@ function useThemeState(options) {
24577
24645
  exportCSS: () => exportCSS(overrides),
24578
24646
  exportJSON: () => exportJSON(overrides, branding, images, customButtonStyles),
24579
24647
  importJSON: handleImportJSON,
24648
+ save,
24649
+ discard,
24580
24650
  branding,
24581
24651
  setBranding,
24582
24652
  images,
@@ -27441,8 +27511,8 @@ var drawerStyles = {
27441
27511
  }),
27442
27512
  footer: {
27443
27513
  display: "flex",
27444
- justifyContent: "center",
27445
- alignItems: "center",
27514
+ flexDirection: "column",
27515
+ gap: "8px",
27446
27516
  padding: "12px 16px",
27447
27517
  borderTop: "1px solid #e5e7eb",
27448
27518
  flexShrink: 0,
@@ -27498,11 +27568,45 @@ function ThemeDrawer({
27498
27568
  onBrandingChange,
27499
27569
  onImagesChange
27500
27570
  });
27501
- const activePanels = enabledPanels ? panelConfig.filter((p) => enabledPanels.includes(p.id)) : panelConfig;
27502
- const handleReset = () => {
27571
+ const { setPreviewBranding, setPreviewImages } = usePreviewBranding();
27572
+ useEffect(() => {
27573
+ if (open) {
27574
+ setPreviewBranding(theme.branding);
27575
+ }
27576
+ }, [open, theme.branding, setPreviewBranding]);
27577
+ useEffect(() => {
27578
+ if (open) {
27579
+ setPreviewImages(theme.images);
27580
+ }
27581
+ }, [open, theme.images, setPreviewImages]);
27582
+ const handleOpenChange = useCallback(
27583
+ (newOpen) => {
27584
+ if (!newOpen) {
27585
+ if (theme.isDirty) {
27586
+ theme.discard();
27587
+ }
27588
+ setPreviewBranding(null);
27589
+ setPreviewImages(null);
27590
+ setResetConfirmOpen(false);
27591
+ }
27592
+ setOpen(newOpen);
27593
+ },
27594
+ [theme, setPreviewBranding, setPreviewImages]
27595
+ );
27596
+ const handleSave = useCallback(() => {
27597
+ theme.save();
27598
+ }, [theme]);
27599
+ const handleDiscard = useCallback(() => {
27600
+ theme.discard();
27601
+ }, [theme]);
27602
+ const handleReset = useCallback(() => {
27503
27603
  theme.resetAll();
27604
+ setPreviewBranding(null);
27605
+ setPreviewImages(null);
27504
27606
  setResetConfirmOpen(false);
27505
- };
27607
+ }, [theme, setPreviewBranding, setPreviewImages]);
27608
+ const activePanels = enabledPanels ? panelConfig.filter((p) => enabledPanels.includes(p.id)) : panelConfig;
27609
+ const showFooter = theme.isDirty || resetConfirmOpen;
27506
27610
  return /* @__PURE__ */ jsxs(Fragment, { children: [
27507
27611
  !open && /* @__PURE__ */ jsx(
27508
27612
  "button",
@@ -27521,7 +27625,7 @@ function ThemeDrawer({
27521
27625
  children: /* @__PURE__ */ jsx(PaletteIcon6, {})
27522
27626
  }
27523
27627
  ),
27524
- /* @__PURE__ */ jsx(Sheet, { open, onOpenChange: setOpen, children: /* @__PURE__ */ jsxs(
27628
+ /* @__PURE__ */ jsx(Sheet, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs(
27525
27629
  SheetContent,
27526
27630
  {
27527
27631
  side: "right",
@@ -27564,7 +27668,7 @@ function ThemeDrawer({
27564
27668
  marginTop: "2px",
27565
27669
  fontFamily: drawerStyles.container.fontFamily
27566
27670
  },
27567
- children: theme.unsavedChangesCount > 0 ? `${theme.unsavedChangesCount} unsaved modification${theme.unsavedChangesCount !== 1 ? "s" : ""}` : "Customize your design system"
27671
+ children: theme.unsavedChangesCount > 0 ? `${theme.unsavedChangesCount} unsaved change${theme.unsavedChangesCount !== 1 ? "s" : ""}` : "Customize your design system"
27568
27672
  }
27569
27673
  )
27570
27674
  ] })
@@ -27583,7 +27687,7 @@ function ThemeDrawer({
27583
27687
  ScrollArea,
27584
27688
  {
27585
27689
  className: "flex-1 overflow-hidden",
27586
- style: { height: `calc(100vh - ${theme.isDirty ? 200 : 150}px)` },
27690
+ style: { height: `calc(100vh - ${showFooter ? 200 : 150}px)` },
27587
27691
  children: /* @__PURE__ */ jsxs("div", { style: drawerStyles.container, children: [
27588
27692
  activeTab === "colors" && /* @__PURE__ */ jsx(ColorsPanel, { theme }),
27589
27693
  activeTab === "images" && /* @__PURE__ */ jsx(ImagesPanel, { theme, onImageUpload }),
@@ -27594,7 +27698,7 @@ function ThemeDrawer({
27594
27698
  ] })
27595
27699
  }
27596
27700
  ),
27597
- theme.isDirty && /* @__PURE__ */ jsx("div", { style: drawerStyles.footer, children: resetConfirmOpen ? /* @__PURE__ */ jsxs(
27701
+ showFooter && /* @__PURE__ */ jsx("div", { style: drawerStyles.footer, children: resetConfirmOpen ? /* @__PURE__ */ jsxs(
27598
27702
  "div",
27599
27703
  {
27600
27704
  style: {
@@ -27663,24 +27767,75 @@ function ThemeDrawer({
27663
27767
  )
27664
27768
  ]
27665
27769
  }
27666
- ) : /* @__PURE__ */ jsx(
27667
- "button",
27668
- {
27669
- onClick: () => setResetConfirmOpen(true),
27670
- style: {
27671
- fontSize: "13px",
27672
- fontWeight: 500,
27673
- color: "#dc2626",
27674
- background: "none",
27675
- border: "1px solid #fca5a5",
27676
- cursor: "pointer",
27677
- padding: "8px 16px",
27678
- borderRadius: "6px",
27679
- width: "100%"
27680
- },
27681
- children: "Reset All to Defaults"
27682
- }
27683
- ) })
27770
+ ) : /* @__PURE__ */ jsxs(Fragment, { children: [
27771
+ /* @__PURE__ */ jsxs(
27772
+ "div",
27773
+ {
27774
+ style: {
27775
+ display: "flex",
27776
+ gap: "8px",
27777
+ width: "100%"
27778
+ },
27779
+ children: [
27780
+ /* @__PURE__ */ jsx(
27781
+ "button",
27782
+ {
27783
+ onClick: handleDiscard,
27784
+ style: {
27785
+ flex: 1,
27786
+ fontSize: "13px",
27787
+ fontWeight: 500,
27788
+ color: "#374151",
27789
+ background: "#ffffff",
27790
+ border: "1px solid #e5e7eb",
27791
+ cursor: "pointer",
27792
+ padding: "8px 16px",
27793
+ borderRadius: "6px"
27794
+ },
27795
+ children: "Discard"
27796
+ }
27797
+ ),
27798
+ /* @__PURE__ */ jsx(
27799
+ "button",
27800
+ {
27801
+ onClick: handleSave,
27802
+ style: {
27803
+ flex: 1,
27804
+ fontSize: "13px",
27805
+ fontWeight: 600,
27806
+ color: "#ffffff",
27807
+ background: "#1f2937",
27808
+ border: "1px solid #1f2937",
27809
+ cursor: "pointer",
27810
+ padding: "8px 16px",
27811
+ borderRadius: "6px"
27812
+ },
27813
+ children: "Save"
27814
+ }
27815
+ )
27816
+ ]
27817
+ }
27818
+ ),
27819
+ /* @__PURE__ */ jsx(
27820
+ "button",
27821
+ {
27822
+ onClick: () => setResetConfirmOpen(true),
27823
+ style: {
27824
+ fontSize: "12px",
27825
+ fontWeight: 400,
27826
+ color: "#9ca3af",
27827
+ background: "none",
27828
+ border: "none",
27829
+ cursor: "pointer",
27830
+ padding: "2px 0",
27831
+ textAlign: "center",
27832
+ textDecoration: "underline",
27833
+ textUnderlineOffset: "2px"
27834
+ },
27835
+ children: "Reset all to defaults"
27836
+ }
27837
+ )
27838
+ ] }) })
27684
27839
  ]
27685
27840
  }
27686
27841
  ) })