@hyvor/design 2.1.4 → 2.1.6-beta.1

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.
@@ -2,7 +2,8 @@
2
2
  import Button from '../Button/Button.svelte';
3
3
  import IconCopy from '@hyvor/icons/IconCopy';
4
4
  import toast from '../Toast/toast.js';
5
- import { getCode, sanitizeLines, type Language } from './getCode.js';
5
+ import { highlightCode, sanitizeLines } from './getCode.js';
6
+ import type { Language } from './types.codeblock.js';
6
7
 
7
8
  interface Props {
8
9
  code: string;
@@ -19,22 +20,22 @@
19
20
  }
20
21
  </script>
21
22
 
22
- <div class="code-container">
23
+ <div class="hds-code-block">
23
24
  <div class="copy-button">
24
25
  <Button color="input" size="x-small" onclick={copyToClipboard}>
25
26
  <IconCopy size={10} />
26
27
  </Button>
27
28
  </div>
28
- {@html await getCode(sanitizedCode, language)}
29
+ {@html await highlightCode(sanitizedCode, language)}
29
30
  </div>
30
31
 
31
32
  <style>
32
33
  /*styles for CodeBlock component */
33
- .code-container {
34
+ .hds-code-block {
34
35
  position: relative;
35
36
  }
36
37
 
37
- .code-container .copy-button {
38
+ .copy-button {
38
39
  position: absolute;
39
40
  top: 0px;
40
41
  right: 12px;
@@ -45,33 +46,4 @@
45
46
  .copy-button :global(button) {
46
47
  border: 1px solid var(--border);
47
48
  }
48
-
49
- .code-container :global(pre) {
50
- text-align: left;
51
- white-space: pre;
52
- word-spacing: normal;
53
- word-break: normal;
54
- word-wrap: normal;
55
- overflow: auto;
56
- border-radius: 20px;
57
- padding: 20px;
58
- line-height: 1.2;
59
- background-color: #f4f2f0 !important;
60
- }
61
-
62
- .code-container :global(pre code) {
63
- all: unset;
64
- font-size: 14px;
65
- line-height: 1.5 !important;
66
- tab-size: 4;
67
- hyphens: none;
68
- }
69
-
70
- :global(:root.dark .shiki, :root.dark .shiki span) {
71
- color: var(--shiki-dark) !important;
72
- background-color: var(--shiki-dark-bg) !important;
73
- font-style: var(--shiki-dark-font-style) !important;
74
- font-weight: var(--shiki-dark-font-weight) !important;
75
- text-decoration: var(--shiki-dark-text-decoration) !important;
76
- }
77
49
  </style>
@@ -1,4 +1,4 @@
1
- import { type Language } from './getCode.js';
1
+ import type { Language } from './types.codeblock.js';
2
2
  interface Props {
3
3
  code: string;
4
4
  language?: Language | null;
@@ -1,3 +1,11 @@
1
- export type Language = 'html' | 'css' | 'js' | 'ts' | 'yaml' | 'json' | 'svelte' | 'jsx' | 'php' | 'sh' | string;
2
- export declare function sanitizeLines(code: string): string;
3
- export declare function getCode(code: string, language: Language | null): Promise<string>;
1
+ /**
2
+ * @param {string} code
3
+ * @returns {string}
4
+ */
5
+ export function sanitizeLines(code: string): string;
6
+ /**
7
+ * @param {string} code
8
+ * @param {import('./types.codeblock.ts').Language | null} language
9
+ * @returns {Promise<string>}
10
+ */
11
+ export function highlightCode(code: string, language: import("./types.codeblock.ts").Language | null): Promise<string>;
@@ -1,33 +1,55 @@
1
1
  import { codeToHtml } from 'shiki';
2
+
3
+ /**
4
+ * @param {string} code
5
+ * @returns {string}
6
+ */
2
7
  export function sanitizeLines(code) {
3
- let ret = code;
4
- // remove the first empty line
5
- ret = ret.replace(/^[^\S\r\n]*\n/, '');
6
- // remove the last empty line
7
- ret = ret.replace(/\n[^\S\r\n]*$/, '');
8
- let lines = ret.split('\n');
9
- let indent = null; // number of spaces to remove from each line
10
- lines = lines.map((line) => {
11
- if (indent === null) {
12
- // find the indent
13
- const match = line.match(/^(\s*)/);
14
- indent = match ? match[1].length : 0;
15
- }
16
- if (line.substring(0, indent).trim() !== '') {
17
- return line;
18
- }
19
- // remove the indent
20
- line = line.substring(indent);
21
- return line;
22
- });
23
- return lines.join('\n');
8
+ let ret = code;
9
+
10
+ // remove the first empty line
11
+ ret = ret.replace(/^[^\S\r\n]*\n/, '');
12
+ // remove the last empty line
13
+ ret = ret.replace(/\n[^\S\r\n]*$/, '');
14
+
15
+ let lines = ret.split('\n');
16
+
17
+ /**
18
+ * @type {null | number}
19
+ */
20
+ let indent = null; // number of spaces to remove from each line
21
+
22
+ lines = lines.map((line) => {
23
+ if (indent === null) {
24
+ // find the indent
25
+ const match = line.match(/^(\s*)/);
26
+ indent = match ? match[1].length : 0;
27
+ }
28
+
29
+ if (line.substring(0, indent).trim() !== '') {
30
+ return line;
31
+ }
32
+
33
+ // remove the indent
34
+ line = line.substring(indent);
35
+
36
+ return line;
37
+ });
38
+
39
+ return lines.join('\n');
24
40
  }
25
- export async function getCode(code, language) {
26
- return await codeToHtml(code, {
27
- lang: language || 'text',
28
- themes: {
29
- light: 'vitesse-light',
30
- dark: 'nord'
31
- }
32
- });
41
+
42
+ /**
43
+ * @param {string} code
44
+ * @param {import('./types.codeblock.ts').Language | null} language
45
+ * @returns {Promise<string>}
46
+ */
47
+ export async function highlightCode(code, language) {
48
+ return await codeToHtml(code, {
49
+ lang: language || 'text',
50
+ themes: {
51
+ light: 'vitesse-light',
52
+ dark: 'nord'
53
+ }
54
+ });
33
55
  }
@@ -0,0 +1 @@
1
+ export type Language = 'html' | 'css' | 'js' | 'ts' | 'yaml' | 'json' | 'svelte' | 'jsx' | 'php' | 'sh' | string;
@@ -0,0 +1 @@
1
+ export {};
@@ -12,6 +12,7 @@ export { default as BoxShadowPicker } from './BoxShadowPicker/BoxShadowPicker.sv
12
12
  export { default as Callout } from './Callout/Callout.svelte';
13
13
  export { default as Checkbox } from './Checkbox/Checkbox.svelte';
14
14
  export { default as CodeBlock } from './CodeBlock/CodeBlock.svelte';
15
+ export { highlightCode } from './CodeBlock/getCode.js';
15
16
  export { default as TabbedCodeBlock } from './CodeBlock/TabbedCodeBlock.svelte';
16
17
  export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
17
18
  export { default as ConsoleLoader } from './ConsoleLoader/ConsoleLoader.svelte';
@@ -12,6 +12,7 @@ export { default as BoxShadowPicker } from './BoxShadowPicker/BoxShadowPicker.sv
12
12
  export { default as Callout } from './Callout/Callout.svelte';
13
13
  export { default as Checkbox } from './Checkbox/Checkbox.svelte';
14
14
  export { default as CodeBlock } from './CodeBlock/CodeBlock.svelte';
15
+ export { highlightCode } from './CodeBlock/getCode.js';
15
16
  export { default as TabbedCodeBlock } from './CodeBlock/TabbedCodeBlock.svelte';
16
17
  export { default as ColorPicker } from './ColorPicker/ColorPicker.svelte';
17
18
  export { default as ConsoleLoader } from './ConsoleLoader/ConsoleLoader.svelte';
@@ -0,0 +1,4 @@
1
+ /**
2
+ * @returns {import('svelte/compiler').PreprocessorGroup}
3
+ */
4
+ export function markdownPlugin(): import("svelte/compiler").PreprocessorGroup;
@@ -0,0 +1,20 @@
1
+ import { mdsvex, escapeSvelte } from 'mdsvex';
2
+ import { highlightCode } from '../components/CodeBlock/getCode.js';
3
+
4
+ // this is a JS file because we can use it in svelte.config.js locally
5
+
6
+ /**
7
+ * @returns {import('svelte/compiler').PreprocessorGroup}
8
+ */
9
+ export function markdownPlugin() {
10
+ return mdsvex({
11
+ extensions: ['.md'],
12
+ highlight: {
13
+ highlighter: async (code, lang) => {
14
+ const highlitedCode = await highlightCode(code, lang || null);
15
+ const html = `<div class="hds-code-block">${highlitedCode}</div>`;
16
+ return escapeSvelte(html);
17
+ }
18
+ }
19
+ });
20
+ }
package/dist/index.css CHANGED
@@ -61,3 +61,34 @@ a {
61
61
  color: var(--link);
62
62
  text-decoration: underline;
63
63
  }
64
+
65
+ /** code block styles */
66
+ .hds-code-block pre {
67
+ text-align: left;
68
+ white-space: pre;
69
+ word-spacing: normal;
70
+ word-break: normal;
71
+ word-wrap: normal;
72
+ overflow: auto;
73
+ border-radius: 20px;
74
+ padding: 20px;
75
+ line-height: 1.2;
76
+ background-color: #f4f2f0 !important;
77
+ }
78
+
79
+ .hds-code-block pre code {
80
+ all: unset;
81
+ font-size: 14px;
82
+ line-height: 1.5 !important;
83
+ tab-size: 4;
84
+ hyphens: none;
85
+ }
86
+
87
+ :root.dark .shiki,
88
+ :root.dark .shiki span {
89
+ color: var(--shiki-dark) !important;
90
+ background-color: var(--shiki-dark-bg) !important;
91
+ font-style: var(--shiki-dark-font-style) !important;
92
+ font-weight: var(--shiki-dark-font-weight) !important;
93
+ text-decoration: var(--shiki-dark-text-decoration) !important;
94
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyvor/design",
3
- "version": "2.1.4",
3
+ "version": "2.1.6-beta.1",
4
4
  "license": "MIT",
5
5
  "private": false,
6
6
  "repository": {
@@ -25,6 +25,10 @@
25
25
  "types": "./dist/components/index.d.ts",
26
26
  "svelte": "./dist/components/index.js"
27
27
  },
28
+ "./dev": {
29
+ "types": "./dist/dev/markdown.d.ts",
30
+ "default": "./dist/dev/markdown.js"
31
+ },
28
32
  "./marketing": {
29
33
  "types": "./dist/marketing/index.d.ts",
30
34
  "svelte": "./dist/marketing/index.js"
@@ -65,6 +69,7 @@
65
69
  "deepmerge-ts": "^7.1.5",
66
70
  "emojibase-data": "^17.0.0",
67
71
  "intl-messageformat": "^11.1.2",
72
+ "mdsvex": "^0.12.8",
68
73
  "shiki": "^3.22.0",
69
74
  "svelte-awesome-color-picker": "^4.1.1",
70
75
  "tocbot": "^4.36.4"