@edgeandnode/eds-react 1.0.1 → 1.1.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 (219) hide show
  1. package/README.md +50 -8
  2. package/dist/EDSContext.d.ts +4 -1
  3. package/dist/EDSContext.d.ts.map +1 -1
  4. package/dist/EDSContext.js +7 -0
  5. package/dist/EDSContext.js.map +1 -1
  6. package/dist/EDSProvider.d.ts +13 -6
  7. package/dist/EDSProvider.d.ts.map +1 -1
  8. package/dist/EDSProvider.js +60 -68
  9. package/dist/EDSProvider.js.map +1 -1
  10. package/dist/components/Address.d.ts +3 -3
  11. package/dist/components/Address.d.ts.map +1 -1
  12. package/dist/components/Address.js.map +1 -1
  13. package/dist/components/Avatar.d.ts +3 -3
  14. package/dist/components/Avatar.d.ts.map +1 -1
  15. package/dist/components/Avatar.js +3 -2
  16. package/dist/components/Avatar.js.map +1 -1
  17. package/dist/components/Breadcrumbs.parts.d.ts +7 -6
  18. package/dist/components/Breadcrumbs.parts.d.ts.map +1 -1
  19. package/dist/components/Breadcrumbs.parts.js +15 -14
  20. package/dist/components/Breadcrumbs.parts.js.map +1 -1
  21. package/dist/components/Button.d.ts.map +1 -1
  22. package/dist/components/Button.js +3 -2
  23. package/dist/components/Button.js.map +1 -1
  24. package/dist/components/Card.d.ts +8 -4
  25. package/dist/components/Card.d.ts.map +1 -1
  26. package/dist/components/Card.js +2 -1
  27. package/dist/components/Card.js.map +1 -1
  28. package/dist/components/Cluster.d.ts +3 -3
  29. package/dist/components/Cluster.d.ts.map +1 -1
  30. package/dist/components/Cluster.js.map +1 -1
  31. package/dist/components/CodeBlock.parts.d.ts.map +1 -1
  32. package/dist/components/CodeBlock.parts.js +16 -20
  33. package/dist/components/CodeBlock.parts.js.map +1 -1
  34. package/dist/components/CopyButton.d.ts.map +1 -1
  35. package/dist/components/CopyButton.js +3 -2
  36. package/dist/components/CopyButton.js.map +1 -1
  37. package/dist/components/Icon.d.ts.map +1 -1
  38. package/dist/components/Icon.js +3 -3
  39. package/dist/components/Icon.js.map +1 -1
  40. package/dist/components/Keyboard.js +1 -1
  41. package/dist/components/LocalTheme.d.ts +29 -0
  42. package/dist/components/LocalTheme.d.ts.map +1 -0
  43. package/dist/components/LocalTheme.js +28 -0
  44. package/dist/components/LocalTheme.js.map +1 -0
  45. package/dist/components/Menu.parts.d.ts +43 -9
  46. package/dist/components/Menu.parts.d.ts.map +1 -1
  47. package/dist/components/Menu.parts.js +121 -115
  48. package/dist/components/Menu.parts.js.map +1 -1
  49. package/dist/components/Modal.parts.d.ts +1 -1
  50. package/dist/components/Modal.parts.d.ts.map +1 -1
  51. package/dist/components/Modal.parts.js +22 -11
  52. package/dist/components/Modal.parts.js.map +1 -1
  53. package/dist/components/Pane.parts.d.ts +23 -22
  54. package/dist/components/Pane.parts.d.ts.map +1 -1
  55. package/dist/components/Pane.parts.js +3 -3
  56. package/dist/components/Pane.parts.js.map +1 -1
  57. package/dist/components/Prose.d.ts +1 -1
  58. package/dist/components/Prose.d.ts.map +1 -1
  59. package/dist/components/Prose.js +3 -3
  60. package/dist/components/Prose.js.map +1 -1
  61. package/dist/components/Prose.meta.d.ts +5 -0
  62. package/dist/components/Prose.meta.d.ts.map +1 -1
  63. package/dist/components/Prose.meta.js +10 -0
  64. package/dist/components/Prose.meta.js.map +1 -1
  65. package/dist/components/SegmentedControl.parts.d.ts.map +1 -1
  66. package/dist/components/SegmentedControl.parts.js +3 -2
  67. package/dist/components/SegmentedControl.parts.js.map +1 -1
  68. package/dist/components/Select.parts.d.ts +12 -7
  69. package/dist/components/Select.parts.d.ts.map +1 -1
  70. package/dist/components/Select.parts.js +28 -18
  71. package/dist/components/Select.parts.js.map +1 -1
  72. package/dist/components/TabSet.parts.d.ts.map +1 -1
  73. package/dist/components/TabSet.parts.js +3 -2
  74. package/dist/components/TabSet.parts.js.map +1 -1
  75. package/dist/components/Table.parts.d.ts.map +1 -1
  76. package/dist/components/Table.parts.js +3 -4
  77. package/dist/components/Table.parts.js.map +1 -1
  78. package/dist/components/ThemeSwitcher.d.ts +5 -5
  79. package/dist/components/ThemeSwitcher.d.ts.map +1 -1
  80. package/dist/components/ThemeSwitcher.js +6 -5
  81. package/dist/components/ThemeSwitcher.js.map +1 -1
  82. package/dist/components/Tooltip.parts.js +2 -2
  83. package/dist/components/Tooltip.parts.js.map +1 -1
  84. package/dist/components/base/Addon.d.ts.map +1 -1
  85. package/dist/components/base/Addon.js +2 -4
  86. package/dist/components/base/Addon.js.map +1 -1
  87. package/dist/components/base/ButtonOrLink.parts.d.ts.map +1 -1
  88. package/dist/components/base/ButtonOrLink.parts.js +2 -1
  89. package/dist/components/base/ButtonOrLink.parts.js.map +1 -1
  90. package/dist/components/base/MaybeButtonOrLink.d.ts +7 -5
  91. package/dist/components/base/MaybeButtonOrLink.d.ts.map +1 -1
  92. package/dist/components/base/MaybeButtonOrLink.js +7 -2
  93. package/dist/components/base/MaybeButtonOrLink.js.map +1 -1
  94. package/dist/components/base/Render.d.ts +25 -6
  95. package/dist/components/base/Render.d.ts.map +1 -1
  96. package/dist/components/base/Render.js +4 -3
  97. package/dist/components/base/Render.js.map +1 -1
  98. package/dist/components/base/index.d.ts +1 -1
  99. package/dist/components/base/index.d.ts.map +1 -1
  100. package/dist/components/base/index.js.map +1 -1
  101. package/dist/components/index.d.ts +1 -0
  102. package/dist/components/index.d.ts.map +1 -1
  103. package/dist/components/index.js +1 -0
  104. package/dist/components/index.js.map +1 -1
  105. package/dist/hooks/useCSSProp.js +1 -1
  106. package/dist/hooks/useCSSProp.js.map +1 -1
  107. package/dist/hooks/useEDS.d.ts +24 -1
  108. package/dist/hooks/useEDS.d.ts.map +1 -1
  109. package/dist/hooks/useEDS.js +26 -2
  110. package/dist/hooks/useEDS.js.map +1 -1
  111. package/dist/hooks/useStyleObserver.d.ts.map +1 -1
  112. package/dist/hooks/useStyleObserver.js +2 -1
  113. package/dist/hooks/useStyleObserver.js.map +1 -1
  114. package/dist/icons/CalendarDynamicIcon.d.ts.map +1 -1
  115. package/dist/icons/CalendarDynamicIcon.js +3 -1
  116. package/dist/icons/CalendarDynamicIcon.js.map +1 -1
  117. package/dist/index.d.ts +2 -1
  118. package/dist/index.d.ts.map +1 -1
  119. package/dist/index.js +1 -0
  120. package/dist/index.js.map +1 -1
  121. package/dist/theme-persistence.d.ts +18 -0
  122. package/dist/theme-persistence.d.ts.map +1 -0
  123. package/dist/theme-persistence.js +25 -0
  124. package/dist/theme-persistence.js.map +1 -0
  125. package/dist/utils/getReactNodeKey.d.ts.map +1 -1
  126. package/dist/utils/getReactNodeKey.js +31 -13
  127. package/dist/utils/getReactNodeKey.js.map +1 -1
  128. package/dist/utils/index.d.ts +1 -1
  129. package/dist/utils/index.d.ts.map +1 -1
  130. package/dist/utils/index.js +1 -1
  131. package/dist/utils/index.js.map +1 -1
  132. package/dist/utils/internal/getTooltipProps.d.ts +9 -0
  133. package/dist/utils/internal/getTooltipProps.d.ts.map +1 -0
  134. package/dist/utils/internal/getTooltipProps.js +18 -0
  135. package/dist/utils/internal/getTooltipProps.js.map +1 -0
  136. package/dist/utils/internal/index.d.ts +4 -0
  137. package/dist/utils/internal/index.d.ts.map +1 -0
  138. package/dist/utils/internal/index.js +4 -0
  139. package/dist/utils/internal/index.js.map +1 -0
  140. package/dist/utils/internal/resolveLazy.d.ts +29 -0
  141. package/dist/utils/internal/resolveLazy.d.ts.map +1 -0
  142. package/dist/utils/internal/resolveLazy.js +40 -0
  143. package/dist/utils/internal/resolveLazy.js.map +1 -0
  144. package/dist/utils/internal/styleScheduler.d.ts.map +1 -0
  145. package/dist/utils/internal/styleScheduler.js.map +1 -0
  146. package/dist/utils/isComponentType.d.ts +9 -0
  147. package/dist/utils/isComponentType.d.ts.map +1 -0
  148. package/dist/utils/isComponentType.js +22 -0
  149. package/dist/utils/isComponentType.js.map +1 -0
  150. package/dist/utils/isReactNode.d.ts +7 -0
  151. package/dist/utils/isReactNode.d.ts.map +1 -1
  152. package/dist/utils/isReactNode.js +11 -0
  153. package/dist/utils/isReactNode.js.map +1 -1
  154. package/dist/utils/reactNodeToString.d.ts +3 -0
  155. package/dist/utils/reactNodeToString.d.ts.map +1 -1
  156. package/dist/utils/reactNodeToString.js +6 -0
  157. package/dist/utils/reactNodeToString.js.map +1 -1
  158. package/dist/utils/styleObserver.js +1 -1
  159. package/dist/utils/trimReactNode.d.ts +3 -0
  160. package/dist/utils/trimReactNode.d.ts.map +1 -1
  161. package/dist/utils/trimReactNode.js +6 -0
  162. package/dist/utils/trimReactNode.js.map +1 -1
  163. package/package.json +24 -23
  164. package/scripts/update-skill.cjs +18 -5
  165. package/skill/SKILL.md +95 -57
  166. package/skill/references/tokens.md +2 -8
  167. package/src/EDSContext.ts +10 -1
  168. package/src/EDSProvider.tsx +111 -80
  169. package/src/components/Address.tsx +4 -3
  170. package/src/components/Avatar.tsx +10 -5
  171. package/src/components/Breadcrumbs.parts.tsx +35 -18
  172. package/src/components/Button.tsx +7 -2
  173. package/src/components/Card.tsx +14 -8
  174. package/src/components/Cluster.tsx +5 -3
  175. package/src/components/CodeBlock.parts.tsx +20 -24
  176. package/src/components/CopyButton.tsx +3 -2
  177. package/src/components/Icon.tsx +3 -9
  178. package/src/components/Keyboard.tsx +1 -1
  179. package/src/components/LocalTheme.tsx +47 -0
  180. package/src/components/Menu.parts.tsx +368 -245
  181. package/src/components/Modal.parts.tsx +28 -11
  182. package/src/components/Pane.parts.tsx +31 -26
  183. package/src/components/Prose.meta.ts +10 -0
  184. package/src/components/Prose.tsx +4 -3
  185. package/src/components/SegmentedControl.parts.tsx +3 -8
  186. package/src/components/Select.parts.tsx +43 -34
  187. package/src/components/TabSet.parts.tsx +3 -5
  188. package/src/components/Table.parts.tsx +3 -3
  189. package/src/components/ThemeSwitcher.tsx +13 -15
  190. package/src/components/Tooltip.parts.tsx +2 -2
  191. package/src/components/base/Addon.tsx +3 -4
  192. package/src/components/base/ButtonOrLink.parts.tsx +2 -1
  193. package/src/components/base/MaybeButtonOrLink.tsx +11 -6
  194. package/src/components/base/Render.tsx +28 -4
  195. package/src/components/base/index.ts +2 -0
  196. package/src/components/index.ts +8 -0
  197. package/src/hooks/useCSSProp.ts +1 -1
  198. package/src/hooks/useEDS.ts +26 -2
  199. package/src/hooks/useStyleObserver.ts +2 -1
  200. package/src/icons/CalendarDynamicIcon.tsx +1 -0
  201. package/src/index.ts +2 -1
  202. package/src/theme-persistence.ts +31 -0
  203. package/src/utils/getReactNodeKey.ts +30 -14
  204. package/src/utils/index.ts +1 -1
  205. package/src/utils/internal/getTooltipProps.ts +25 -0
  206. package/src/utils/internal/index.ts +3 -0
  207. package/src/utils/internal/resolveLazy.ts +44 -0
  208. package/src/utils/isComponentType.ts +27 -0
  209. package/src/utils/isReactNode.ts +11 -0
  210. package/src/utils/reactNodeToString.ts +7 -0
  211. package/src/utils/styleObserver.ts +1 -1
  212. package/src/utils/trimReactNode.tsx +7 -0
  213. package/dist/utils/styleScheduler.d.ts.map +0 -1
  214. package/dist/utils/styleScheduler.js.map +0 -1
  215. package/src/__snapshots__/compiled.css +0 -22499
  216. package/styles/tailwind.storybook.css +0 -19
  217. /package/dist/utils/{styleScheduler.d.ts → internal/styleScheduler.d.ts} +0 -0
  218. /package/dist/utils/{styleScheduler.js → internal/styleScheduler.js} +0 -0
  219. /package/src/utils/{styleScheduler.ts → internal/styleScheduler.ts} +0 -0
