Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Initial commit
  • Loading branch information
patrick-kw-chiu committed May 3, 2024
0 parents commit 0b81fb4
Show file tree
Hide file tree
Showing 88 changed files with 11,633 additions and 0 deletions.
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

/node_modules/
/lib/
/test/
custom-elements.json
/bin/
/internal/
/src/annotative/highlight.js
/src/annotative/styles/css
/src/annotative/constants/*.json

/docs/.next
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2023 Patrick Chiu

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
127 changes: 127 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# annotative

<p align="center">
<img src="https://github.com/patrick-kw-chiu/annotative/blob/main/assets/annotative-2.png?raw=true" alt="Annotative Code | Generated with Stable Diffusion XL" width="160" />
<h6 align="center">
Icon generated with <a href="https://stability.ai/">Stable Diffusion XL</a>
</h6>
</p>

Supercharge your [highlight.js](https://github.com/highlightjs/highlight.js) code demo with interactive input knobs

**Quick links:** [Get Started](https://patrick-kw-chiu.github.io/annotative-code/getting-started/) | API Doc | Interactive Playground

**Demos:** [React](https://stackblitz.com/edit/vitejs-vite-qczupp?file=src%2FAnnotativeCode.tsx,src%2FCodeDemo.tsx&terminal=dev) | [Vue](https://stackblitz.com/edit/vitejs-vite-xijn5h?file=src%2Fcomponents%2FHelloWorld.vue&terminal=dev) | [Svelte](https://stackblitz.com/edit/vitejs-vite-rqlzes?file=package.json,src%2FApp.svelte&terminal=dev) | [vanilla JS](https://stackblitz.com/edit/vitejs-vite-nzhtqa?file=index.html,main.js&terminal=dev)

<!-- [Astro](https://stackblitz.com/edit/withastro-astro-podyte?file=src%2Fpages%2Findex.astro&title=Astro%20Starter%20Kit:%20Minimal) | -->

## Quick React.js example

```
npm i annotative-code -S
```

<p align="center">
<img src="https://github.com/patrick-kw-chiu/annotative/blob/main/assets/quick-demo.gif?raw=true" alt="Quick demo" />
</p>

```javascript
// 1. Because using web components in React is not mature yet
// we need to create a bridge React component <AnnotativeCode /> with `@lit/react`
import React from 'react';
import { createComponent } from '@lit/react';
import { AnnotativeCode as AnnotativeCodeWC } from 'annotative-code';

export const AnnotativeCode = createComponent({
tagName: 'annotative-code',
elementClass: AnnotativeCodeWC,
react: React,
});
```

```javascript
import { AnnotativeCode } from './AnnotativeCode';

// 2. Only import the language function and theme css in need can reduce the bundle size
import languageFn from 'annotative-code/bin/highlight.js/languages/javascript';
import themeCss from 'annotative-code/bin/highlight.js/css/a11y-dark';

// 3. Code/content to be highlighted
const content = `<Button variant="____variant____">
Click me!
</Button>`;

// 4. Add annotations to the highlighted code!
const annotation = {
variant: {
type: 'string',
knob: 'select',
options: ['text', 'contained', 'outlined'],
value: variant,
},
};

<AnnotativeCode
themeCss={themeCss}
languageFn={languageFn}
content={content}
annotation={annotation}
onValueChange={({ detail }) => setVariant(detail.valueObj.variant)}
/>;
```

## Features

- 📝 **Goodies of [highlight.js](https://github.com/highlightjs/highlight.js)** - Syntax highlighting of [190+ programming languages](https://github.com/highlightjs/highlight.js/tree/main/src/languages) and [240+ themes](https://github.com/highlightjs/highlight.js/tree/main/src/styles) support
- 🎮 **Interactive knobs** - Let users play around with your code **safely** with various knobs e.g. `string`, `number`, `select` and `datetime-local`
- 👂🏻 **On change listener** - Captures user's input and reflect to the demo
- 🧙🏻‍♂️ **Customizable** - Code block styles (`styleMap`) and pop up (`renderPopup` and `renderDescription`) are customizable
- 🧱 **Web component** - Works with most of the frameworks e.g. React, Svelte, Vue and more

---

## Development

(WIP)

1. (One time only) Install dependencies

```
npm install
```

The `annotative` package is built with `lit` and the local development environment is using `vite`.

2. (One time only) Generate lit theme CSS and programming languages functions from [highlight.js](https://github.com/highlightjs/highlight.js)

```
node ./tools/generateThemes
node ./tools/generateProgLangs
```

3. Run the dev server

```
npm run dev
```

<!--
---
## Build for publish
1. Compile the packages
```
npm run build
```
2. Bundle the code to `esm` format
```
npm run rollup
```
So it can be directly used in modern browser by e.g. `<script type="module" src="{{cdn}}/annotative-python-a11y-dark.js" />`
-->
Binary file added assets/annotative-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/annotative.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/quick-demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
45 changes: 45 additions & 0 deletions docs/components/Code/JS/QuickCode.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
```html filename="/index.html" copy
<body>
<!-- 1. Add a 'annotative-code' web component in the html and import main.js -->
<annotative-code id="code-block"></annotative-code>
<script type="module" src="./main.js"></script>
</body>
```

```javascript filename="/main.js" copy
// 2. Inside main.js,
// Import 'annotative-code' to make the web component available
// Only import the language function and theme css in need can reduce the bundle size
import 'annotative-code';
import javascript from 'annotative-code/bin/highlight.js/languages/javascript.js';
import a11yDarkCss from 'annotative-code/bin/highlight.js/css/a11y-dark.js';
// Also import the `applyProperties` utility
import { applyProperties } from 'annotative-code/bin/utilities/utilities.js';

// 3. Code/content to be highlighted
// If you enclose certain text with ____ (4 underscore), it becomes a placeholder.
// The object key(s) of `annotation` will try to insert an annotation popup to it
const content = `<Button variant="____variant____">
Button
</Button>`;

// 4. Add annotations to the highlighted code!
// Object key(s) of `annotation` is used to search for placeholder(s) that is enclosed with ____ (4 underscore)
// Then insert an annotation popup to the placeholder
const annotation = {
variant: {
type: 'string',
knob: 'select',
options: ['text', 'contained', 'outlined'],
value: 'text',
},
};

// 5. Apply the props to the HTML element (with id = 'code-block')
applyProperties(document.getElementById('code-block'), {
languageFn: javascript,
themeCss: a11yDarkCss,
content,
annotation,
});
```
10 changes: 10 additions & 0 deletions docs/components/Code/React/ImportLangFnAndTheme.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import ExplainImportLangFnAndTheme from '../../Content/ExplainImportLangFnAndTheme.mdx';

<ExplainImportLangFnAndTheme />

```js filename="/components/CodeDemo.jsx" copy
import { useState } from 'react';
import AnnotativeCode from './AnnotativeCode';
import languageFn from 'annotative-code/bin/highlight.js/languages/javascript';
import themeCss from 'annotative-code/bin/highlight.js/css/a11y-dark';
```
38 changes: 38 additions & 0 deletions docs/components/Code/React/QuickCode.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
```js filename="/components/CodeDemo.jsx" copy
// 1. Because using web components in React is not mature yet
// We need to create a bridge React component <AnnotativeCode /> with `@lit/react`
// In here, we assume we have done so.
// See more in "Getting Started > annotative-code > React"
import AnnotativeCode from './AnnotativeCode';

// 2. Only import the language function and theme css in need can reduce the bundle size
import languageFn from 'annotative-code/bin/highlight.js/languages/javascript';
import themeCss from 'annotative-code/bin/highlight.js/css/a11y-dark';

// 3. Code/content to be highlighted
// If you enclose certain text with ____ (4 underscore), it becomes a placeholder.
// The object key(s) of `annotation` will try to insert an annotation popup to it
const content = `<Button variant="____variant____">
Button
</Button>`;

// 4. Add annotations to the highlighted code!
// Object key(s) of `annotation` is used to search for placeholder(s) that is enclosed with ____ (4 underscore)
// Then insert an annotation popup to the placeholder
const annotation = {
variant: {
type: 'string',
knob: 'select',
options: ['text', 'contained', 'outlined'],
value: 'text',
},
};

// 5. Pass all the 4 props
<AnnotativeCode
themeCss={themeCss}
languageFn={languageFn}
content={content}
annotation={annotation}
/>;
```
17 changes: 17 additions & 0 deletions docs/components/Code/React/ReactBridgeComponent.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
```bash filename="Terminal" copy
npm i @lit/react
```

```js filename="/components/AnnotativeCode.jsx" copy
import React from 'react';
import { createComponent } from '@lit/react';
import { AnnotativeCode as AnnotativeCodeWC } from 'annotative-code';

const AnnotativeCode = createComponent({
tagName: 'annotative-code',
elementClass: AnnotativeCodeWC,
react: React,
});

export default AnnotativeCode;
```
38 changes: 38 additions & 0 deletions docs/components/Code/React/ReactCode.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
```js filename="/components/CodeDemo.jsx" copy
import { useState } from 'react';
import Button from '@mui/material/Button';
// ...other import from step 2

const CodeDemo = () => {
const [variant, setVariant] = useState('text');

const content = `<Button variant="____variant____">
Button
</Button>`;

const annotation = {
variant: {
type: 'string',
knob: 'select',
options: ['text', 'contained', 'outlined'],
value: variant,
},
};

return (
<div>
<Button variant={variant}>Button</Button>
<hr />
<AnnotativeCode
themeCss={themeCss}
languageFn={languageFn}
content={content}
annotation={annotation}
onChange={(event) => {
setVariant(event.detail.valueObj.variant);
}}
/>
</div>
);
};
```
37 changes: 37 additions & 0 deletions docs/components/Code/Svelte/QuickCode.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
```svelte filename="/components/CodeDemo.svelte" copy
<script>
// 1. Import 'annotative-code' to make the web component available
import 'annotative-code';
// 2. Only import the language function and theme css in need can reduce the bundle size
import languageFn from 'annotative-code/bin/highlight.js/languages/javascript';
import themeCss from 'annotative-code/bin/highlight.js/css/a11y-dark';
// 3. Code/content to be highlighted
// If you enclose certain text with ____ (4 underscore), it becomes a placeholder.
// The object key(s) of `annotation` will try to insert an annotation popup to it
const content = `<Button variant="____variant____">
Button
</Button>`;
// 4. Add annotations to the highlighted code!
// Object key(s) of `annotation` is used to search for placeholder(s) that is enclosed with ____ (4 underscore)
// Then insert an annotation popup to the placeholder
const annotation = {
variant: {
type: 'string',
knob: 'select',
options: ['text', 'contained', 'outlined'],
value: 'text',
},
};
</script>
// 5. Pass all the 4 props
<annotative-code
themeCss={themeCss}
languageFn={languageFn}
content={content}
annotation={annotation}
/>
```
Loading

0 comments on commit 0b81fb4

Please sign in to comment.