Skip to content

Commit

Permalink
Merge pull request #21 from break-stuff/add-preact-integration
Browse files Browse the repository at this point in the history
Add JSX integration
  • Loading branch information
break-stuff authored Oct 17, 2023
2 parents ac4ce6b + 20f20b0 commit c0765b9
Show file tree
Hide file tree
Showing 50 changed files with 20,908 additions and 11,081 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
"html.customData": ["./demo/lit-demo/vscode.html-custom-data.json"],
"css.customData": ["./demo/lit-demo/vscode.css-custom-data.json"],
"cSpell.words": [
"exportparts",
"Outdir",
"preact",
"solidjs"
]
}
133 changes: 133 additions & 0 deletions demo/lit-app/custom-element-jsx.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import type { RadioGroup, InterfaceEventType } from "./types/radio-group/RadioGroup.d.ts";
import type { RadioButton } from "./types/radio-button/RadioButton.d.ts";

/**
* This type can be used to create scoped tags for your components.
*
* Usage:
*
* ```ts
* import type { ScopedElements } from "path/to/library/jsx-integration";
*
* declare module "my-library" {
* namespace JSX {
* interface IntrinsicElements
* extends ScopedElements<'test-', ''> {}
* }
* }
* ```
*
*/
export type ScopedElements<Prefix extends string = "", Suffix extends string = ""> = {
[Key in keyof CustomElements as `${Prefix}${Key}${Suffix}`]: CustomElements[Key];
};

type BaseProps = {
/** Content added between the opening and closing tags of the element */
children?: any;
/** Used for declaratively styling one or more elements using CSS (Cascading Stylesheets) */
class?: string;
/** Takes an object where the key is the class name(s) and the value is a boolean expression. When true, the class is applied, and when false, it is removed. */
classList?: Record<string, boolean | undefined>;
/** Contains a space-separated list of the part names of the element. Part names allows CSS to select and style specific elements in a shadow tree via the ::part pseudo-element. */
part?: string;
/** Contains a space-separated list of the part names of the element that should be exposed on the host element. */
exportparts?: string;
/** Adds a reference for a custom element slot */
slot?: string;
/** Prop for setting inline styles */
style?: Record<string, string | number>;
};

type BaseEvents = {};

type RadioGroupProps = {
/** The value assigned to the radio button. This will reflect in the radio group when clicked. */
value?: RadioGroup["value"];
/** Disables the radio group and all of its radio buttons */
disabled?: RadioGroup["disabled"];
/** This will control the size of the radio buttons */
size?: RadioGroup["size"];
/** This is a test for internal options */
variants?: RadioGroup["variants"];
/** This is a test for external d.ts options */
external?: RadioGroup["external"];
/** This is a test for external .ts options */
external2?: RadioGroup["external2"];
/** This is a test for options from an object */
complex?: RadioGroup["complex"];
/** This is a camel-case attribute */
"my-attribute"?: RadioGroup["myAttribute"];

/** some description for custom-event */
onCustomEvent?: (e: CustomEvent<never>) => void;
/** some description for typed-event */
onTypedEvent?: (e: CustomEvent<HTMLInputElement>) => void;
/** some description for typed-custom-event */
onTypedCustomEvent?: (e: CustomEvent<InterfaceEventType>) => void;
};

type RadioButtonProps = {
/** The value assigned to the radio button. This will reflect in the radio group when clicked. */
value?: RadioButton["value"];
/** Disables the radio button */
disabled?: RadioButton["disabled"];
/** A lookup type for example */
target?: RadioButton["target"];
};

export type CustomElements = {
/**
*
* Radio groups are used to group multiple radios or radio buttons, so they function as a single form control. Here is its [documentation](https://github.com/microsoft/vscode-custom-data/blob/master/samples/webcomponents/src/components/my-component/docs.md).
*
* Use it like this:
* ```html
* <radio-group value="2" size="3">
* <span slot="label">My Label</span>
* <radio-button value="1">Option 1</radio-button>
* <radio-button value="2">Option 2</radio-button>
* <radio-button value="3">Option 3</radio-button>
* </radio-group>
* ```
* ---
*
*
* ### **Events:**
* - **custom-event** - some description for custom-event
* - **typed-event** - some description for typed-event
* - **typed-custom-event** - some description for typed-custom-event
*
* ### **Methods:**
* - **validate()** - Validated the radio inputs
* - **checkStatus(value: _string_, message: _string_): _string_** - This is a test method with parameters
*
*
* ### **Slots:**
* - _default_ - add radio buttons to the `default` slot to create options to your radio group
* - **label** - placeholder for the radio group label
*
* ### **CSS Properties:**
* - **--radio-border-radius** - Controls the border radius of the radio buttons _(default: undefined)_
* - **--radio-background-color** - Controls the color of bar _(default: red)_
*
* ### **CSS Parts:**
* - **radio-label** - Applies custom styles the radio group label
*/
"radio-group": Partial<RadioGroupProps | BaseProps | BaseEvents>;

/**
* Radio buttons allow users to select a single option from a group. Here is its [documentation](https://my-site.com/documentation).
*
* Use it like this:
* ```html
* <radio-button value="1" disabled>Your label</radio-button>
* ```
* ---
*
*
* ### **Slots:**
* - _default_ - add text here to label your radio button
*/
"radio-button": Partial<RadioButtonProps | BaseProps | BaseEvents>;
};
4 changes: 4 additions & 0 deletions demo/lit-app/custom-elements-manifest.config.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { customElementVsCodePlugin } from "custom-element-vs-code-integration";
import { customElementJetBrainsPlugin } from "custom-element-jet-brains-integration";
import { customElementSolidJsPlugin } from "custom-element-solidjs-integration";
import { customElementJsxPlugin } from "custom-element-jsx-integration";
import { getTsProgram, expandTypesPlugin } from "cem-plugin-expanded-types";

