@beforesemicolon/builder 1.8.1 → 1.8.13

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 (58) hide show
  1. package/README.md +839 -142
  2. package/dist/cjs/docs/markdown-layout/index.js +1 -0
  3. package/dist/cjs/docs/markdown-layout/marked-extension.js +1 -0
  4. package/dist/cjs/docs/markdown-layout/parser.js +7 -0
  5. package/dist/cjs/docs/markdown-layout/renderer.js +1 -0
  6. package/dist/cjs/docs/markdown-layout/types.js +1 -0
  7. package/dist/cjs/docs/run.js +76 -1
  8. package/dist/cjs/docs/templates/fading-citrus/README.md +770 -0
  9. package/dist/cjs/docs/templates/fading-citrus/assets/logo.svg +8 -0
  10. package/dist/cjs/docs/templates/fading-citrus/layouts/_code-snippet.js +53 -0
  11. package/dist/cjs/docs/templates/fading-citrus/layouts/_footer.js +7 -4
  12. package/dist/cjs/docs/templates/fading-citrus/layouts/_header.js +4 -4
  13. package/dist/cjs/docs/templates/fading-citrus/layouts/_layout-utils.js +89 -0
  14. package/dist/cjs/docs/templates/fading-citrus/layouts/document.js +7 -4
  15. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-cta.js +30 -0
  16. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-ecosystem.js +43 -0
  17. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-features.js +25 -0
  18. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-hero.js +81 -0
  19. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-install.js +116 -0
  20. package/dist/cjs/docs/templates/fading-citrus/layouts/landing-showcase.js +125 -0
  21. package/dist/cjs/docs/templates/fading-citrus/layouts/landing.js +8 -618
  22. package/dist/cjs/docs/templates/fading-citrus/stylesheets/common.css +6 -4
  23. package/dist/cjs/docs/templates/fading-citrus/template.config.js +100 -1
  24. package/dist/cjs/docs/types.js +1 -1
  25. package/dist/esm/docs/markdown-layout/index.js +1 -0
  26. package/dist/esm/docs/markdown-layout/marked-extension.js +1 -0
  27. package/dist/esm/docs/markdown-layout/parser.js +7 -0
  28. package/dist/esm/docs/markdown-layout/renderer.js +1 -0
  29. package/dist/esm/docs/markdown-layout/types.js +0 -0
  30. package/dist/esm/docs/run.js +76 -1
  31. package/dist/esm/docs/templates/fading-citrus/README.md +770 -0
  32. package/dist/esm/docs/templates/fading-citrus/assets/logo.svg +8 -0
  33. package/dist/esm/docs/templates/fading-citrus/layouts/_code-snippet.js +53 -0
  34. package/dist/esm/docs/templates/fading-citrus/layouts/_footer.js +7 -4
  35. package/dist/esm/docs/templates/fading-citrus/layouts/_header.js +4 -4
  36. package/dist/esm/docs/templates/fading-citrus/layouts/_layout-utils.js +89 -0
  37. package/dist/esm/docs/templates/fading-citrus/layouts/document.js +7 -4
  38. package/dist/esm/docs/templates/fading-citrus/layouts/landing-cta.js +30 -0
  39. package/dist/esm/docs/templates/fading-citrus/layouts/landing-ecosystem.js +43 -0
  40. package/dist/esm/docs/templates/fading-citrus/layouts/landing-features.js +25 -0
  41. package/dist/esm/docs/templates/fading-citrus/layouts/landing-hero.js +81 -0
  42. package/dist/esm/docs/templates/fading-citrus/layouts/landing-install.js +116 -0
  43. package/dist/esm/docs/templates/fading-citrus/layouts/landing-showcase.js +125 -0
  44. package/dist/esm/docs/templates/fading-citrus/layouts/landing.js +8 -618
  45. package/dist/esm/docs/templates/fading-citrus/stylesheets/common.css +6 -4
  46. package/dist/esm/docs/templates/fading-citrus/template.config.js +100 -1
  47. package/dist/types/docs/markdown-layout/index.d.ts +4 -0
  48. package/dist/types/docs/markdown-layout/marked-extension.d.ts +8 -0
  49. package/dist/types/docs/markdown-layout/parser.d.ts +12 -0
  50. package/dist/types/docs/markdown-layout/renderer.d.ts +3 -0
  51. package/dist/types/docs/markdown-layout/types.d.ts +35 -0
  52. package/dist/types/docs/run.d.ts +12 -1
  53. package/dist/types/docs/types.d.ts +23 -0
  54. package/package.json +3 -2
  55. package/dist/cjs/docs/templates/fading-citrus/layouts/_copy-code.js +0 -50
  56. package/dist/cjs/docs/templates/fading-citrus/layouts/_logo.js +0 -31
  57. package/dist/esm/docs/templates/fading-citrus/layouts/_copy-code.js +0 -50
  58. package/dist/esm/docs/templates/fading-citrus/layouts/_logo.js +0 -31
