@solo-io-public/ui-components 0.0.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.
Files changed (77) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +167 -0
  3. package/dist/Button.style-CCplEN2o.js +474 -0
  4. package/dist/Button.style-CCplEN2o.js.map +1 -0
  5. package/dist/Button.style-CI6Xbod7.cjs +10 -0
  6. package/dist/Button.style-CI6Xbod7.cjs.map +1 -0
  7. package/dist/_internal/Svg.d.ts +15 -0
  8. package/dist/_internal/colors.d.ts +17 -0
  9. package/dist/_internal/gradients.d.ts +11 -0
  10. package/dist/_internal/hexAddAlpha.d.ts +3 -0
  11. package/dist/_internal/palette.d.ts +30 -0
  12. package/dist/_internal/sizing.d.ts +14 -0
  13. package/dist/_internal/unstyledButton.d.ts +8 -0
  14. package/dist/_internal/utils.d.ts +7 -0
  15. package/dist/components/Alert/Alert.d.ts +17 -0
  16. package/dist/components/Alert/index.d.ts +1 -0
  17. package/dist/components/Button/Button.d.ts +32 -0
  18. package/dist/components/Button/Button.style.d.ts +48 -0
  19. package/dist/components/Button/index.d.ts +1 -0
  20. package/dist/components/CloseButton/CloseButton.d.ts +14 -0
  21. package/dist/components/CloseButton/index.d.ts +1 -0
  22. package/dist/components/Layout/FlexLayout.d.ts +83 -0
  23. package/dist/components/Layout/Spacer.d.ts +80 -0
  24. package/dist/components/Layout/index.d.ts +2 -0
  25. package/dist/components/MonacoEditor/EditorSettingsContext.d.ts +15 -0
  26. package/dist/components/MonacoEditor/MonacoEditorWithSettings.d.ts +20 -0
  27. package/dist/components/MonacoEditor/index.d.ts +2 -0
  28. package/dist/components/Text/Text.d.ts +71 -0
  29. package/dist/components/Text/index.d.ts +1 -0
  30. package/dist/index.d.ts +7 -0
  31. package/dist/providers/SoloContextProvider.d.ts +62 -0
  32. package/dist/providers/SoloModeContext.d.ts +5 -0
  33. package/dist/providers/index.d.ts +2 -0
  34. package/dist/solo-components.cjs +56 -0
  35. package/dist/solo-components.cjs.map +1 -0
  36. package/dist/solo-components.js +664 -0
  37. package/dist/solo-components.js.map +1 -0
  38. package/dist/styles.cjs +2 -0
  39. package/dist/styles.cjs.map +1 -0
  40. package/dist/styles.d.ts +1 -0
  41. package/dist/styles.js +5 -0
  42. package/dist/styles.js.map +1 -0
  43. package/package.json +109 -0
  44. package/src/_internal/Svg.tsx +58 -0
  45. package/src/_internal/colors.ts +26 -0
  46. package/src/_internal/gradients.ts +36 -0
  47. package/src/_internal/hexAddAlpha.ts +9 -0
  48. package/src/_internal/palette.ts +46 -0
  49. package/src/_internal/sizing.ts +15 -0
  50. package/src/_internal/unstyledButton.ts +17 -0
  51. package/src/_internal/utils.ts +11 -0
  52. package/src/components/Alert/Alert.stories.tsx +44 -0
  53. package/src/components/Alert/Alert.tsx +168 -0
  54. package/src/components/Alert/index.ts +1 -0
  55. package/src/components/Button/Button.stories.tsx +62 -0
  56. package/src/components/Button/Button.style.ts +158 -0
  57. package/src/components/Button/Button.test.tsx +47 -0
  58. package/src/components/Button/Button.tsx +84 -0
  59. package/src/components/Button/index.ts +11 -0
  60. package/src/components/CloseButton/CloseButton.tsx +76 -0
  61. package/src/components/CloseButton/index.ts +1 -0
  62. package/src/components/Layout/FlexLayout.tsx +101 -0
  63. package/src/components/Layout/Spacer.tsx +131 -0
  64. package/src/components/Layout/index.ts +2 -0
  65. package/src/components/MonacoEditor/EditorSettingsContext.test.tsx +55 -0
  66. package/src/components/MonacoEditor/EditorSettingsContext.tsx +63 -0
  67. package/src/components/MonacoEditor/MonacoEditor.stories.tsx +197 -0
  68. package/src/components/MonacoEditor/MonacoEditorWithSettings.tsx +376 -0
  69. package/src/components/MonacoEditor/index.ts +9 -0
  70. package/src/components/Text/Text.stories.tsx +63 -0
  71. package/src/components/Text/Text.tsx +65 -0
  72. package/src/components/Text/index.ts +1 -0
  73. package/src/index.ts +7 -0
  74. package/src/providers/SoloContextProvider.tsx +213 -0
  75. package/src/providers/SoloModeContext.tsx +13 -0
  76. package/src/providers/index.ts +10 -0
  77. package/src/styles.ts +5 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solo-components.cjs","sources":["../src/providers/SoloModeContext.tsx","../src/components/CloseButton/CloseButton.tsx","../src/components/Layout/Spacer.tsx","../src/components/Text/Text.tsx","../src/components/Alert/Alert.tsx","../src/_internal/Svg.tsx","../src/components/Button/Button.tsx","../src/components/Layout/FlexLayout.tsx","../src/components/MonacoEditor/EditorSettingsContext.tsx","../src/components/MonacoEditor/MonacoEditorWithSettings.tsx","../src/providers/SoloContextProvider.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nexport type SoloMode = 'light' | 'dark';\n\nconst SoloModeContext = createContext<SoloMode>('dark');\n\n/** Provides the active light/dark mode to descendants (e.g. the editor). */\nexport const SoloModeProvider = SoloModeContext.Provider;\n\n/** Read the active Solo color mode. Defaults to `'dark'` outside a provider. */\nexport function useSoloMode(): SoloMode {\n return useContext(SoloModeContext);\n}\n","import type { SerializedStyles } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport { X } from 'lucide-react';\nimport type { ButtonHTMLAttributes } from 'react';\nimport { dontForwardProps } from '../../_internal/utils';\n\n// region Styles\n\nconst StyledCloseButton = styled('button', dontForwardProps('styleOverrides'))<{ styleOverrides?: SerializedStyles }>`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n padding: 6px;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: inherit;\n opacity: 0.8;\n transition:\n background-color 0.08s ease,\n opacity 0.08s ease;\n\n &:hover {\n opacity: 1;\n /* Subtle wash derived from the button's own color, so it works on any background. */\n background-color: color-mix(in srgb, currentColor 14%, transparent);\n }\n\n &:active {\n background-color: color-mix(in srgb, currentColor 24%, transparent);\n }\n\n &:focus-visible {\n outline: 2px solid var(--color-primary, #6844ff);\n outline-offset: 2px;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n\n svg {\n display: block;\n }\n\n ${props => props.styleOverrides}\n`;\n\n// region Component\n\nexport interface CloseButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n /** X icon size in px. */\n size?: number;\n /** Emotion styles appended to the button. */\n styleOverrides?: SerializedStyles;\n}\n\n/**\n * A minimal \"×\" icon button (Lucide `X`). Inherits its color from context\n * (override via `style`/`styleOverrides`); hover/active washes derive from that\n * color, so it sits cleanly on any surface — alerts, drawers, modals, etc.\n */\nexport function CloseButton({\n size = 18,\n styleOverrides,\n type = 'button',\n 'aria-label': ariaLabel = 'Close',\n ...props\n}: CloseButtonProps) {\n return (\n <StyledCloseButton type={type} aria-label={ariaLabel} styleOverrides={styleOverrides} {...props}>\n <X size={size} />\n </StyledCloseButton>\n );\n}\n","import type { SerializedStyles } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport type { ComponentProps, CSSProperties } from 'react';\nimport { cssProp, dontForwardProps } from '../../_internal/utils';\n\n// region Helpers\n\ntype SizeType = number | string;\n\n// region Component\n\n/**\n * Margin/padding/sizing primitive. Use a string for exact values\n * (e.g. `mx='5px'`). Directional props (`mr`, `mb`, …) override the axis\n * shorthands (`mx`, `my`).\n */\nexport type SpacerProps = {\n mx?: string;\n my?: string;\n mr?: string;\n ml?: string;\n mt?: string;\n mb?: string;\n margin?: string;\n px?: string;\n py?: string;\n pr?: string;\n pl?: string;\n pt?: string;\n pb?: string;\n padding?: string;\n display?: CSSProperties['display'];\n position?: CSSProperties['position'];\n minHeight?: SizeType;\n minWidth?: CSSProperties['minWidth'];\n height?: SizeType;\n width?: SizeType;\n maxHeight?: CSSProperties['maxHeight'];\n maxWidth?: CSSProperties['maxWidth'];\n flexGrow?: CSSProperties['flexGrow'];\n flexBasis?: CSSProperties['flexBasis'];\n flexShrink?: CSSProperties['flexShrink'];\n overflowY?: CSSProperties['overflowY'];\n overflowX?: CSSProperties['overflowX'];\n textOverflow?: CSSProperties['textOverflow'];\n overflow?: CSSProperties['overflow'];\n zIndex?: CSSProperties['zIndex'];\n stylingOverrides?: SerializedStyles;\n fadeIn?: boolean;\n} & ComponentProps<'div'>;\n\nexport const Spacer = styled(\n 'div',\n dontForwardProps(\n 'mx',\n 'my',\n 'mr',\n 'ml',\n 'mt',\n 'mb',\n 'margin',\n 'px',\n 'py',\n 'pr',\n 'pl',\n 'pt',\n 'pb',\n 'padding',\n 'display',\n 'position',\n 'minHeight',\n 'minWidth',\n 'height',\n 'width',\n 'maxHeight',\n 'maxWidth',\n 'flexGrow',\n 'flexBasis',\n 'flexShrink',\n 'overflowY',\n 'overflowX',\n 'textOverflow',\n 'overflow',\n 'zIndex',\n 'stylingOverrides',\n 'fadeIn'\n )\n)<SpacerProps>(props => {\n const { mx, my, mr, ml, mt, mb, margin, px, py, pl, pr, pt, pb, padding } = props;\n const marginRight = mr ?? mx;\n const marginLeft = ml ?? mx;\n const marginTop = mt ?? my;\n const marginBottom = mb ?? my;\n const paddingRight = pr ?? px;\n const paddingLeft = pl ?? px;\n const paddingTop = pt ?? py;\n const paddingBottom = pb ?? py;\n return `\n ${cssProp('display', props.display)}\n ${cssProp('position', props.position)}\n ${cssProp('margin', margin)}\n ${cssProp('margin-right', marginRight)}\n ${cssProp('margin-left', marginLeft)}\n ${cssProp('margin-top', marginTop)}\n ${cssProp('margin-bottom', marginBottom)}\n ${cssProp('padding', padding)}\n ${cssProp('padding-right', paddingRight)}\n ${cssProp('padding-left', paddingLeft)}\n ${cssProp('padding-top', paddingTop)}\n ${cssProp('padding-bottom', paddingBottom)}\n ${cssProp('min-height', props.minHeight)}\n ${cssProp('min-width', props.minWidth)}\n ${cssProp('height', props.height)}\n ${cssProp('width', props.width)}\n ${cssProp('max-height', props.maxHeight)}\n ${cssProp('max-width', props.maxWidth)}\n ${cssProp('flex-grow', props.flexGrow)}\n ${cssProp('flex-shrink', props.flexShrink)}\n ${cssProp('flex-basis', props.flexBasis)}\n ${cssProp('overflow-y', props.overflowY)}\n ${cssProp('overflow-x', props.overflowX)}\n ${cssProp('overflow', props.overflow)}\n ${cssProp('text-overflow', props.textOverflow)}\n ${cssProp('z-index', props.zIndex)}\n\n animation: ${props.fadeIn ? `fadeIn 200ms cubic-bezier(0.22, 1, 0.36, 1) forwards` : 'none'};\n ${props.fadeIn ? `@media (prefers-reduced-motion: reduce) { animation: none; opacity: 1; }` : ''}\n\n ${props.stylingOverrides?.styles ? props.stylingOverrides.styles : ''}\n`;\n});\n","import styled from '@emotion/styled';\nimport type { CSSProperties } from 'react';\nimport { cssProp, dontForwardProps } from '../../_internal/utils';\nimport { Spacer, type SpacerProps } from '../Layout/Spacer';\n\n// region Helpers\n\nconst truncated = `\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n`;\n\n// region Component\n\n/**\n * Typography primitive built on `Spacer` (so margin/padding/sizing props work\n * too). Defaults to the theme's `--color-text-primary`, so text color follows\n * the active light/dark mode unless `color` is set explicitly.\n */\nexport type TextProps = SpacerProps & {\n size?: CSSProperties['fontSize'];\n weight?: CSSProperties['fontWeight'];\n lineHeight?: CSSProperties['lineHeight'];\n color?: CSSProperties['color'];\n textAlign?: CSSProperties['textAlign'];\n whiteSpace?: CSSProperties['whiteSpace'];\n truncate?: boolean;\n wordBreak?: CSSProperties['wordBreak'];\n textTransform?: CSSProperties['textTransform'];\n fontStyle?: CSSProperties['fontStyle'];\n inline?: boolean;\n};\n\nexport const Text = styled(\n Spacer,\n dontForwardProps(\n 'size',\n 'weight',\n 'lineHeight',\n 'color',\n 'textAlign',\n 'whiteSpace',\n 'truncate',\n 'wordBreak',\n 'textTransform',\n 'fontStyle',\n 'inline'\n )\n)<TextProps>(\n ({ size, weight, lineHeight, color, textAlign, whiteSpace, truncate, wordBreak, textTransform, fontStyle, inline, display }) => `\n font-family: var(--solo-font-family, inherit);\n color: ${color ?? 'var(--color-text-primary, #fafafa)'};\n ${cssProp('font-size', size)}\n ${cssProp('font-weight', weight)}\n ${cssProp('line-height', lineHeight)}\n ${cssProp('text-align', textAlign)}\n ${cssProp('white-space', whiteSpace)}\n ${cssProp('word-break', wordBreak)}\n ${cssProp('text-transform', textTransform)}\n ${cssProp('font-style', fontStyle)}\n ${cssProp('display', display ?? (inline ? 'inline' : 'block'))}\n ${truncate ? truncated : ''}\n `\n);\n","import styled from '@emotion/styled';\nimport { CircleCheck, Info, OctagonAlert, TriangleAlert, type LucideIcon } from 'lucide-react';\nimport { useState, type ReactNode } from 'react';\nimport { soloColorTokens, type SoloColorName } from '../../_internal/palette';\nimport { dontForwardProps } from '../../_internal/utils';\nimport { useSoloMode } from '../../providers/SoloModeContext';\nimport { CloseButton } from '../CloseButton';\nimport { Text } from '../Text';\n\n// region Styles\n\nconst Container = styled('div', dontForwardProps('background', 'frame', 'shadow'))<{\n background: string;\n frame: string;\n shadow: string;\n}>`\n display: flex;\n align-items: flex-start;\n gap: 12px;\n padding: 14px 16px;\n border-radius: 6px;\n border: 1px solid ${props => props.frame};\n background: ${props => props.background};\n box-shadow: ${props => props.shadow};\n`;\n\nconst IconSlot = styled('div', dontForwardProps('accent'))<{ accent: string }>`\n flex-shrink: 0;\n display: flex;\n margin-top: 1px;\n color: ${props => props.accent};\n\n svg {\n width: 18px;\n height: 18px;\n }\n`;\n\nconst Body = styled.div`\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n`;\n\n// region Component\n\nexport type AlertType = 'info' | 'success' | 'warning' | 'danger';\n\n// `darkAccent` is a neon-bright icon/outline for dark mode. `lightAccent` lets a\n// type swap its muted palette solid for a punchier hue in light mode (e.g. a\n// truer red / yellow); it falls back to the solid when omitted.\nconst typeConfig: Record<AlertType, { color: SoloColorName; Icon: LucideIcon; darkAccent: string; lightAccent?: string }> = {\n // Brand purple, matching the Button's `dark-purple`.\n info: { color: 'dark-purple', Icon: Info, darkAccent: '#b57bff', lightAccent: '#8134e2' },\n success: { color: 'success', Icon: CircleCheck, darkAccent: '#2fe07f', lightAccent: '#16a34a' },\n warning: { color: 'warning', Icon: TriangleAlert, darkAccent: '#ffb238', lightAccent: '#f7c52e' },\n danger: { color: 'red', Icon: OctagonAlert, darkAccent: '#ff6a6a', lightAccent: '#ef3030' }\n};\n\nexport interface AlertProps {\n type?: AlertType;\n title?: ReactNode;\n children?: ReactNode;\n /** Shows an X button in the upper-right that hides the alert. */\n isDismissable?: boolean;\n /** Called when the alert is dismissed (after it hides itself). */\n onDismiss?: () => void;\n}\n\n/**\n * Inline alert with a Lucide icon. Dark uses a neon accent — a bright outline +\n * icon with a glow — over a translucent fill; light uses a soft accent wash on\n * near-white. Pass `isDismissable` for an X button that closes it.\n */\nexport function Alert({ type = 'info', title, children, isDismissable = false, onDismiss }: AlertProps) {\n const { color, Icon, darkAccent, lightAccent } = typeConfig[type];\n const tokens = soloColorTokens[color];\n const mode = useSoloMode();\n const [dismissed, setDismissed] = useState(false);\n\n // Light mode can swap the muted solid for a punchier hue; dark keeps its neon.\n const lightBase = lightAccent ?? tokens.bg;\n const accent = mode === 'dark' ? darkAccent : lightBase;\n // Base color the fill + text tints are composed from.\n const tintBase = mode === 'dark' ? tokens.bg : lightBase;\n // Colored icon in light (keeps the hue, grounded for contrast); dark keeps the\n // neon accent. Warning's bright yellow is deepened more so it stays legible.\n const iconColor =\n mode === 'dark'\n ? accent\n : type === 'warning'\n ? `color-mix(in srgb, ${lightBase} 42%, #15151a)`\n : `color-mix(in srgb, ${lightBase} 60%, #1c1c22)`;\n // Light uses an accent-on-white border; dark keeps the neon edge. Warning's\n // pale-yellow border needs full strength to stay visible.\n const borderColor =\n mode === 'dark'\n ? accent\n : type === 'warning'\n ? lightBase\n : `color-mix(in srgb, ${lightBase} 60%, #ffffff)`;\n\n // Dark: a translucent accent-tinted fill so the page shows through. Light: a\n // medium accent tint on near-white.\n const opacity = mode === 'dark' ? 72 : 100;\n const fillPct = mode === 'dark' ? 28 : 20;\n const background = `color-mix(in srgb, color-mix(in srgb, ${tintBase} ${fillPct}%, var(--color-bg-elevated, #1e1e22)) ${opacity}%, transparent)`;\n\n // Dark: a neon glow from the accent plus a small drop shadow. Light: a soft,\n // slightly accent-tinted card shadow so the alert reads as an elevated surface\n // instead of a flat tinted rectangle.\n const shadow =\n mode === 'dark'\n ? `0 0 16px color-mix(in srgb, ${accent} 34%, transparent), 0 2px 4px rgba(0, 0, 0, 0.32)`\n : `0 1px 2px rgba(16, 24, 40, 0.05), 0 2px 5px rgba(16, 24, 40, 0.04)`;\n\n // Text is tinted with the accent — light on dark, and a soft accent-tinted dark\n // on light (tinted rather than near-black, to suit the airy wash).\n const titleColor =\n mode === 'dark'\n ? `color-mix(in srgb, ${tintBase} 22%, #ffffff)`\n : `color-mix(in srgb, ${tintBase} 30%, #17171b)`;\n const messageColor =\n mode === 'dark'\n ? `color-mix(in srgb, ${tintBase} 20%, #c8ccd4)`\n : `color-mix(in srgb, ${tintBase} 22%, #3c3c44)`;\n\n if (dismissed) return null;\n\n const handleDismiss = () => {\n setDismissed(true);\n onDismiss?.();\n };\n\n // info/success are polite (status); warning/danger interrupt (alert).\n const role = type === 'warning' || type === 'danger' ? 'alert' : 'status';\n\n return (\n <Container role={role} background={background} frame={borderColor} shadow={shadow}>\n {/* Icon is decorative — the title/message already carry the meaning. */}\n <IconSlot accent={iconColor} aria-hidden='true'>\n <Icon />\n </IconSlot>\n <Body>\n {title ? (\n <Text size='14px' weight={600} color={titleColor}>\n {title}\n </Text>\n ) : null}\n {children ? (\n <Text size='14px' color={messageColor}>\n {children}\n </Text>\n ) : null}\n </Body>\n {isDismissable ? (\n <CloseButton\n aria-label='Dismiss'\n size={16}\n onClick={handleDismiss}\n style={{ color: messageColor, flexShrink: 0, marginTop: 1 }}\n />\n ) : null}\n </Container>\n );\n}\n","import { css } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport type { FunctionComponent, SVGProps } from 'react';\nimport { dontForwardProps } from './utils';\n\nexport type SvgAsset = FunctionComponent<SVGProps<SVGSVGElement> & { title?: string }>;\n\nexport type SvgSize = number | string;\n\ntype SvgContainerProps = {\n svgColor?: string;\n inline?: boolean;\n width?: SvgSize;\n height?: SvgSize;\n};\n\nconst px = (v: SvgSize | undefined) =>\n v === undefined ? undefined : typeof v === 'number' ? `${v}px` : v;\n\nconst SvgContainer = styled(\n 'span',\n dontForwardProps('svgColor', 'inline', 'width', 'height')\n)<SvgContainerProps>(\n ({ svgColor, inline, width, height }) => css`\n display: ${inline ? 'inline-flex' : 'flex'};\n align-items: center;\n justify-items: center;\n ${svgColor ? `color: ${svgColor};` : ''}\n\n svg {\n ${width !== undefined ? `width: ${px(width)};` : ''}\n ${height !== undefined ? `height: ${px(height)};` : ''}\n ${svgColor\n ? `&:not([fill]), &[fill]:not([fill='none'], [fill='transparent']) { fill: ${svgColor}; }\n *[fill]:not([fill='none'], [fill='transparent']) { fill: ${svgColor}; }\n *[stroke]:not([stroke='none'], [stroke='transparent']) { stroke: ${svgColor}; }`\n : ''}\n }\n `\n);\n\nexport type SvgProps = {\n asset: SvgAsset;\n color?: string;\n width?: SvgSize;\n height?: SvgSize;\n /** Sets both width and height. */\n size?: SvgSize;\n inline?: boolean;\n};\n\nexport const Svg = ({ asset: Asset, color, size, width = size, height = size, inline }: SvgProps) => {\n return (\n <SvgContainer svgColor={color} width={width} height={height} inline={inline}>\n <Asset />\n </SvgContainer>\n );\n};\n","import { css, type SerializedStyles } from '@emotion/react';\nimport type { CSSProperties, PropsWithChildren, ReactNode, ButtonHTMLAttributes } from 'react';\nimport { Svg, type SvgAsset } from '../../_internal/Svg';\nimport type { ElementOf } from '../../_internal/utils';\nimport { StyledButton } from './Button.style';\n\n/** Helper to render an SvgAsset at the standard 16px size with `currentColor`. */\nexport const buttonSvg = (asset: SvgAsset) => <Svg asset={asset} color='currentColor' size={16} />;\n\nexport const buttonVariants = {\n /** `variant='bare'` is an outlined secondary button (dim fill + accent outline & text). */\n variants: ['solid', 'bare'],\n colors: ['dark-purple', 'red', 'warning', 'success', 'gray', 'black', 'blue'],\n sizes: ['sm', 'md']\n} as const;\n\nexport type ButtonPropsBase = {\n variant?: ElementOf<(typeof buttonVariants)['variants']>;\n color?: ElementOf<(typeof buttonVariants)['colors']>;\n size?: ElementOf<(typeof buttonVariants)['sizes']>;\n\n disabled?: boolean;\n isSquareIconButton?: boolean;\n isCircleIconButton?: boolean;\n minWidth?: CSSProperties['minWidth'];\n\n leftIcon?: ReactNode;\n rightIcon?: ReactNode;\n uiTestId?: string;\n styleOverrides?: SerializedStyles;\n} & PropsWithChildren<unknown>;\n\nexport type ButtonProps = ButtonPropsBase & ButtonHTMLAttributes<HTMLButtonElement>;\n\nexport const Button = ({ children, leftIcon, rightIcon, uiTestId, disabled, ...props }: ButtonProps) => {\n return (\n <StyledButton\n type='button'\n // `aria-disabled` (not the native attribute) keeps the button focusable and\n // lets `cursor: not-allowed` show — browsers suppress custom cursors on a\n // natively-disabled control. Activation is guarded in the onClick below.\n aria-disabled={disabled || undefined}\n {...props}\n {...(uiTestId ? { 'data-testid': uiTestId } : {})}\n onClick={\n props.onClick && !disabled\n ? e => {\n // Stops propagation so the button is safe inside clickable rows/cards.\n e.stopPropagation();\n e.preventDefault();\n props.onClick?.(e);\n return false;\n }\n : undefined\n }>\n {leftIcon}\n {children}\n {rightIcon}\n </StyledButton>\n );\n};\n\nexport type IconButtonProps = Omit<ButtonProps, 'children' | 'leftIcon' | 'rightIcon' | 'size'> & {\n icon: SvgAsset;\n size?: number | ButtonPropsBase['size'];\n};\n\nexport const IconButton = ({ icon, size: sizeIn = 'md', ...props }: IconButtonProps) => {\n const size = typeof sizeIn === 'number' ? sizeIn : sizeIn === 'sm' ? 32 : 36;\n return (\n <Button\n {...props}\n size='sm'\n minWidth='auto'\n styleOverrides={css`\n padding: ${size / 4}px;\n width: ${size + 1}px;\n height: ${size + 1}px;\n ${props.styleOverrides}\n `}>\n <Svg asset={icon} size={size / 2} color='currentColor' />\n </Button>\n );\n};\n","import { css } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport type { CSSProperties } from 'react';\nimport { cssProp, dontForwardProps } from '../../_internal/utils';\nimport { Spacer, type SpacerProps } from './Spacer';\n\n// region Component\n\nexport type FlexLayoutProps = SpacerProps & {\n horizontal?: boolean;\n vertical?: boolean;\n gap?: CSSProperties['gap'] | number;\n display?: CSSProperties['display'];\n flexWrap?: CSSProperties['flexWrap'];\n justifyContent?: CSSProperties['justifyContent'];\n alignItems?: CSSProperties['alignItems'];\n alignContent?: CSSProperties['alignContent'];\n flexDirection?: CSSProperties['flexDirection'];\n overflow?: CSSProperties['overflow'];\n column?: boolean;\n row?: boolean;\n nowrap?: boolean;\n expandChildren?: boolean;\n};\n\n/**\n * Quick horizontal, vertical, or centered (horizontal & vertical) flex layout.\n * A numeric `gap` is treated as a 0.25em scale step (e.g. `gap={3}` → `0.75em`).\n */\nexport const FlexLayout = styled(\n Spacer,\n dontForwardProps(\n 'horizontal',\n 'vertical',\n 'gap',\n 'display',\n 'flexWrap',\n 'justifyContent',\n 'alignItems',\n 'alignContent',\n 'flexDirection',\n 'overflow',\n 'column',\n 'row',\n 'nowrap',\n 'expandChildren'\n )\n)<FlexLayoutProps>(({\n horizontal,\n vertical,\n gap,\n display,\n flexWrap,\n nowrap,\n justifyContent,\n alignItems,\n alignContent,\n flexDirection,\n column,\n row,\n maxWidth,\n minWidth,\n maxHeight,\n expandChildren,\n overflow\n}) => {\n if (typeof gap === 'number') gap = gap * 0.25 + 'em';\n return css`\n display: flex;\n ${cssProp('justify-content', justifyContent ? justifyContent : horizontal ? 'center' : undefined)}\n ${cssProp('align-items', alignItems ? alignItems : vertical ? 'center' : undefined)}\n ${cssProp('align-content', alignContent ? alignContent : vertical ? 'center' : undefined)}\n ${cssProp('flex-direction', flexDirection ? flexDirection : column ? 'column' : row ? 'row' : undefined)}\n ${cssProp('gap', gap)}\n ${cssProp('display', display)}\n ${cssProp('flex-wrap', flexWrap ? flexWrap : nowrap ? 'nowrap' : 'wrap')}\n ${cssProp('overflow', overflow)}\n max-width: ${maxWidth ?? '100%'};\n ${minWidth\n ? css`\n min-width: ${minWidth};\n `\n : ''}\n max-height: ${maxHeight ?? '100%'};\n ${expandChildren &&\n css`\n > * {\n flex-grow: 1;\n width: auto;\n }\n `}\n `;\n});\n\n/** Adds a `flex-grow: 1` filler into a flex layout. */\nexport const FlexLayoutSpacer = styled.div<{ flexBasis?: CSSProperties['flexBasis'] }>(\n ({ flexBasis }) => css`\n flex-grow: 1;\n ${cssProp('flex-basis', flexBasis)}\n `\n);\n","import { createContext, useContext, useState, type ReactNode } from 'react';\n\n// region Helpers\n\nconst VIM_MODE_STORAGE_KEY = 'monaco-editor-vim-mode';\nconst WORD_WRAP_STORAGE_KEY = 'monaco-editor-word-wrap';\n\nexport interface EditorSettings {\n vimEnabled: boolean;\n toggleVimMode: () => void;\n wordWrapEnabled: boolean;\n toggleWordWrap: () => void;\n}\n\nconst EditorSettingsContext = createContext<EditorSettings | undefined>(undefined);\n\n// region Component\n\n/**\n * Provides per-user editor preferences (vim mode, word wrap), persisted to\n * `localStorage`. Wrap any tree that renders `<MonacoEditorWithSettings />`.\n */\nexport function EditorSettingsProvider({ children }: { children: ReactNode }) {\n const [vimEnabled, setVimEnabled] = useState(() => {\n const saved = localStorage.getItem(VIM_MODE_STORAGE_KEY);\n return saved === 'true';\n });\n\n const [wordWrapEnabled, setWordWrapEnabled] = useState(() => {\n const saved = localStorage.getItem(WORD_WRAP_STORAGE_KEY);\n return saved === 'true';\n });\n\n const toggleVimMode = () => {\n setVimEnabled(prev => {\n const newValue = !prev;\n localStorage.setItem(VIM_MODE_STORAGE_KEY, String(newValue));\n return newValue;\n });\n };\n\n const toggleWordWrap = () => {\n setWordWrapEnabled(prev => {\n const newValue = !prev;\n localStorage.setItem(WORD_WRAP_STORAGE_KEY, String(newValue));\n return newValue;\n });\n };\n\n return (\n <EditorSettingsContext.Provider value={{ vimEnabled, toggleVimMode, wordWrapEnabled, toggleWordWrap }}>\n {children}\n </EditorSettingsContext.Provider>\n );\n}\n\nexport function useEditorSettings() {\n const context = useContext(EditorSettingsContext);\n if (context === undefined) {\n throw new Error('useEditorSettings must be used within EditorSettingsProvider');\n }\n return context;\n}\n","import type { SerializedStyles } from '@emotion/react';\nimport styled from '@emotion/styled';\nimport { Editor, type OnMount } from '@monaco-editor/react';\nimport { Dropdown, Tooltip, type MenuProps } from 'antd';\nimport { Copy, Settings } from 'lucide-react';\nimport type * as monacoEditor from 'monaco-editor';\nimport { initVimMode, type VimMode, VimMode as VimModeClass } from 'monaco-vim';\nimport { useCallback, useEffect, useRef, useState } from 'react';\nimport toast from 'react-hot-toast';\nimport { useEditorSettings } from './EditorSettingsContext';\nimport { useSoloMode, type SoloMode } from '../../providers/SoloModeContext';\n\n// region Styles\n\n// The component reads its palette from CSS custom properties so consumers can\n// theme it, but ships dark-theme fallbacks so it looks right with no theming.\nconst EditorContainer = styled.div<{ height: string; mode: SoloMode; styleOverrides?: SerializedStyles }>`\n /* Include the 1px border in the 100% width/height so the container never spills\n past a tight parent (e.g. an antd Drawer body), which would show scrollbars. */\n box-sizing: border-box;\n position: relative;\n width: 100%;\n height: ${props => props.height};\n display: flex;\n flex-direction: column;\n background: transparent;\n border-radius: 6px;\n overflow: hidden;\n /* Light gets a clearer border + a soft card shadow so the editor reads as an\n elevated surface on a white page; dark keeps a subtle themed frame. */\n ${props =>\n props.mode === 'light'\n ? `\n border: 1px solid #cdd1d8;\n box-shadow: 0 1px 2px rgba(16, 24, 40, 0.06), 0 6px 16px rgba(16, 24, 40, 0.06);\n `\n : `border: 1px solid var(--color-border-base, #3f3f46);`}\n ${props => props.styleOverrides}\n`;\n\nconst EditorWrapper = styled.div`\n flex: 1;\n position: relative;\n min-height: 0;\n background: transparent;\n`;\n\n// Top-right control bar holding the (read-only) copy button and the settings gear.\n// Shifts left by `offsetRight` so it clears the editor's vertical scrollbar.\nconst ControlsBar = styled.div<{ offsetRight: number }>`\n position: absolute;\n top: 8px;\n right: ${props => props.offsetRight}px;\n z-index: 10;\n display: flex;\n gap: 6px;\n transition: right 0.15s ease;\n`;\n\nconst IconActionButton = styled.button`\n background: var(--color-bg-elevated, #1e1e22);\n border: 1px solid var(--color-border-base, #3f3f46);\n border-radius: 3px;\n padding: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.08s ease;\n\n &:hover {\n background: var(--color-bg-hover, #282035);\n border-color: var(--color-primary, #8134e2);\n }\n\n /* Active is a clearly distinct step from hover (deeper fill + press shift). */\n &:active {\n background: var(--color-bg-active, #352b48);\n border-color: var(--color-primary, #8134e2);\n transform: translateY(1px);\n }\n\n &:focus-visible {\n outline: 2px solid var(--color-primary, #8134e2);\n outline-offset: 2px;\n }\n\n svg {\n width: 16px;\n height: 16px;\n color: var(--color-text-primary, #fafafa);\n }\n`;\n\nconst VimStatusBar = styled.div`\n padding: 4px 8px;\n background: var(--color-bg-elevated, #1e1e22);\n border-top: 1px solid var(--color-border-base, #3f3f46);\n font-family: monospace;\n font-size: 12px;\n min-height: 24px;\n`;\n\n// region Component\n\nexport interface MonacoEditorWithSettingsProps {\n value: string;\n onChange?: (value: string | undefined) => void;\n language: string;\n height?: string;\n /** Defaults to the active `SoloContextProvider` mode when omitted. */\n theme?: 'light' | 'dark';\n options?: monacoEditor.editor.IStandaloneEditorConstructionOptions;\n onMount?: OnMount;\n readOnly?: boolean;\n downloadFileName?: string;\n onSave?: () => void;\n onQuit?: () => void;\n /** Emotion styles appended to the outer container. */\n styleOverrides?: SerializedStyles;\n}\n\nexport function MonacoEditorWithSettings({\n value,\n onChange,\n language,\n height = '100%',\n theme,\n options = {},\n onMount,\n readOnly = false,\n downloadFileName,\n onSave,\n onQuit,\n styleOverrides,\n}: MonacoEditorWithSettingsProps) {\n const { vimEnabled, toggleVimMode, wordWrapEnabled, toggleWordWrap } = useEditorSettings();\n // Vim is suppressed in read-only mode, regardless of the user's saved setting.\n const vimActive = vimEnabled && !readOnly;\n // Fall back to the provider's light/dark mode when no explicit theme is given.\n const soloMode = useSoloMode();\n const resolvedTheme = theme ?? soloMode;\n const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor | null>(null);\n const vimModeRef = useRef<VimMode | null>(null);\n const statusNodeRef = useRef<HTMLDivElement | null>(null);\n const onSaveRef = useRef(onSave);\n const onQuitRef = useRef(onQuit);\n const disposablesRef = useRef<monacoEditor.IDisposable[]>([]);\n // Width of the vertical scrollbar when it's visible; the controls shift left by this.\n const [scrollbarWidth, setScrollbarWidth] = useState(0);\n\n // Keep onSave and onQuit refs up to date\n useEffect(() => {\n onSaveRef.current = onSave;\n }, [onSave]);\n\n useEffect(() => {\n onQuitRef.current = onQuit;\n }, [onQuit]);\n\n // Enable/disable vim mode for this editor instance\n useEffect(() => {\n if (!editorRef.current) return;\n\n if (vimActive) {\n // Enable vim mode\n if (!vimModeRef.current && statusNodeRef.current) {\n vimModeRef.current = initVimMode(editorRef.current, statusNodeRef.current);\n\n // Set up vim save and quit commands using VimMode.Vim\n setTimeout(() => {\n try {\n const Vim = (VimModeClass as any).Vim;\n if (Vim && Vim.defineEx) {\n if (onSaveRef.current) {\n Vim.defineEx('write', 'w', () => {\n onSaveRef.current?.();\n });\n }\n if (onQuitRef.current) {\n Vim.defineEx('quit', 'q', () => {\n onQuitRef.current?.();\n });\n }\n if (onSaveRef.current && onQuitRef.current) {\n Vim.defineEx('wq', 'wq', () => {\n onSaveRef.current?.();\n onQuitRef.current?.();\n });\n }\n }\n } catch (e) {\n console.error('Failed to setup vim commands:', e);\n }\n }, 100);\n }\n } else {\n // Disable vim mode\n if (vimModeRef.current) {\n vimModeRef.current.dispose();\n vimModeRef.current = null;\n }\n }\n }, [vimActive]);\n\n const handleEditorMount: OnMount = useCallback(\n (editor, monaco) => {\n editorRef.current = editor;\n\n // Track the vertical scrollbar so the top-right controls can clear it.\n const syncScrollbar = () => {\n const layout = editor.getLayoutInfo();\n const hasVerticalScrollbar = editor.getScrollHeight() > layout.height;\n setScrollbarWidth(hasVerticalScrollbar ? layout.verticalScrollbarWidth : 0);\n };\n syncScrollbar();\n disposablesRef.current.push(\n editor.onDidContentSizeChange(syncScrollbar),\n editor.onDidLayoutChange(syncScrollbar)\n );\n\n // Add keyboard shortcut for save (Cmd+S / Ctrl+S)\n if (onSaveRef.current) {\n editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {\n onSaveRef.current?.();\n });\n }\n\n // Initialize vim mode if enabled (never in read-only mode)\n if (vimActive && statusNodeRef.current && !vimModeRef.current) {\n vimModeRef.current = initVimMode(editor, statusNodeRef.current);\n\n // Set up vim save and quit commands using VimMode.Vim\n setTimeout(() => {\n try {\n const Vim = (VimModeClass as any).Vim;\n if (Vim && Vim.defineEx) {\n if (onSaveRef.current) {\n Vim.defineEx('write', 'w', () => {\n onSaveRef.current?.();\n });\n }\n if (onQuitRef.current) {\n Vim.defineEx('quit', 'q', () => {\n onQuitRef.current?.();\n });\n }\n if (onSaveRef.current && onQuitRef.current) {\n Vim.defineEx('wq', 'wq', () => {\n onSaveRef.current?.();\n onQuitRef.current?.();\n });\n }\n }\n } catch (e) {\n console.error('Failed to setup vim commands:', e);\n }\n }, 100);\n }\n\n // Call custom onMount if provided\n if (onMount) {\n onMount(editor, monaco);\n }\n },\n [onMount, vimActive]\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n vimModeRef.current?.dispose();\n disposablesRef.current.forEach(d => d.dispose());\n };\n }, []);\n\n const handleCopy = useCallback(async () => {\n // Read the live editor content, not the (possibly stale) `value` prop.\n const text = editorRef.current?.getValue() ?? value;\n try {\n await navigator.clipboard.writeText(text);\n toast.success('Copied to clipboard');\n } catch {\n toast.error('Failed to copy to clipboard');\n }\n }, [value]);\n\n const handleDownload = useCallback(() => {\n const text = editorRef.current?.getValue() ?? value;\n try {\n const blob = new Blob([text], { type: 'text/plain' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n\n // Determine file extension from language\n let extension = 'txt';\n if (language === 'json') extension = 'json';\n else if (language === 'yaml' || language === 'yml') extension = 'yaml';\n else if (language === 'javascript' || language === 'typescript')\n extension = language === 'typescript' ? 'ts' : 'js';\n else if (language === 'html') extension = 'html';\n else if (language === 'css') extension = 'css';\n\n a.download = downloadFileName || `content.${extension}`;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n toast.success('Downloaded successfully');\n } catch {\n toast.error('Failed to download file');\n }\n }, [value, language, downloadFileName]);\n\n const menuItems: MenuProps['items'] = [\n // Copy lives in its own always-visible button (left of the gear), not the menu.\n {\n key: 'download',\n label: 'Download',\n onClick: handleDownload,\n },\n {\n type: 'divider',\n },\n // Vim mode is meaningless when read-only, so omit the toggle there.\n !readOnly && {\n key: 'vim',\n label: vimEnabled ? 'Disable Vim Mode' : 'Enable Vim Mode',\n onClick: toggleVimMode,\n },\n {\n key: 'wordwrap',\n label: wordWrapEnabled ? 'Disable Word Wrap' : 'Enable Word Wrap',\n onClick: toggleWordWrap,\n },\n ].filter(Boolean) as MenuProps['items'];\n\n return (\n <EditorContainer height={height} mode={resolvedTheme} styleOverrides={styleOverrides}>\n <EditorWrapper>\n <ControlsBar offsetRight={8 + scrollbarWidth}>\n <Tooltip title='Copy to clipboard'>\n <IconActionButton type='button' aria-label='Copy to clipboard' onClick={handleCopy}>\n <Copy />\n </IconActionButton>\n </Tooltip>\n <Dropdown menu={{ items: menuItems }} placement='bottomRight' trigger={['click']}>\n <Tooltip title='More options'>\n <IconActionButton type='button' aria-label='Editor settings'>\n <Settings />\n </IconActionButton>\n </Tooltip>\n </Dropdown>\n </ControlsBar>\n <Editor\n height='100%'\n language={language}\n value={value}\n onChange={onChange}\n theme={resolvedTheme === 'dark' ? 'vs-dark' : 'vs'}\n onMount={handleEditorMount}\n options={{\n // Keep Monaco fitted to its container as it resizes (e.g. a drawer\n // opening) so it never ends up shorter than its box.\n automaticLayout: true,\n ...options,\n readOnly,\n wordWrap: wordWrapEnabled ? 'on' : 'off',\n }}\n />\n </EditorWrapper>\n {vimActive && <VimStatusBar ref={statusNodeRef as any} className='monaco-vim-status' />}\n </EditorContainer>\n );\n}\n","import { css, Global, ThemeProvider, type Theme } from '@emotion/react';\nimport type { ReactNode } from 'react';\nimport { Toaster, type ToasterProps } from 'react-hot-toast';\n// Import the context directly (not the MonacoEditor barrel) so this provider\n// never pulls the editor's heavy optional deps (antd / monaco) into apps that\n// only use it for theming + toasts.\nimport { EditorSettingsProvider } from '../components/MonacoEditor/EditorSettingsContext';\nimport { SoloModeProvider, type SoloMode } from './SoloModeContext';\n\n// region Helpers\n\n/** Theme tokens the library — and the Monaco editor chrome — read from. */\nexport interface SoloTheme {\n mode: SoloMode;\n fontFamily: string;\n colors: {\n background: string;\n bgElevated: string;\n bgHover: string;\n /** Pressed/active surface — a clearly distinct step from `bgHover`. */\n bgActive: string;\n borderBase: string;\n primary: string;\n textPrimary: string;\n textSecondary: string;\n };\n}\n\nconst FONT_FAMILY = \"'Figtree', ui-sans-serif, system-ui, sans-serif\";\n\n// Light and dark palettes. The editor chrome and components read these via the\n// `--color-*` CSS variables the provider injects.\n// Purple-core: neutrals are tinted toward the brand violet (#8134e2, hue ~267) so\n// purple reads as the system. `bgHover` → `bgActive` is a clear, deliberate step.\nconst palettes: Record<SoloMode, SoloTheme['colors']> = {\n dark: {\n background: '#0f0b18',\n bgElevated: '#1b1624',\n bgHover: '#282035',\n bgActive: '#352b48',\n borderBase: '#3d344d',\n primary: '#8134e2',\n textPrimary: '#f6f4fb',\n textSecondary: '#a6a0b8'\n },\n light: {\n background: '#ffffff',\n bgElevated: '#f6f3fb',\n bgHover: '#ece7f5',\n bgActive: '#ddd3ee',\n borderBase: '#ded7ec',\n primary: '#8134e2',\n textPrimary: '#1a1623',\n textSecondary: '#585465'\n }\n};\n\n/** Default Solo theme (dark). */\nexport const defaultSoloTheme: SoloTheme = { mode: 'dark', fontFamily: FONT_FAMILY, colors: palettes.dark };\n\n/** Theme overrides — non-recursive (one level of `colors`) to keep types cheap. */\nexport interface SoloThemeOverride {\n fontFamily?: string;\n colors?: Partial<SoloTheme['colors']>;\n}\n\n/** Toggle which providers `SoloContextProvider` sets up. Each defaults to `true`. */\nexport interface SoloFeatures {\n /** emotion `ThemeProvider`, the `--color-*` CSS variables, and the web fonts. */\n theme?: boolean;\n /** react-hot-toast `<Toaster />`. */\n toaster?: boolean;\n}\n\n/** Fully typed customization for the enabled features. */\nexport interface SoloConfig {\n /** Theme overrides, merged over the mode palette and any outer `ThemeProvider`. */\n theme?: SoloThemeOverride;\n /** Props for the bundled react-hot-toast `<Toaster />`. */\n toaster?: ToasterProps;\n}\n\n// Loads Figtree (UI), DM Sans, and DM Mono. Kept first in the injected sheet so\n// the @import stays valid.\nconst FONT_IMPORT =\n \"@import url('https://fonts.googleapis.com/css2?family=Figtree:wght@300;400;500;600;700;800&family=DM+Sans:wght@300;400;500;600;700&family=DM+Mono:wght@300;400;500&display=swap');\";\n\n// Non-destructive merge: start from the mode palette, keep outer emotion theme\n// keys, then apply the caller's overrides.\nconst mergeTheme = (mode: SoloMode, outer: Theme | undefined, overrides?: SoloThemeOverride): SoloTheme => {\n const outerOverride = (outer ?? {}) as SoloThemeOverride;\n return {\n ...(outer as object),\n mode,\n fontFamily: overrides?.fontFamily ?? outerOverride.fontFamily ?? FONT_FAMILY,\n colors: {\n ...palettes[mode],\n ...(outerOverride.colors ?? {}),\n ...(overrides?.colors ?? {})\n }\n };\n};\n\nconst globalStyles = (theme: SoloTheme) => css`\n ${FONT_IMPORT}\n\n :root {\n --solo-font-family: ${theme.fontFamily};\n --color-background: ${theme.colors.background};\n --color-bg-elevated: ${theme.colors.bgElevated};\n --color-bg-hover: ${theme.colors.bgHover};\n --color-bg-active: ${theme.colors.bgActive};\n --color-border-base: ${theme.colors.borderBase};\n --color-primary: ${theme.colors.primary};\n --color-text-primary: ${theme.colors.textPrimary};\n --color-text-secondary: ${theme.colors.textSecondary};\n }\n\n body {\n font-family: ${theme.fontFamily};\n }\n\n @keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n }\n`;\n\n// region Component\n\n/**\n * Wraps children in the emotion theme + CSS variables + web fonts, or passes\n * them through untouched when theming is off. Isolating this keeps\n * `SoloContextProvider` a flat, declarative tree instead of branching inline.\n */\nfunction ThemeLayer({\n enabled,\n mode,\n overrides,\n children\n}: {\n enabled: boolean;\n mode: SoloMode;\n overrides?: SoloThemeOverride;\n children: ReactNode;\n}) {\n if (!enabled) return <>{children}</>;\n\n const theme = mergeTheme(mode, undefined, overrides);\n return (\n <ThemeProvider theme={outer => mergeTheme(mode, outer, overrides)}>\n <Global styles={globalStyles(theme)} />\n {children}\n </ThemeProvider>\n );\n}\n\nexport interface SoloContextProviderProps {\n children: ReactNode;\n /** Light or dark color mode. Drives the palette and the editor's default theme. Defaults to `'dark'`. */\n mode?: SoloMode;\n /** Toggle which providers are set up. Each feature defaults to on. */\n features?: SoloFeatures;\n /** Fully typed customization for the enabled features. */\n config?: SoloConfig;\n}\n\n/**\n * Single top-level provider for apps consuming this library. Composes the\n * color mode + emotion theme (web fonts + the `--color-*` CSS variables the\n * editor chrome reads), editor settings, and a react-hot-toast `<Toaster />` —\n * so the library's components work as drop-ins.\n *\n * Opinionated by default (closed to modification), open to extension: pick\n * `mode`, toggle pieces with `features`, and customize them with `config`.\n *\n * The body reads top-down as the provider tree it renders:\n * mode → theme → editor settings → toaster → your app.\n */\nexport function SoloContextProvider({ children, mode = 'dark', features, config }: SoloContextProviderProps) {\n const themeEnabled = features?.theme !== false;\n const toasterEnabled = features?.toaster !== false;\n\n return (\n <SoloModeProvider value={mode}>\n <ThemeLayer enabled={themeEnabled} mode={mode} overrides={config?.theme}>\n <EditorSettingsProvider>\n {toasterEnabled && (\n <Toaster\n {...config?.toaster}\n position={config?.toaster?.position ?? 'bottom-right'}\n toastOptions={{\n ...config?.toaster?.toastOptions,\n // Themed via CSS variables so toasts match light/dark automatically.\n style: {\n background: 'var(--color-bg-elevated, #1e1e22)',\n color: 'var(--color-text-primary, #fafafa)',\n border: '1px solid var(--color-border-base, #3f3f46)',\n ...config?.toaster?.toastOptions?.style\n }\n }}\n />\n )}\n {children}\n </EditorSettingsProvider>\n </ThemeLayer>\n </SoloModeProvider>\n );\n}\n"],"names":["SoloModeContext","createContext","SoloModeProvider","Provider","useSoloMode","useContext","StyledCloseButton","process","env","NODE_ENV","_extends","target","dontForwardProps","label","props","styleOverrides","CloseButton","size","type","ariaLabel","jsx","X","Spacer","mx","my","mr","ml","mt","mb","margin","px","py","pl","pr","pt","pb","padding","marginRight","marginLeft","marginTop","marginBottom","paddingRight","paddingLeft","paddingTop","paddingBottom","cssProp","display","position","minHeight","minWidth","height","width","maxHeight","maxWidth","flexGrow","flexShrink","flexBasis","overflowY","overflowX","overflow","textOverflow","zIndex","fadeIn","stylingOverrides","styles","truncated","Text","weight","lineHeight","color","textAlign","whiteSpace","truncate","wordBreak","textTransform","fontStyle","inline","Container","frame","background","shadow","IconSlot","accent","Body","_styled","name","toString","_EMOTION_STRINGIFIED_CSS_ERROR__","typeConfig","info","Icon","Info","darkAccent","lightAccent","success","CircleCheck","warning","TriangleAlert","danger","OctagonAlert","Alert","title","children","isDismissable","onDismiss","tokens","soloColorTokens","mode","dismissed","setDismissed","useState","lightBase","bg","tintBase","iconColor","borderColor","titleColor","messageColor","handleDismiss","role","v","undefined","SvgContainer","svgColor","css","Svg","asset","Asset","buttonSvg","buttonVariants","variants","colors","sizes","Button","leftIcon","rightIcon","uiTestId","disabled","jsxs","StyledButton","onClick","e","stopPropagation","preventDefault","IconButton","icon","sizeIn","_ref","FlexLayout","horizontal","vertical","gap","flexWrap","nowrap","justifyContent","alignItems","alignContent","flexDirection","column","row","expandChildren","FlexLayoutSpacer","VIM_MODE_STORAGE_KEY","WORD_WRAP_STORAGE_KEY","EditorSettingsContext","EditorSettingsProvider","vimEnabled","setVimEnabled","localStorage","getItem","wordWrapEnabled","setWordWrapEnabled","toggleVimMode","prev","newValue","setItem","String","toggleWordWrap","useEditorSettings","context","Error","EditorContainer","EditorWrapper","ControlsBar","offsetRight","IconActionButton","VimStatusBar","MonacoEditorWithSettings","value","onChange","language","theme","options","onMount","readOnly","downloadFileName","onSave","onQuit","vimActive","soloMode","resolvedTheme","editorRef","useRef","vimModeRef","statusNodeRef","onSaveRef","onQuitRef","disposablesRef","scrollbarWidth","setScrollbarWidth","useEffect","current","initVimMode","setTimeout","Vim","VimModeClass","defineEx","console","error","dispose","handleEditorMount","useCallback","editor","monaco","syncScrollbar","layout","getLayoutInfo","hasVerticalScrollbar","getScrollHeight","verticalScrollbarWidth","push","onDidContentSizeChange","onDidLayoutChange","addCommand","KeyMod","CtrlCmd","KeyCode","KeyS","forEach","d","handleCopy","text","getValue","navigator","clipboard","writeText","toast","menuItems","key","blob","Blob","url","URL","createObjectURL","a","document","createElement","href","extension","download","body","appendChild","click","removeChild","revokeObjectURL","handleDownload","filter","Boolean","Tooltip","Copy","Dropdown","items","Settings","Editor","automaticLayout","wordWrap","FONT_FAMILY","palettes","dark","bgElevated","bgHover","bgActive","borderBase","primary","textPrimary","textSecondary","light","defaultSoloTheme","fontFamily","FONT_IMPORT","mergeTheme","outer","overrides","outerOverride","globalStyles","ThemeLayer","enabled","Fragment","ThemeProvider","Global","SoloContextProvider","features","config","themeEnabled","toasterEnabled","toaster","Toaster","toastOptions","style","border"],"mappings":"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"}