export default {
Expand Down Expand Up @@ -34,6 +35,9 @@ export default {
customElementSolidJsPlugin({
// globalTypePath: "./types"
componentTypePath: (name, tag) => `./types/${tag}/${name}.d.ts`
}),
customElementJsxPlugin({
componentTypePath: (name, tag) => `./types/${tag}/${name}.d.ts`
})
],
};
16 changes: 8 additions & 8 deletions demo/lit-app/custom-elements.json
Original file line number Diff line number Diff line change
Expand Up @@ -450,30 +450,30 @@
},
{
"kind": "javascript-module",
"path": "src/radio-button/radio-button.ts",
"path": "src/radio-group/radio-group.ts",
"declarations": [],
"exports": [
{
"kind": "custom-element-definition",
"name": "radio-button",
"name": "radio-group",
"declaration": {
"name": "RadioButton",
"module": "/src/radio-button/RadioButton.js"
"name": "RadioGroup",
"module": "/src/radio-group/RadioGroup.js"
}
}
]
},
{
"kind": "javascript-module",
"path": "src/radio-group/radio-group.ts",
"path": "src/radio-button/radio-button.ts",
"declarations": [],
"exports": [
{
"kind": "custom-element-definition",
"name": "radio-group",
"name": "radio-button",
"declaration": {
"name": "RadioGroup",
"module": "/src/radio-group/RadioGroup.js"
"name": "RadioButton",
"module": "/src/radio-button/RadioButton.js"
}
}
]
Expand Down
3 changes: 2 additions & 1 deletion demo/lit-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"custom-element-vs-code-integration": "*",
"custom-element-jet-brains-integration": "*",
"cem-plugin-expanded-types": "*",
"custom-element-solidjs-integration": "*"
"custom-element-solidjs-integration": "*",
"custom-element-jsx-integration": "*"
},
"customElements": "custom-elements.json",
"web-types": "./web-types.json"
Expand Down
24 changes: 24 additions & 0 deletions demo/preact-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 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?
14 changes: 14 additions & 0 deletions demo/preact-app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light dark" />
<title>Vite + Preact</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
18 changes: 18 additions & 0 deletions demo/preact-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"preact": "^10.13.1",
"lit-app": "*"
},
"devDependencies": {
"@preact/preset-vite": "^2.5.0",
"typescript": "^5.2.2",
"vite": "^4.3.2"
}
}
1 change: 1 addition & 0 deletions demo/preact-app/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions demo/preact-app/scoped-components.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { CustomElements, ScopedElements } from "lit-app/custom-element-jsx";

declare module "preact" {
namespace JSX {
interface IntrinsicElements
extends CustomElements {}
}
}
1 change: 1 addition & 0 deletions demo/preact-app/src/assets/preact.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 47 additions & 0 deletions demo/preact-app/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { render } from 'preact';
import preactLogo from './assets/preact.svg';
import './style.css';

export function App() {
return (
<div>
<a href="https://preactjs.com" target="_blank">
<img src={preactLogo} alt="Preact logo" height="160" width="160" />
</a>
<h1>Get Started building Vite-powered Preact Apps </h1>
<section>
<Resource
title="Learn Preact"
description="If you're new to Preact, try the interactive tutorial to learn important concepts"
href="https://preactjs.com/tutorial"
/>
<Resource
title="Differences to React"
description="If you're coming from React, you may want to check out our docs to see where Preact differs"
href="https://preactjs.com/guide/v10/differences-to-react"
/>
<Resource
title="Learn Vite"
description="To learn more about Vite and how you can customize it to fit your needs, take a look at their excellent documentation"
href="https://vitejs.dev"
/>
<radio-group>
<radio-button></radio-button>
<radio-button></radio-button>
<radio-button></radio-button>
</radio-group>
</section>
</div>
);
}

function Resource(props) {
return (
<a href={props.href} target="_blank" class="resource">
<h2>{props.title}</h2>
<p>{props.description}</p>
</a>
);
}

render(<App />, document.getElementById('app'));
Loading

0 comments on commit c0765b9

Please sign in to comment.