@@ -50,15 +50,6 @@ import { TabSetContext } from './TabSet.context.ts'
50
50
  import { TabSet, type TabSetTabProps } from './TabSet.tsx'
51
51
  import { ToggleButton } from './ToggleButton.tsx'
52
52
 
53
- // Can't import `@shikijs/vscode-textmate`'s `FontStyle` enum due to `verbatimModuleSyntax`
54
- const FontStyle = {
55
- NotSet: -1,
56
- None: 0,
57
- Italic: 1,
58
- Bold: 2,
59
- Underline: 4,
60
- } as const
61
-
62
53
  const THEMES = {
63
54
  dark: 'night-owl',
64
55
  light: 'min-light',
@@ -166,7 +157,7 @@ export function CodeBlockRoot({
166
157
  children,
167
158
  ...props
168
159
  }: CodeBlockProps) {
169
- const { activeTheme } = useEDS()
160
+ useEDS()
170
161
  const tabsContext = useContext(CodeBlockTabsContext)
171
162
  const hasAncestorTabs = tabsContext !== null
172
163
  const hasAncestorHeader = useContext(CodeBlockHeaderContext) !== false
@@ -209,7 +200,6 @@ export function CodeBlockRoot({
209
200
  highlights,
210
201
  secrets,
211
202
  language,
212
- activeTheme,
213
203
  highlighter,
214
204
  hasAncestorHeader,
215
205
  })
@@ -363,7 +353,18 @@ export function CodeBlockRoot({
363
353
  <span className="select-none"> </span>
364
354
  ) : (
365
355
  <span
356
+ /**
357
+ * `light-dark()` only works for colors, so the font styles use the `dark:`
358
+ * variant (and highlighted tokens need `i:font-bold` to override the weight).
359
+ */
366
360
  className="
361
+ *:font-(--shiki-light-font-weight)
362
+ *:text-[light-dark(var(--shiki-light),var(--shiki-dark))]
363
+ *:[font-style:var(--shiki-light-font-style)]
364
+ *:[text-decoration:var(--shiki-light-text-decoration)]
365
+ dark:*:font-(--shiki-dark-font-weight)
366
+ dark:*:[font-style:var(--shiki-dark-font-style)]
367
+ dark:*:[text-decoration:var(--shiki-dark-text-decoration)]
367
368
  @prop-wrap-true/code-block:wrap-anywhere
368
369
  @prop-wrap-true/code-block:whitespace-pre-wrap
369
370
  "
@@ -379,23 +380,18 @@ export function CodeBlockRoot({
379
380
  data-whitespace={chunk.content.trim() === '' || undefined}
380
381
  data-highlighted={chunk.highlighted || undefined}
381
382
  className={cn(
382
- chunk.fontStyle === FontStyle.Bold ? 'font-bold' : undefined,
383
- chunk.fontStyle === FontStyle.Italic ? 'italic' : undefined,
384
- chunk.fontStyle === FontStyle.Underline ? 'underline' : undefined,
385
- chunk.highlighted ? `z-10 bg-code-highlighted py-1 font-bold
383
+ chunk.highlighted ? `z-10 bg-code-highlighted py-1
386
384
  not-has-[+[data-highlighted]]:-me-1
387
385
  not-has-[+[data-highlighted]]:rounded-e-4
388
386
  not-has-[+[data-highlighted]]:pe-1
389
387
  not-[[data-highlighted]+*]:-ms-1
390
388
  not-[[data-highlighted]+*]:rounded-s-4
391
- not-[[data-highlighted]+*]:ps-1` : 'z-20',
389
+ not-[[data-highlighted]+*]:ps-1
390
+ i:font-bold` : 'z-20',
392
391
  // Prevent wrapping between the indentation and the code
393
392
  chunkIndex === 1 ? '[[data-whitespace]+*]:break-all' : undefined,
394
393
  )}
395
- style={{
396
- color: chunk.color,
397
- backgroundColor: chunk.bgColor,
398
- }}
394
+ style={chunk.htmlStyle}
399
395
  >
400
396
  {chunkContent}
401
397
  </span>
@@ -423,7 +419,6 @@ function useCodeLines({
423
419
  highlights,
424
420
  secrets,
425
421
  language,
426
- activeTheme,
427
422
  highlighter,
428
423
  hasAncestorHeader,
429
424
  }: {
@@ -432,7 +427,6 @@ function useCodeLines({
432
427
  highlights: string[]
433
428
  secrets: string[]
434
429
  language: Language
435
- activeTheme: 'dark' | 'light'
436
430
  highlighter: Highlighter
437
431
  hasAncestorHeader: boolean
438
432
  }): { lines: CodeLine[]; codeToCopy: string } {
@@ -461,7 +455,9 @@ function useCodeLines({
461
455
  if (hasAncestorHeader) return []
462
456
 
463
457
  const { tokens } = highlighter.codeToTokens(code, {
464
- theme: THEMES[activeTheme],
458
+ // Both themes' styles become CSS variables, so tokens follow the local color scheme
459
+ themes: THEMES,
460
+ defaultColor: false,
465
461
  lang: LANGUAGES.includes(language) ? language : 'text',
466
462
  })
467
463
 
@@ -526,7 +522,7 @@ function useCodeLines({
526
522
 
527
523
  return { chunks, style: lineStyle }
528
524
  })
529
- }, [highlighter, passedCode, activeTheme, language, highlights, secrets, diff])
525
+ }, [highlighter, passedCode, language, highlights, secrets, diff])
530
526
 
531
527
  return { lines, codeToCopy }
532
528
  }
@@ -8,7 +8,8 @@ import type { EDSComponentProps } from '@edgeandnode/eds-css'
8
8
  import { CopyInteractiveIcon } from '@edgeandnode/eds-react/icons'
9
9
 
10
10
  import { useEDS } from '../hooks/index.ts'
11
- import { cn, isReactNode } from '../utils/index.ts'
11
+ import { cn } from '../utils/index.ts'
12
+ import { getTooltipProps } from '../utils/internal/index.ts'
12
13
  import { Button, type ButtonProps } from './Button.tsx'
13
14
  import type { CopyButtonMeta } from './CopyButton.meta.ts'
14
15
  import { Tooltip } from './Tooltip.tsx'
@@ -49,7 +50,7 @@ export function CopyButton({
49
50
 
50
51
  const hasChildren = children != null
51
52
  const copyIcon = <CopyInteractiveIcon copied={copied} />
52
- const tooltipProps = isReactNode(tooltip) ? { content: tooltip } : tooltip
53
+ const tooltipProps = getTooltipProps(tooltip)
53
54
  const [tooltipOpen, setTooltipOpen] = useState(false)
54
55
 
55
56
  return (
@@ -1,18 +1,12 @@
1
1
  'use client'
2
2
 
3
- import {
4
- createElement,
5
- isValidElement,
6
- type ComponentProps,
7
- type ComponentType,
8
- type ReactElement,
9
- } from 'react'
3
+ import { createElement, type ComponentProps, type ComponentType, type ReactElement } from 'react'
10
4
  import { mergeProps } from '@base-ui/react'
11
5
 
12
6
  import type { EDSComponentProps } from '@edgeandnode/eds-css'
13
7
 
14
8
  import { useEDS } from '../hooks/index.ts'
15
- import { cn, getCSSPropsAttributes } from '../utils/index.ts'
9
+ import { cn, getCSSPropsAttributes, isComponentType } from '../utils/index.ts'
16
10
  import { IconMeta } from './Icon.meta.ts'
17
11
  import { useTooltipCollector } from './Tooltip.tsx'
18
12
 
@@ -37,7 +31,7 @@ export interface IconPropsWithSrc extends IconProps {
37
31
  export function Icon({ src, alt, size, color, ...props }: IconPropsWithSrc) {
38
32
  useEDS()
39
33
 
40
- const iconContent = isValidElement(src) ? src : createElement(src)
34
+ const iconContent = isComponentType(src) ? createElement(src) : src
41
35
  const collectTooltipContent = useTooltipCollector()
42
36
 
43
37
  if (collectTooltipContent && alt) {
@@ -54,7 +54,7 @@ export function Keyboard({ ref: passedRef, size, children, ...props }: KeyboardP
54
54
  >
55
55
  <span
56
56
  className={cn(
57
- `inline-flex h-(--height) min-w-(--height) items-center justify-center rounded-4 border border-default
57
+ `inline-flex h-(--height) min-w-(--height) items-center justify-center rounded-4 border border-current/15
58
58
  @prop-size-small/keyboard:gap-0.5
59
59
  @prop-size-small/keyboard:px-0.75
60
60
  @prop-size-small/keyboard:text-10
@@ -0,0 +1,47 @@
1
+ 'use client'
2
+
3
+ import { mergeProps } from '@base-ui/react'
4
+ import type { DistributedOmit } from 'type-fest'
5
+
6
+ import { LocalThemeContext, THEME_CLASSES, type ResolvedTheme } from '../EDSContext.ts'
7
+ import { Render, type AsOrRenderProps, type HTMLElementProps } from './base/Render.tsx'
8
+
9
+ export declare namespace LocalThemeProps {
10
+ interface CommonProps extends HTMLElementProps {
11
+ /** The theme to render the content in. */
12
+ theme: ResolvedTheme
13
+ }
14
+ }
15
+
16
+ export type LocalThemeProps = LocalThemeProps.CommonProps & AsOrRenderProps
17
+ export type DarkProps = DistributedOmit<LocalThemeProps, 'theme'>
18
+ export type LightProps = DistributedOmit<LocalThemeProps, 'theme'>
19
+
20
+ /**
21
+ * Renders its content in the given theme, whatever the page's theme is. Unlike switching between
22
+ * `Dark` and `Light`, changing `theme` doesn't remount the content. Components that need to know
23
+ * the theme in JavaScript can read it with `useEDS().activeTheme`.
24
+ */
25
+ export function LocalTheme({ theme, ...props }: LocalThemeProps) {
26
+ return (
27
+ <LocalThemeContext.Provider value={theme}>
28
+ <Render {...mergeProps({ className: THEME_CLASSES[theme] }, props)} />
29
+ </LocalThemeContext.Provider>
30
+ )
31
+ }
32
+
33
+ /**
34
+ * Renders its content in the dark theme, whatever the page's theme is. Components that need to know
35
+ * the theme in JavaScript can read it with `useEDS().activeTheme`.
36
+ */
37
+ export function Dark(props: DarkProps) {
38
+ return <LocalTheme theme="dark" {...props} />
39
+ }
40
+
41
+ /**
42
+ * Renders its content in the light theme, whatever the page's theme is. Components that need to
43
+ * know the theme in JavaScript can read it with `useEDS().activeTheme`.
44
+ */
45
+ export function Light(props: LightProps) {
46
+ return <LocalTheme theme="light" {...props} />
47
+ }