@@ -341,7 +341,7 @@ footer .footer-brand {
341
341
  min-width: 280px;
342
342
  }
343
343
 
344
- footer .footer-brand svg {
344
+ footer .footer-brand .site-logo {
345
345
  margin-bottom: 16px;
346
346
  display: block;
347
347
  }
@@ -663,8 +663,10 @@ header.site-header .header-inner {
663
663
  justify-content: space-between;
664
664
  }
665
665
 
666
- header.site-header h1 a svg {
666
+ header.site-header h1 a .site-logo {
667
667
  height: 28px;
668
+ width: auto;
669
+ display: block;
668
670
  }
669
671
 
670
672
  header.site-header nav a {
@@ -704,10 +706,10 @@ header.site-header nav a.docs-github-link {
704
706
  gap: 40px;
705
707
  }
706
708
 
707
- .site-footer .footer-brand svg {
709
+ .site-footer .footer-brand .site-logo {
708
710
  height: 28px;
709
711
  width: auto;
710
- color: var(--foreground);
712
+ display: block;
711
713
  }
712
714
 
713
715
  .site-footer .footer-brand p {
@@ -1,6 +1,27 @@
1
- import { renderCodeBlock } from './layouts/_code-snippet.js'
1
+ import {
2
+ renderCodeBlock,
3
+ renderCodeCopyScript,
4
+ } from './layouts/_code-snippet.js'
5
+ import landingHero from './layouts/landing-hero.js'
6
+ import landingEcosystem from './layouts/landing-ecosystem.js'
7
+ import landingFeatures from './layouts/landing-features.js'
8
+ import landingShowcase, {
9
+ renderShowcaseScript,
10
+ } from './layouts/landing-showcase.js'
11
+ import landingInstall, {
12
+ renderInstallScript,
13
+ } from './layouts/landing-install.js'
14
+ import landingCta from './layouts/landing-cta.js'
2
15
 
3
16
  export default {
17
+ markdownLayouts: {
18
+ 'landing-hero': landingHero,
19
+ 'landing-ecosystem': landingEcosystem,
20
+ 'landing-features': landingFeatures,
21
+ 'landing-showcase': landingShowcase,
22
+ 'landing-install': landingInstall,
23
+ 'landing-cta': landingCta,
24
+ },
4
25
  markedOptions: {
5
26
  renderer: {
6
27
  code({ lang, raw }) {
@@ -11,4 +32,82 @@ export default {
11
32
  },
12
33
  },
13
34
  },
35
+ scripts: {
36
+ 'code-copy': {
37
+ match: 'code-copy-btn',
38
+ render: renderCodeCopyScript,
39
+ },
40
+ showcase: {
41
+ match: 'data-fading-citrus-showcase',
42
+ render: renderShowcaseScript,
43
+ },
44
+ install: {
45
+ match: 'data-fading-citrus-install',
46
+ render: renderInstallScript,
47
+ },
48
+ },
49
+ theme: {
50
+ light: {
51
+ '--background': 'oklch(0.98 0.006 250)',
52
+ '--foreground': 'oklch(0.18 0.015 250)',
53
+ '--card': 'oklch(1 0 0)',
54
+ '--primary': 'oklch(0.66 0.18 45)',
55
+ '--primary-glow': 'oklch(0.72 0.19 50)',
56
+ '--primary-foreground': 'oklch(0.98 0.006 250)',
57
+ '--secondary': 'oklch(0.93 0.01 250)',
58
+ '--muted': 'oklch(0.94 0.01 250)',
59
+ '--muted-foreground': 'oklch(0.42 0.02 250)',
60
+ '--accent': 'oklch(0.58 0.16 200)',
61
+ '--border': 'oklch(0.86 0.018 250)',
62
+ '--ring': 'oklch(0.66 0.18 45)',
63
+ '--code-bg': 'oklch(0.16 0.015 250)',
64
+ '--syntax-comment': 'oklch(0.55 0.02 250)',
65
+ '--syntax-keyword': 'oklch(0.78 0.19 50)',
66
+ '--syntax-string': 'oklch(0.78 0.15 145)',
67
+ '--syntax-tag': 'oklch(0.72 0.16 200)',
68
+ '--syntax-attr': 'oklch(0.82 0.14 90)',
69
+ '--gradient-hero':
70
+ 'radial-gradient(ellipse at top, oklch(0.86 0.08 45 / 0.35), transparent 60%)',
71
+ '--gradient-primary':
72
+ 'linear-gradient(135deg, var(--primary), var(--primary-glow))',
73
+ '--gradient-text':
74
+ 'linear-gradient(135deg, oklch(0.18 0.015 250), oklch(0.35 0.03 250))',
75
+ '--gradient-border':
76
+ 'linear-gradient(135deg, oklch(0.66 0.18 45 / 0.45), oklch(0.58 0.16 200 / 0.25))',
77
+ '--shadow-glow': '0 0 60px -15px oklch(0.66 0.18 45 / 0.35)',
78
+ '--shadow-card':
79
+ '0 1px 0 0 oklch(1 0 0 / 0.75) inset, 0 20px 40px -20px oklch(0.18 0.015 250 / 0.18)',
80
+ },
81
+ dark: {
82
+ '--background': 'oklch(0.18 0.015 250)',
83
+ '--foreground': 'oklch(0.96 0.005 250)',
84
+ '--card': 'oklch(0.22 0.018 250)',
85
+ '--primary': 'oklch(0.74 0.18 45)',
86
+ '--primary-glow': 'oklch(0.78 0.19 50)',
87
+ '--primary-foreground': 'oklch(0.18 0.02 250)',
88
+ '--secondary': 'oklch(0.27 0.02 250)',
89
+ '--muted': 'oklch(0.25 0.018 250)',
90
+ '--muted-foreground': 'oklch(0.68 0.02 250)',
91
+ '--accent': 'oklch(0.7 0.16 200)',
92
+ '--border': 'oklch(0.3 0.02 250)',
93
+ '--ring': 'oklch(0.74 0.18 45)',
94
+ '--code-bg': 'oklch(0.16 0.015 250)',
95
+ '--syntax-comment': 'oklch(0.55 0.02 250)',
96
+ '--syntax-keyword': 'oklch(0.78 0.19 50)',
97
+ '--syntax-string': 'oklch(0.78 0.15 145)',
98
+ '--syntax-tag': 'oklch(0.72 0.16 200)',
99
+ '--syntax-attr': 'oklch(0.82 0.14 90)',
100
+ '--gradient-hero':
101
+ 'radial-gradient(ellipse at top, oklch(0.28 0.08 45 / 0.35), transparent 60%)',
102
+ '--gradient-primary':
103
+ 'linear-gradient(135deg, var(--primary), var(--primary-glow))',
104
+ '--gradient-text':
105
+ 'linear-gradient(135deg, oklch(0.98 0.005 250), oklch(0.78 0.05 250))',
106
+ '--gradient-border':
107
+ 'linear-gradient(135deg, oklch(0.74 0.18 45 / 0.5), oklch(0.7 0.16 200 / 0.3))',
108
+ '--shadow-glow': '0 0 60px -15px oklch(0.74 0.18 45 / 0.5)',
109
+ '--shadow-card':
110
+ '0 1px 0 0 oklch(1 0 0 / 0.05) inset, 0 20px 40px -20px oklch(0 0 0 / 0.5)',
111
+ },
112
+ },
14
113
  }
@@ -0,0 +1,4 @@
1
+ export * from './marked-extension.ts';
2
+ export * from './parser.ts';
3
+ export * from './renderer.ts';
4
+ export * from './types.ts';
@@ -0,0 +1,8 @@
1
+ import { Marked, MarkedExtension } from 'marked';
2
+ import { MarkdownLayoutHandler } from './types.ts';
3
+ export interface MarkdownLayoutExtensionOptions {
4
+ marked: Marked;
5
+ handlers?: Record<string, MarkdownLayoutHandler>;
6
+ renderMarkdown?: (markdown: string) => string;
7
+ }
8
+ export declare const createMarkdownLayoutExtension: ({ marked, handlers, renderMarkdown, }: MarkdownLayoutExtensionOptions) => MarkedExtension;
@@ -0,0 +1,12 @@
1
+ import { MarkdownLayoutNode, MarkdownLayoutOptions } from './types.ts';
2
+ export declare const parseOptions: (input?: string) => MarkdownLayoutOptions;
3
+ export declare const parseLayoutHeader: (line: string) => {
4
+ layoutType: string;
5
+ options: MarkdownLayoutOptions;
6
+ };
7
+ export declare const parseItemHeader: (line: string) => {
8
+ name: string | null;
9
+ options: MarkdownLayoutOptions;
10
+ };
11
+ export declare const parseLayoutBlock: (block: string) => MarkdownLayoutNode;
12
+ export declare const readLayoutBlock: (src: string) => string | null;
@@ -0,0 +1,3 @@
1
+ import { MarkdownLayoutHandler, MarkdownLayoutNode, MarkdownLayoutRenderContext } from './types.ts';
2
+ export declare const renderDefaultMarkdownLayout: (node: MarkdownLayoutNode, context: MarkdownLayoutRenderContext) => string;
3
+ export declare const renderMarkdownLayout: (node: MarkdownLayoutNode, context: MarkdownLayoutRenderContext, handlers?: Record<string, MarkdownLayoutHandler>) => string;
@@ -0,0 +1,35 @@
1
+ import { Marked } from 'marked';
2
+ export type MarkdownLayoutOptionValue = string | number | boolean;
3
+ export interface MarkdownLayoutOptions {
4
+ [key: string]: MarkdownLayoutOptionValue;
5
+ }
6
+ export interface MarkdownLayoutItemNode {
7
+ name: string | null;
8
+ options: MarkdownLayoutOptions;
9
+ body: string;
10
+ }
11
+ export interface MarkdownLayoutNode {
12
+ layoutType: string;
13
+ options: MarkdownLayoutOptions;
14
+ items: MarkdownLayoutItemNode[];
15
+ raw: string;
16
+ }
17
+ export interface MarkdownLayoutToken extends MarkdownLayoutNode {
18
+ type: 'markdownLayout';
19
+ }
20
+ export interface MarkdownLayoutRenderContext {
21
+ marked: Marked;
22
+ renderMarkdown(markdown: string): string;
23
+ renderDefault(node: MarkdownLayoutNode): string;
24
+ renderParts(node: MarkdownLayoutNode): MarkdownLayoutRenderedPart[];
25
+ }
26
+ export type MarkdownLayoutHandler = (layout: MarkdownLayoutHandlerInput, context: MarkdownLayoutRenderContext) => string;
27
+ export interface MarkdownLayoutRenderedPart extends MarkdownLayoutItemNode {
28
+ html: string;
29
+ }
30
+ export interface MarkdownLayoutHandlerInput {
31
+ type: string;
32
+ options: MarkdownLayoutOptions;
33
+ parts: MarkdownLayoutRenderedPart[];
34
+ raw: string;
35
+ }
@@ -1,8 +1,19 @@
1
1
  import { MarkedExtension } from 'marked';
2
+ type GeneratedFilesConfig = {
3
+ sitemap: boolean;
4
+ robots: boolean;
5
+ llms: boolean;
6
+ llmsFull: boolean;
7
+ netlify: boolean;
8
+ };
9
+ type GeneratedFilesOptions = boolean | Partial<GeneratedFilesConfig>;
2
10
  export interface BuildDocsOptions {
3
11
  publicDir?: string;
4
12
  srcDir?: string;
5
13
  markedOptions?: MarkedExtension;
6
14
  template?: string;
15
+ siteUrl?: string;
16
+ generatedFiles?: GeneratedFilesOptions;
7
17
  }
8
- export declare const buildDocs: ({ srcDir, publicDir, markedOptions, template, }?: BuildDocsOptions) => Promise<void>;
18
+ export declare const buildDocs: ({ srcDir, publicDir, markedOptions, template, siteUrl, generatedFiles, }?: BuildDocsOptions) => Promise<void>;
19
+ export {};
@@ -1,3 +1,17 @@
1
+ import { MarkedExtension } from 'marked';
2
+ import { MarkdownLayoutHandler } from './markdown-layout/types.ts';
3
+ export type DocsThemeMode = Record<string, string | number>;
4
+ export type DocsThemeModeConfig = DocsThemeMode | false;
5
+ export interface DocsTheme {
6
+ light?: DocsThemeModeConfig;
7
+ dark?: DocsThemeModeConfig;
8
+ }
9
+ export type DocsScriptMatcher = string | string[] | RegExp | ((html: string) => boolean);
10
+ export interface DocsScriptDefinition {
11
+ match?: DocsScriptMatcher;
12
+ render: () => string;
13
+ }
14
+ export type DocsScriptRegistry = Record<string, false | DocsScriptDefinition | (() => string)>;
1
15
  export interface PageProps {
2
16
  name?: string;
3
17
  path?: string;
@@ -16,6 +30,9 @@ export interface PageProps {
16
30
  version: string;
17
31
  [key: string]: unknown;
18
32
  };
33
+ renderMarkdown?: (markdown: string) => string;
34
+ scripts?: string[];
35
+ themeStylesheet?: string;
19
36
  }
20
37
  export interface CustomOptions {
21
38
  name?: string;
@@ -37,3 +54,9 @@ export interface CustomOptions {
37
54
  [key: string]: unknown;
38
55
  }
39
56
  export type SiteMap = Map<string, CustomOptions | SiteMap>;
57
+ export interface DocsTemplateConfig {
58
+ markedOptions?: MarkedExtension;
59
+ markdownLayouts?: Record<string, MarkdownLayoutHandler>;
60
+ scripts?: DocsScriptRegistry;
61
+ theme?: DocsTheme;
62
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beforesemicolon/builder",
3
- "version": "1.8.1",
3
+ "version": "1.8.13",
4
4
  "description": "Utilities to build npm packages and documentation website",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
@@ -21,7 +21,8 @@
21
21
  "scripts": {
22
22
  "build": "rm -rf dist && tsc --emitDeclarationOnly && tsx ./build.ts",
23
23
  "lint": "eslint ./src && prettier --check .",
24
- "format": "eslint ./src --fix && prettier --write ."
24
+ "format": "eslint ./src --fix && prettier --write .",
25
+ "test": "tsx src/docs/markdown-layout/markdown-layout.spec.ts"
25
26
  },
26
27
  "author": "Elson Correia",
27
28
  "license": "BSD-3-Clause",
@@ -1,50 +0,0 @@
1
- export default () => `
2
- <script type="application/javascript">
3
- // handle all possible copy snippet code button on the page
4
- // this implementation is in sync with CodeSnippet partial
5
- document.querySelectorAll('.code-copy-btn').forEach((copyBtn) => {
6
- const snippet = copyBtn.closest('.code-snippet')
7
- const hasCode = snippet?.dataset.code || snippet?.querySelector('code') || snippet?.querySelector('.content')
8
- if (hasCode) {
9
- copyBtn.style.visibility = 'visible'
10
- }
11
- })
12
-
13
- document.addEventListener('click', (e) => {
14
- const copyBtn = e.target.closest('.code-copy-btn')
15
- if (!copyBtn) return
16
-
17
- const snippet = copyBtn.closest('.code-snippet')
18
- if (!snippet) return
19
-
20
- let code = snippet.dataset.code ?? ''
21
-
22
- if (!code) {
23
- const codeEl = snippet.querySelector('code')
24
- if (codeEl) {
25
- const clone = codeEl.cloneNode(true)
26
- clone.querySelectorAll('.line-number').forEach(el => el.remove())
27
- code = clone.textContent ?? ''
28
- }
29
- }
30
-
31
- if (!code) {
32
- code = snippet.querySelector('.content')?.textContent ?? ''
33
- }
34
-
35
- // no code, no copy button
36
- if (code.trim().length) {
37
- clearTimeout(copyBtn._timer)
38
- navigator.clipboard.writeText(code.trim())
39
- copyBtn.textContent = 'copied'
40
- copyBtn.setAttribute('aria-label', 'Code copied')
41
- copyBtn.classList.add('copied')
42
- copyBtn._timer = setTimeout(() => {
43
- copyBtn.textContent = 'copy'
44
- copyBtn.setAttribute('aria-label', 'Copy code')
45
- copyBtn.classList.remove('copied')
46
- }, 1000)
47
- }
48
- })
49
- </script>
50
- `
@@ -1,31 +0,0 @@
1
- export default ({ fill = '#D2ECFF', width = '80px' } = {}) => `
2
- <svg
3
- xmlns="http://www.w3.org/2000/svg"
4
- viewBox="0 0 207.25 61.99"
5
- width="207.25"
6
- height="61.99"
7
- aria-hidden="true"
8
- style="width: ${width}; height: auto"
9
- >
10
- <g fill="${fill}">
11
- <path
12
- d="m47.74.19c-.93-.39-2.01-.17-2.72.54l-20.38,20.38L4.27.73C3.55.02,2.48-.2,1.54.19.61.58,0,1.49,0,2.5v46.81h5V8.54l16.11,16.11-9.19,9.19,3.54,3.54,9.19-9.19,9.19,9.19,3.54-3.54-9.19-9.19,16.11-16.11v40.77h5V2.5c0-1.01-.61-1.92-1.54-2.31Z"
13
- />
14
- <path
15
- d="m84.81,19.78v29.53h-4.7v-5.34c-.86,1.84-2.16,3.26-3.9,4.26-1.74,1-3.77,1.5-6.08,1.5-2.62,0-4.92-.63-6.9-1.88-1.98-1.25-3.5-3.02-4.58-5.31-1.08-2.29-1.61-4.96-1.61-8.01s.55-5.74,1.64-8.07c1.1-2.33,2.63-4.14,4.61-5.43,1.98-1.29,4.26-1.94,6.84-1.94,2.31,0,4.32.51,6.05,1.53,1.72,1.02,3.03,2.45,3.93,4.29v-5.11h4.7Zm-7.04,23.04c1.56-1.98,2.35-4.78,2.35-8.42s-.78-6.44-2.35-8.39c-1.57-1.96-3.8-2.94-6.69-2.94s-5.16,1.01-6.78,3.02c-1.62,2.02-2.44,4.82-2.44,8.42s.8,6.38,2.41,8.33c1.6,1.96,3.87,2.94,6.81,2.94s5.13-.99,6.69-2.96Z"
16
- />
17
- <path
18
- d="m110.46,19.43l-.12,4.34c-.9-.31-1.94-.47-3.11-.47-2.86,0-4.98.89-6.37,2.67-1.39,1.78-2.08,3.94-2.08,6.49v16.85h-4.75v-21.25c0-3.05-.16-5.81-.47-8.28h4.52l.47,5.46c.74-2,1.94-3.52,3.58-4.58,1.64-1.06,3.52-1.58,5.63-1.58.98,0,1.88.12,2.7.35Z"
19
- />
20
- <path
21
- d="m135.17,49.31l-15.14-14.21v14.21h-4.75V6.11h4.75v27.24l13.91-13.5h6.05l-14.79,14.15,16.2,15.32h-6.22Z"
22
- />
23
- <path
24
- d="m170.22,19.78v29.53h-4.64v-5.11c-.94,1.8-2.25,3.17-3.93,4.11-1.68.94-3.58,1.41-5.69,1.41-3.48,0-6.12-.98-7.92-2.94-1.8-1.96-2.7-4.85-2.7-8.69v-18.31h4.75v18.2c0,2.66.55,4.62,1.64,5.87,1.09,1.25,2.76,1.88,4.99,1.88,2.62,0,4.73-.85,6.34-2.55,1.6-1.7,2.41-3.94,2.41-6.72v-16.67h4.75Z"
25
- />
26
- <path
27
- d="m200.97,21.02c2,1.29,3.54,3.1,4.64,5.43,1.1,2.33,1.64,5.02,1.64,8.07s-.55,5.72-1.64,8.01c-1.1,2.29-2.63,4.06-4.61,5.31-1.98,1.25-4.28,1.88-6.9,1.88-2.31,0-4.32-.51-6.05-1.53-1.72-1.02-3.03-2.47-3.93-4.34v18.14h-4.75V28.06c0-3.05-.16-5.81-.47-8.28h4.52l.47,5.69c.82-2.03,2.12-3.61,3.9-4.73,1.78-1.12,3.88-1.67,6.31-1.67,2.58,0,4.87.65,6.87,1.94Zm-1.03,21.84c1.58-1.96,2.38-4.73,2.38-8.33s-.8-6.41-2.41-8.42c-1.61-2.02-3.84-3.02-6.69-3.02s-5.19.98-6.75,2.94c-1.57,1.96-2.35,4.75-2.35,8.39s.78,6.45,2.35,8.42c1.57,1.98,3.82,2.96,6.75,2.96s5.14-.98,6.72-2.94Z"
28
- />
29
- </g>
30
- </svg>
31
- `
@@ -1,50 +0,0 @@
1
- export default () => `
2
- <script type="application/javascript">
3
- // handle all possible copy snippet code button on the page
4
- // this implementation is in sync with CodeSnippet partial
5
- document.querySelectorAll('.code-copy-btn').forEach((copyBtn) => {
6
- const snippet = copyBtn.closest('.code-snippet')
7
- const hasCode = snippet?.dataset.code || snippet?.querySelector('code') || snippet?.querySelector('.content')
8
- if (hasCode) {
9
- copyBtn.style.visibility = 'visible'
10
- }
11
- })
12
-
13
- document.addEventListener('click', (e) => {
14
- const copyBtn = e.target.closest('.code-copy-btn')
15
- if (!copyBtn) return
16
-
17
- const snippet = copyBtn.closest('.code-snippet')
18
- if (!snippet) return
19
-
20
- let code = snippet.dataset.code ?? ''
21
-
22
- if (!code) {
23
- const codeEl = snippet.querySelector('code')
24
- if (codeEl) {
25
- const clone = codeEl.cloneNode(true)
26
- clone.querySelectorAll('.line-number').forEach(el => el.remove())
27
- code = clone.textContent ?? ''
28
- }
29
- }
30
-
31
- if (!code) {
32
- code = snippet.querySelector('.content')?.textContent ?? ''
33
- }
34
-
35
- // no code, no copy button
36
- if (code.trim().length) {
37
- clearTimeout(copyBtn._timer)
38
- navigator.clipboard.writeText(code.trim())
39
- copyBtn.textContent = 'copied'
40
- copyBtn.setAttribute('aria-label', 'Code copied')
41
- copyBtn.classList.add('copied')
42
- copyBtn._timer = setTimeout(() => {
43
- copyBtn.textContent = 'copy'
44
- copyBtn.setAttribute('aria-label', 'Copy code')
45
- copyBtn.classList.remove('copied')
46
- }, 1000)
47
- }
48
- })
49
- </script>
50
- `
@@ -1,31 +0,0 @@
1
- export default ({ fill = '#D2ECFF', width = '80px' } = {}) => `
2
- <svg
3
- xmlns="http://www.w3.org/2000/svg"
4
- viewBox="0 0 207.25 61.99"
5
- width="207.25"
6
- height="61.99"
7
- aria-hidden="true"
8
- style="width: ${width}; height: auto"
9
- >
10
- <g fill="${fill}">
11
- <path
12
- d="m47.74.19c-.93-.39-2.01-.17-2.72.54l-20.38,20.38L4.27.73C3.55.02,2.48-.2,1.54.19.61.58,0,1.49,0,2.5v46.81h5V8.54l16.11,16.11-9.19,9.19,3.54,3.54,9.19-9.19,9.19,9.19,3.54-3.54-9.19-9.19,16.11-16.11v40.77h5V2.5c0-1.01-.61-1.92-1.54-2.31Z"
13
- />
14
- <path
15
- d="m84.81,19.78v29.53h-4.7v-5.34c-.86,1.84-2.16,3.26-3.9,4.26-1.74,1-3.77,1.5-6.08,1.5-2.62,0-4.92-.63-6.9-1.88-1.98-1.25-3.5-3.02-4.58-5.31-1.08-2.29-1.61-4.96-1.61-8.01s.55-5.74,1.64-8.07c1.1-2.33,2.63-4.14,4.61-5.43,1.98-1.29,4.26-1.94,6.84-1.94,2.31,0,4.32.51,6.05,1.53,1.72,1.02,3.03,2.45,3.93,4.29v-5.11h4.7Zm-7.04,23.04c1.56-1.98,2.35-4.78,2.35-8.42s-.78-6.44-2.35-8.39c-1.57-1.96-3.8-2.94-6.69-2.94s-5.16,1.01-6.78,3.02c-1.62,2.02-2.44,4.82-2.44,8.42s.8,6.38,2.41,8.33c1.6,1.96,3.87,2.94,6.81,2.94s5.13-.99,6.69-2.96Z"
16
- />
17
- <path
18
- d="m110.46,19.43l-.12,4.34c-.9-.31-1.94-.47-3.11-.47-2.86,0-4.98.89-6.37,2.67-1.39,1.78-2.08,3.94-2.08,6.49v16.85h-4.75v-21.25c0-3.05-.16-5.81-.47-8.28h4.52l.47,5.46c.74-2,1.94-3.52,3.58-4.58,1.64-1.06,3.52-1.58,5.63-1.58.98,0,1.88.12,2.7.35Z"
19
- />
20
- <path
21
- d="m135.17,49.31l-15.14-14.21v14.21h-4.75V6.11h4.75v27.24l13.91-13.5h6.05l-14.79,14.15,16.2,15.32h-6.22Z"
22
- />
23
- <path
24
- d="m170.22,19.78v29.53h-4.64v-5.11c-.94,1.8-2.25,3.17-3.93,4.11-1.68.94-3.58,1.41-5.69,1.41-3.48,0-6.12-.98-7.92-2.94-1.8-1.96-2.7-4.85-2.7-8.69v-18.31h4.75v18.2c0,2.66.55,4.62,1.64,5.87,1.09,1.25,2.76,1.88,4.99,1.88,2.62,0,4.73-.85,6.34-2.55,1.6-1.7,2.41-3.94,2.41-6.72v-16.67h4.75Z"
25
- />
26
- <path
27
- d="m200.97,21.02c2,1.29,3.54,3.1,4.64,5.43,1.1,2.33,1.64,5.02,1.64,8.07s-.55,5.72-1.64,8.01c-1.1,2.29-2.63,4.06-4.61,5.31-1.98,1.25-4.28,1.88-6.9,1.88-2.31,0-4.32-.51-6.05-1.53-1.72-1.02-3.03-2.47-3.93-4.34v18.14h-4.75V28.06c0-3.05-.16-5.81-.47-8.28h4.52l.47,5.69c.82-2.03,2.12-3.61,3.9-4.73,1.78-1.12,3.88-1.67,6.31-1.67,2.58,0,4.87.65,6.87,1.94Zm-1.03,21.84c1.58-1.96,2.38-4.73,2.38-8.33s-.8-6.41-2.41-8.42c-1.61-2.02-3.84-3.02-6.69-3.02s-5.19.98-6.75,2.94c-1.57,1.96-2.35,4.75-2.35,8.39s.78,6.45,2.35,8.42c1.57,1.98,3.82,2.96,6.75,2.96s5.14-.98,6.72-2.94Z"
28
- />
29
- </g>
30
- </svg>
31
- `