rn-shiki 0.0.37-8 → 0.0.37-9

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rn-shiki",
3
3
  "type": "module",
4
- "version": "0.0.37-8",
4
+ "version": "0.0.37-9",
5
5
  "description": "Shiki syntax highlighter for React Native.",
6
6
  "author": "Ryan Skinner <hello@ryanskinner.com>",
7
7
  "license": "MIT",
@@ -1,9 +1,9 @@
1
- import type { ThemeRegistrationAny } from 'shiki'
2
1
  import type { SyntaxHighlighterProps } from 'src/types/shiki'
3
- import React from 'react'
2
+ import type { ReactStyle } from '../../utils/style-transformer'
3
+ import React, { useMemo } from 'react'
4
4
  import { Platform, ScrollView, StyleSheet, Text, type TextStyle, View } from 'react-native'
5
5
  import { useSyntaxHighlighter } from '../../hooks/useSyntaxHighlighter'
6
- import { convertShikiTheme } from '../../utils/style-transformer'
6
+ import { getRNStylesFromShikiStyle } from '../../utils/style-transformer'
7
7
 
8
8
  const monospaceFont = Platform.select({
9
9
  ios: 'Menlo',
@@ -16,9 +16,6 @@ const styles = StyleSheet.create({
16
16
  flex: 1,
17
17
  minHeight: 20,
18
18
  },
19
- contentContainer: {
20
- flexGrow: 1,
21
- },
22
19
  lineContainer: {
23
20
  flexDirection: 'row',
24
21
  flexWrap: 'wrap',
@@ -26,7 +23,7 @@ const styles = StyleSheet.create({
26
23
  })
27
24
 
28
25
  const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({ text, language, languageId, theme }) => {
29
- const themeStyles = React.useMemo(() => convertShikiTheme(theme as ThemeRegistrationAny), [theme])
26
+ const stylesheet = useMemo(() => getRNStylesFromShikiStyle(theme as ReactStyle), [theme])
30
27
  const { tokens } = useSyntaxHighlighter({
31
28
  text,
32
29
  language,
@@ -35,16 +32,18 @@ const SyntaxHighlighter: React.FC<SyntaxHighlighterProps> = ({ text, language, l
35
32
  })
36
33
 
37
34
  const renderToken = (token: any, index: number, lineIndex: number) => {
38
- const tokenStyle: TextStyle = {
39
- ...themeStyles.token,
40
- fontFamily: monospaceFont,
41
- ...(token.color && { color: token.color }),
42
- ...(token.fontStyle === 'italic' && themeStyles.italic),
43
- ...(token.fontWeight === 'bold' && themeStyles.bold),
44
- }
35
+ const tokenStyles: TextStyle = StyleSheet.flatten([
36
+ stylesheet.token,
37
+ {
38
+ fontFamily: monospaceFont,
39
+ ...(token.color && { color: token.color }),
40
+ ...(token.fontStyle === 'italic' && stylesheet.italic),
41
+ ...(token.fontWeight === 'bold' && stylesheet.bold),
42
+ },
43
+ ])
45
44
 
46
45
  return (
47
- <Text key={`${lineIndex}-${index}`} style={tokenStyle}>
46
+ <Text key={`${lineIndex}-${index}`} style={tokenStyles}>
48
47
  {token.content.replace(/ /g, '\u00A0')}
49
48
  </Text>
50
49
  )
@@ -1,91 +1,28 @@
1
- import type { RawThemeSetting, ThemeRegistrationAny } from 'shiki'
1
+ import type { CSSProperties } from 'react'
2
+ import type { TextStyle } from 'react-native'
2
3
  import transform, { type StyleTuple } from 'css-to-react-native'
3
- import { StyleSheet, type TextStyle } from 'react-native'
4
4
 
5
5
  export interface HighlighterStyleSheet {
6
- container: TextStyle
7
- token: TextStyle
8
- selection: TextStyle
9
- styles: Record<string, TextStyle>
10
- [key: string]: TextStyle | Record<string, TextStyle>
6
+ [key: string]: TextStyle
11
7
  }
8
+ export type ReactStyle = Record<string, CSSProperties>
12
9
 
13
- // Allowed CSS properties for conversion
14
10
  const ALLOWED_STYLE_PROPERTIES: Record<string, boolean> = {
15
11
  color: true,
12
+ background: true,
16
13
  backgroundColor: true,
17
14
  fontWeight: true,
18
15
  fontStyle: true,
19
16
  }
20
17
 
21
- // Cleans and transforms CSS properties to React Native compatible style
22
- function cleanStyle(style: Record<string, any>): TextStyle {
23
- const filteredStyles = Object.entries(style)
24
- .filter(([key]) => ALLOWED_STYLE_PROPERTIES[key])
25
- .map<StyleTuple>(([key, value]) => [key, value])
26
-
27
- return transform(filteredStyles)
18
+ export function getRNStylesFromShikiStyle(shikiStyle: ReactStyle): HighlighterStyleSheet {
19
+ return Object.fromEntries(Object.entries(shikiStyle).map(([className, style]) => [className, cleanStyle(style)]))
28
20
  }
29
21
 
30
- function processSettings(settings: RawThemeSetting[]): Record<string, TextStyle> {
31
- const tokenStyles: Record<string, TextStyle> = {}
32
-
33
- settings.forEach((setting) => {
34
- if (!setting.scope || !setting.settings)
35
- return
36
-
37
- const style = cleanStyle(setting.settings)
38
-
39
- // Handle single scope
40
- if (typeof setting.scope === 'string') {
41
- tokenStyles[setting.scope] = style
42
- }
43
- // Handle multiple scopes
44
- else if (Array.isArray(setting.scope)) {
45
- setting.scope.forEach((scope) => {
46
- tokenStyles[scope] = style
47
- })
48
- }
49
- })
50
-
51
- return tokenStyles
52
- }
53
-
54
- export function convertShikiTheme(theme: ThemeRegistrationAny): ReturnType<typeof StyleSheet.create> {
55
- // Get all styles from both settings and tokenColors
56
- const settings = [...(theme.settings || []), ...(theme.tokenColors || [])]
57
-
58
- // Process basic colors from the theme
59
- const backgroundColor = theme.colors?.['editor.background'] || theme.bg || '#1e1e1e'
60
- const defaultColor = theme.colors?.['editor.foreground'] || theme.fg || '#d4d4d4'
61
- const selectionColor = theme.colors?.['editor.selectionBackground'] || 'rgba(255, 255, 255, 0.1)'
62
-
63
- // Process token styles
64
- const tokenStyles = processSettings(settings)
65
-
66
- // Convert token styles to RN styles
67
- const tokenStylesMap = Object.entries(tokenStyles).reduce<Record<string, TextStyle>>((acc, [scope, style]) => {
68
- acc[`token-${scope.replace(/\./g, '-')}`] = style
69
- return acc
70
- }, {})
71
-
72
- // Create the complete styles object
73
- const completeStyles: HighlighterStyleSheet = {
74
- container: {
75
- backgroundColor,
76
- flex: 1,
77
- padding: 16,
78
- },
79
- token: {
80
- color: defaultColor,
81
- fontSize: 14,
82
- lineHeight: 21,
83
- },
84
- selection: {
85
- backgroundColor: selectionColor,
86
- },
87
- styles: tokenStylesMap,
88
- }
22
+ export function cleanStyle(style: CSSProperties) {
23
+ const styles = Object.entries(style)
24
+ .filter(([key]) => ALLOWED_STYLE_PROPERTIES[key])
25
+ .map<StyleTuple>(([key, value]) => [key, value])
89
26
 
90
- return StyleSheet.create(completeStyles)
27
+ return transform(styles)
91
28
  }