Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No Tailwind selectors #1894

Merged
merged 3 commits into from
Jun 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions packages/components/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
import * as React from "react";

import "../src/styles/main.css";

import { SquiggleContainer } from "../src/components/SquiggleContainer";

export const decorators = [
(Story) => (
<SquiggleContainer>
<Story />
</SquiggleContainer>
),
];

export const parameters = {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
Expand Down
134 changes: 92 additions & 42 deletions packages/components/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,66 +3,116 @@

# Squiggle components

This package contains the react components for squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/).
This package contains the React components for Squiggle. These can be used either as a library or hosted as a [storybook](https://storybook.js.org/).

The `@quri/squiggle-components` package offers several components and utilities for people who want to embed Squiggle components into websites.

## Usage in a Next.js project
This package is pure ESM; if you have trouble with importing it, read [this document](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c).

For now, `squiggle-components` requires the `window` property, so using the package in Next.js requires dynamic loading:
## Configuration

First, install this library:

```
yarn add @quri/squiggle-components # or npm install if you use npm
```

import React from "react";
import { SquiggleChart } from "@quri/squiggle-components";

import dynamic from "next/dynamic";

const SquiggleChart = dynamic(
() => import("@quri/squiggle-components").then((mod) => mod.SquiggleChart),
{
loading: () => <p>Loading...</p>,
ssr: false,
}
);

export function DynamicSquiggleChart({ squiggleString }) {
if (squiggleString == "") {
return null;
} else {
return (
<SquiggleChart
defaultCode={squiggleString}
width={445}
height={200}
showSummary={true}
/>
);
}
## Styles

Before using this library, you'll have to make a decision on how to use styles.

There are three options:

### 1. Usage with Tailwind

If you already use Tailwind, you should add `./node_modules/@quri/ui/dist/**/*.js` and `./node_modules/@quri/squiggle-components/dist/**/*.js` to your `tailwind.config.js` [content configuration](https://tailwindcss.com/docs/content-configuration):

```js
module.exports = {
content: [
..., // other files for your own project
'./node_modules/@quri/ui/dist/**/*.js',
'./node_modules/@quri/squiggle-components/dist/**/*.js',
],
plugins: [
require("@tailwindcss/forms")({ strategy: "class" }), // playground settings use tailwind forms
require("@quri/squiggle-components/tailwind-plugin"), // some squiggle-components styles extend the default Tailwind's theme
],
..., // other settings
}
```

You can example of this approach in [this repository](https://github.com/NunoSempere/squiggle-nexjs-example), which you could clone to begin using Squiggle in your project.
It's possible that in the future you might need to change the `content` or `plugins` lists. Please check this README and consult with squiggle-components changelog when you update this library to a new version.

## Usage with create-react-app
### 2. Usage without Tailwind

You can import the CSS file that we bundle with this library:

```js
import "@quri/squiggle-components/dist/main.css";
```

Note that you have to import this CSS file **only if you don't use Tailwind**.

Create React App seems to be [on the way out](https://github.com/reactjs/react.dev/pull/5487#issuecomment-1409720741) and it is currently not supported by Squiggle. We recommend looking into ["production-grade React frameworks"](https://react.dev/learn/start-a-new-react-project#production-grade-react-frameworks) instead.
The downsides of this approach:

## Build storybook for development
- It will include the Tailwind's global [preflight](https://tailwindcss.com/docs/preflight) styles, which do some non-trivial CSS resets, e.g. it resets all heading styles.
- There's a slight risk that your own CSS framework class names will collide with Tailwind class names.

We assume that you had run `yarn` at monorepo level, installing dependencies.
You might want to import squiggle-components CSS _before_ your own CSS resets; in that case, your CSS will get a chance to override the styles that Tailwind's preflight broke for you.

You need to _prepare_ by building and bundling `squiggle-lang`
### 3. Configure Tailwind with scoped styles just for this library

```sh
cd ../squiggle-lang
yarn build
This is the approach that we recommend if the previous one doesn't work for you. It's more complicated, though.

First, [install Tailwind](https://tailwindcss.com/docs/installation) in your project.

Then configure Tailwind (in `tailwind.config.js`) in the similar way as the first approach explained above in the "Usage with Tailwind" section:

```js
// tailwind.config.js
module.exports = {
content: [
"./node_modules/@quri/ui/dist/**/*.js",
"./node_modules/@quri/squiggle-components/dist/**/*.js",
],
plugins: [
require("@tailwindcss/forms")({ strategy: "class" }),
require("@quri/squiggle-components/tailwind-plugin"),
],
corePlugins: {
preflight: false,
},
important: ".squiggle",
};
```

If you've otherwise done this recently you can skip those.
Next, in your CSS file for Tailwind, the one with `@tailwind` directives, you'll have to insert the full Tailwind's [preflight](https://unpkg.com/[email protected]/src/css/preflight.css), but wrap it in `.squiggle { ... }`. This way, Tailwind's preflight will affect only Squiggle components and nothing else.

Run a development server
This will require you to install [postcss-nested](https://github.com/postcss/postcss-nested) and add it to your `postcss.config.js`, like this:

```sh
yarn start
```js
// postcss.config.js
module.exports = {
plugins: {
"postcss-nested": {},
tailwindcss: {},
autoprefixer: {},
},
};
```

Then, add `<TailwindProvider>...</TailwindProvider>` on top of your app (it can be imported from `@quri/ui` package). It will:

1. Add an additional `<div class="squiggle">...</div>` for scoped Tailwind styles.
2. Set up React context that will allow to wrap modals and tooltips with that div too. (This is necessary because our modals and tooltips rely on React portals and jump out of the main DOM tree.)

## Components

Consult with our [Storybook](https://components.squiggle-language.com/) to find out which components you can use.

You'll probably need one of `<SquiggleChart>`, `<SquiggleEditor>` or `<SquigglePlayground>`, depending on your goals.

## Usage with create-react-app

Create React App seems to be [on the way out](https://github.com/reactjs/react.dev/pull/5487#issuecomment-1409720741) and might be not compatible with Squiggle. We recommend looking into ["production-grade React frameworks"](https://react.dev/learn/start-a-new-react-project#production-grade-react-frameworks) instead.
19 changes: 11 additions & 8 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@
"jsdom": "^22.1.0",
"postcss": "^8.4.24",
"postcss-cli": "^10.0.0",
"postcss-import": "^15.1.0",
"postcss-loader": "^7.3.2",
"postcss-nesting": "^11.2.2",
"react": "^18.1.0",
"react-dom": "^18.2.0",
"resize-observer-polyfill": "^1.5.1",
Expand All @@ -75,7 +72,7 @@
"scripts": {
"start": "yarn dev",
"dev": "storybook dev -p 6006",
"build:typescript": "rm -rf dist/esm && tsc",
"build:typescript": "rm -rf dist/src dist/tsconfig.tsbuildinfo && tsc",
"build:css": "postcss ./src/styles/main.css -o ./dist/main.css",
"build:lezer": "cd ./src/languageSupport; mkdir -p generated; lezer-generator ./squiggle.grammar --output generated/squiggle.ts",
"build:storybook": "storybook build",
Expand Down Expand Up @@ -125,14 +122,20 @@
"type": "module",
"exports": {
".": {
"import": "./dist/esm/src/index.js",
"types": "./dist/types/src/index.d.ts"
"import": "./dist/src/index.js",
"types": "./dist/src/index.d.ts"
},
"./dist/main.css": {
"default": "./dist/main.css"
},
"./main.css": {
"default": "./dist/main.css"
},
"./tailwind-plugin": {
"default": "./dist/src/tailwind-plugin.cjs"
}
},
"module": "./dist/esm/src/index.js",
"types": "./dist/types/src/index.js",
"module": "./dist/src/index.js",
"types": "./dist/src/index.d.ts",
"source": "./src/index.ts"
}
3 changes: 0 additions & 3 deletions packages/components/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
module.exports = {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
cssnano: {},
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { clsx } from "clsx";
import * as d3 from "d3";
import isEqual from "lodash/isEqual.js";
import * as React from "react";
import { FC, useCallback, useState } from "react";

import {
Expand All @@ -28,7 +27,6 @@ import { SummaryTable } from "./SummaryTable.js";

import { Point } from "../../lib/draw/types.js";
import { DrawContext } from "../../lib/hooks/useCanvas.js";
import { tailwindSelector } from "../SquiggleContainer.js";

export type DistributionsChartProps = {
plot: SqDistributionsPlot;
Expand Down Expand Up @@ -254,8 +252,7 @@ const InnerDistributionsChart: FC<{
render={() => (
<div
className={clsx(
"bg-white border border-gray-300 rounded text-xs p-2 grid gap-x-2",
"squiggle" // tooltip is rendered in a portal, so we need this because squiggle-components styles depend on it
"bg-white border border-gray-300 rounded text-xs p-2 grid gap-x-2"
)}
style={{
gridTemplateColumns: "min-content min-content",
Expand All @@ -268,7 +265,6 @@ const InnerDistributionsChart: FC<{
<br />
</div>
)}
tailwindSelector={tailwindSelector}
>
<canvas
data-testid="multi-distribution-chart"
Expand Down
7 changes: 1 addition & 6 deletions packages/components/src/components/SquiggleChart.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from "react";
import { useSquiggle, SquiggleArgs } from "../lib/hooks/useSquiggle.js";
import { SquiggleContainer } from "./SquiggleContainer.js";
import { SquiggleViewer, SquiggleViewerProps } from "./SquiggleViewer/index.js";
import { getValueToRender } from "../lib/utility.js";

Expand All @@ -13,9 +12,5 @@ export const SquiggleChart: React.FC<Props> = React.memo((props) => {

const valueToRender = getValueToRender(resultAndBindings);

return (
<SquiggleContainer>
<SquiggleViewer {...props} result={valueToRender} />
</SquiggleContainer>
);
return <SquiggleViewer {...props} result={valueToRender} />;
});
28 changes: 0 additions & 28 deletions packages/components/src/components/SquiggleContainer.tsx

This file was deleted.

5 changes: 2 additions & 3 deletions packages/components/src/components/SquiggleEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useMaybeControlledValue } from "../lib/hooks/index.js";
import { SquiggleArgs, useSquiggle } from "../lib/hooks/useSquiggle.js";
import { getErrors, getValueToRender } from "../lib/utility.js";
import { CodeEditor } from "./CodeEditor.js";
import { SquiggleContainer } from "./SquiggleContainer.js";
import { SquiggleViewer, SquiggleViewerProps } from "./SquiggleViewer/index.js";

export type SquiggleEditorProps = SquiggleArgs & {
Expand All @@ -25,7 +24,7 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = (props) => {
const errors = getErrors(resultAndBindings.result);

return (
<SquiggleContainer>
<div>
<div
className="border border-grey-200 p-2 m-4"
data-testid="squiggle-editor"
Expand All @@ -41,6 +40,6 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = (props) => {
{props.hideViewer ? null : (
<SquiggleViewer result={valueToRender} {...props} />
)}
</SquiggleContainer>
</div>
);
};
Loading