Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/npm_and_yarn/ip-2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
psirenny authored Feb 24, 2024
2 parents 9de2903 + cac89e5 commit 869a88e
Show file tree
Hide file tree
Showing 14 changed files with 1,850 additions and 81 deletions.
5 changes: 5 additions & 0 deletions .changeset/honest-needles-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@spear-ai/ui": minor
---

Added TextField component.
6 changes: 6 additions & 0 deletions .changeset/nasty-walls-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@spear-ai/tailwind-config": patch
"@spear-ai/ui": patch
---

Added missing React Aria Components plugin to the Tailwind config.
5 changes: 5 additions & 0 deletions .changeset/six-roses-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@spear-ai/ui": minor
---

Added Spinner component.
12 changes: 12 additions & 0 deletions packages/relay-environment/eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ const eslintConfig = [
},
...baseEslintConfig,
prettierConfig,
{
files: [
"**/*.md/**/*.cjs",
"**/*.md/**/*.js",
"**/*.md/**/*.jsx",
"**/*.md/**/*.ts",
"**/*.md/**/*.tsx",
],
rules: {
"import/no-unresolved": ["off"],
},
},
];

export default eslintConfig;
1 change: 1 addition & 0 deletions packages/tailwind-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"tailwind-scrollbar": "^3.1.0",
"tailwindcss-3d": "^1.0.5",
"tailwindcss-animate": "^1.0.7",
"tailwindcss-react-aria-components": "^1.1.1",
"ts-invariant": "^0.10.3",
"type-fest": "^4.10.2"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/tailwind-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Config } from "tailwindcss";
import defaultTheme from "tailwindcss/defaultTheme";
import threeDPlugin from "tailwindcss-3d";
import animatePlugin from "tailwindcss-animate";
import reactAriaComponentsPlugin from "tailwindcss-react-aria-components";
import { radixColorThemePlugin } from "./tailwind-radix-color-theme-plugin";
import { colors } from "./tailwind-radix-colors";
import { data } from "./tailwind-radix-primitives";
Expand All @@ -22,6 +23,7 @@ export const tailwindConfig: Config = {
containerQueriesPlugin,
formsPlugin,
radixColorThemePlugin,
reactAriaComponentsPlugin,
scrollbarPlugin,
threeDPlugin,
typographyPlugin,
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"next": "14.1.0",
"next-themes": "0.2.1",
"react": "18.2.0",
"react-aria-components": "1.1.1",
"react-dom": "18.2.0",
"react-hook-form": "7.50.1",
"react-intl": "6.6.2",
Expand All @@ -32,6 +33,7 @@
"@chromatic-com/storybook": "1.1.5",
"@dotenv-run/cli": "1.3.5",
"@formatjs/cli": "6.2.7",
"@react-stately/utils": "3.9.1",
"@spear-ai/eslint-config": "17.1.0",
"@spear-ai/npm-package-json-lint-config": "3.1.0",
"@spear-ai/prettier-config": "2.1.0",
Expand Down
1 change: 0 additions & 1 deletion packages/ui/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export const AppLayout = (properties: {
return (
<div
className={`size-full ${backgroundClassName} ${layoutClassName} ${inter.className} selection:bg-primary-9 selection:text-primary-contrast theme-dfs:selection:bg-black theme-dfs:selection:text-white theme-forerunner:selection:bg-black theme-forerunner:selection:text-white theme-dfs:dark:selection:bg-primary-9 theme-dfs:dark:selection:text-primary-contrast theme-forerunner:dark:selection:bg-white theme-forerunner:dark:selection:text-black`}
dir={direction}
lang="en-US"
>
<AppProviders direction={direction} product={product}>
Expand Down
4 changes: 4 additions & 0 deletions packages/ui/src/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export const AppProviders = (properties: {
document.documentElement.classList.add(`theme-${product}`);
}, [previousProduct, product]);

useEffect(() => {
document.documentElement.dir = direction;
}, [direction]);

return (
<IntlProvider
locale="en-US"
Expand Down
20 changes: 20 additions & 0 deletions packages/ui/src/app/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,24 @@
* {
@apply focus-visible:outline outline-1 focus-visible:outline-2 outline-offset-2 focus-visible:outline-primary-7;
}

[type="text"]:focus,
input:where(:not([type])),
[type="email"]:focus,
[type="email"]:focus,
[type="url"]:focus,
[type="password"]:focus,
[type="number"]:focus,
[type="date"]:focus,
[type="datetime-local"]:focus,
[type="month"]:focus,
[type="search"]:focus,
[type="tel"]:focus,
[type="time"]:focus,
[type="week"]:focus,
[multiple]:focus,
textarea:focus,
select:focus {
@apply outline outline-2 outline-offset-0 outline-primary-a-7 border-transparent ring-0 ring-offset-0;
}
}
157 changes: 80 additions & 77 deletions packages/ui/src/components/select/select.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import * as Form from "@radix-ui/react-form";
import { CaretSortIcon, CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
import { Label } from "@radix-ui/react-label";
import * as Select from "@radix-ui/react-select";
import { CaretSortIcon, CheckIcon } from "@radix-ui/react-icons";
import { useControlledState } from "@react-stately/utils";
import type { Meta, StoryObj } from "@storybook/react";
import { useId } from "react";
import {
Button,
FieldError,
Form,
Label,
ListBox,
ListBoxItem,
Popover,
Select,
SelectValue,
} from "react-aria-components";
import { useIntl } from "react-intl";

const sensorList = [
Expand All @@ -30,24 +39,44 @@ const sensorList = [
];

const PreviewSelect = (properties: {
hasDescription: boolean;
hasError: boolean;
hasLabel: boolean;
hasLabelDescription: boolean;
isAlwaysOpen: boolean;
isDisabled: boolean;
isOptional: boolean;
isSquished: boolean;
}) => {
const { hasDescription, hasError, hasLabel, isDisabled, isSquished } = properties;
const { hasError, hasLabel, hasLabelDescription, isAlwaysOpen, isDisabled, isOptional, isSquished } =
properties;
const intl = useIntl();
const sensorFormId = useId();
const [value, setValue] = useControlledState<string | null>(undefined, null);

return (
<div className={`w-full ${isSquished ? "max-w-36" : "max-w-xs"}`}>
<Form.Root className="relative w-full">
<Form.Field className="group" name="sensor" serverInvalid={hasError}>
<Form className="relative w-full">
<Select
className="group w-full focus:outline-none"
isDisabled={isDisabled}
isInvalid={hasError}
isOpen={isAlwaysOpen ? true : undefined}
onSelectionChange={
isOptional
? (key) => {
setValue(key === "" ? null : `${key}`);
}
: undefined
}
placeholder={intl.formatMessage({
defaultMessage: "Select a sensor",
id: "W2C6Wt",
})}
selectedKey={isOptional ? value : undefined}
>
{hasLabel ? (
<Label
// eslint-disable-next-line tailwindcss/no-arbitrary-value
className="block select-none text-base/6 text-neutral-12 group-has-[[data-disabled]]:text-neutral-11 sm:text-sm/6"
className="block select-none text-base/6 text-neutral-12 group-disabled:text-neutral-11 sm:text-sm/6"
htmlFor={sensorFormId}
>
{intl.formatMessage({
Expand All @@ -56,84 +85,56 @@ const PreviewSelect = (properties: {
})}
</Label>
) : null}
{hasLabel && hasDescription ? (
// eslint-disable-next-line tailwindcss/no-arbitrary-value
<p className="mt-1 text-base/6 text-neutral-11 group-has-[[data-disabled]]:text-neutral-9 sm:text-sm/6">
{hasLabel && hasLabelDescription ? (
<p className="mt-1 text-base/6 text-neutral-11 group-disabled:text-neutral-9 sm:text-sm/6">
{intl.formatMessage({
defaultMessage: "A mechanical device sensitive to sound.",
id: "2YVoI/",
})}
</p>
) : null}
<Form.Control asChild>
<Select.Root disabled={isDisabled}>
<Select.Trigger
// eslint-disable-next-line tailwindcss/no-arbitrary-value
className="group mt-3 inline-flex h-9 w-full cursor-default items-center justify-between gap-1 rounded-lg bg-white-a-3 pe-2 ps-3.5 text-base leading-none text-neutral-12 shadow outline outline-offset-0 outline-neutral-a-7 data-disabled:pointer-events-none data-disabled:text-neutral-a-8 data-open:outline-2 data-open:outline-primary-a-8 data-placeholder:text-neutral-11 focus-visible:outline-primary-a-8 theme-dfs:bg-canvas-1 theme-galapago:bg-white theme-dfs:dark:bg-white-a-3 theme-forerunner:dark:bg-black-a-3 theme-galapago:dark:bg-black-a-3 sm:ps-3 sm:text-sm [[data-invalid]_&]:outline-x-negative-a-7 [[data-invalid]_&]:data-disabled:outline-x-negative-a-6"
id={sensorFormId}
>
<span className="truncate">
<Select.Value
placeholder={intl.formatMessage({
defaultMessage: "Select a sensor",
id: "W2C6Wt",
})}
/>
</span>
<Select.Icon className="text-neutral-11 group-data-disabled:text-neutral-8">
<CaretSortIcon className="size-5" />
</Select.Icon>
</Select.Trigger>
<Select.Portal>
<Select.Content
className="isolate max-h-select-content-available-height rounded-xl bg-canvas-1 shadow-lg !outline !outline-1 outline-offset-0 !outline-neutral-a-6 backdrop-blur data-closed:duration-1000 data-closed:animate-out data-closed:fade-out data-closed:zoom-out-95 data-open:animate-in data-open:fade-in data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2 theme-forerunner:bg-white-a-3 theme-galapago:bg-white theme-underway:shadow-2xl theme-galapago:dark:bg-black-a-3"
position="popper"
sideOffset={8}
>
<Select.ScrollUpButton className="flex h-6 cursor-default items-center justify-center rounded-t-xl text-neutral-11">
<ChevronUpIcon />
</Select.ScrollUpButton>
<Select.Viewport className="h-select-trigger-height w-full min-w-select-trigger-width p-1">
<Select.Item
className="cursor-default select-none rounded-lg py-2.5 pe-5 ps-2 text-base leading-none text-neutral-11 outline-none data-highlighted:bg-primary-5 data-highlighted:outline-none hover:bg-primary-4 sm:py-1.5 sm:text-sm"
value="0"
>
{intl.formatMessage({
defaultMessage: "None",
id: "450Fty",
})}
</Select.Item>
{sensorList.map((sensor) => (
<Select.Item
className="relative cursor-default select-none rounded-lg py-2.5 pe-5 ps-2 text-base leading-none text-neutral-12 data-highlighted:bg-primary-5 data-highlighted:outline-none hover:bg-primary-4 sm:py-1.5 sm:text-sm"
key={sensor.id}
value={sensor.id}
>
<Select.ItemText>{sensor.name}</Select.ItemText>
<Select.ItemIndicator className="absolute top-2 inline-flex size-4 items-center justify-center ltr:right-1 rtl:left-1">
<CheckIcon className="size-4" />
</Select.ItemIndicator>
</Select.Item>
))}
</Select.Viewport>
<Select.ScrollDownButton className="flex h-6 cursor-default items-center justify-center rounded-b-xl text-neutral-11">
<ChevronDownIcon />
</Select.ScrollDownButton>
</Select.Content>
</Select.Portal>
</Select.Root>
</Form.Control>
<Button className="group mt-2 inline-flex h-9 w-full cursor-default select-none items-center justify-between gap-1 rounded-lg border border-transparent bg-white-a-3 pe-2 ps-3.5 text-base leading-none shadow outline outline-offset-0 outline-neutral-a-7 entering:outline-2 entering:outline-primary-a-8 group-invalid:outline-x-negative-a-7 group-disabled:pointer-events-none group-invalid:group-disabled:outline-x-negative-a-6 focus-visible:outline-primary-a-8 theme-dfs:bg-canvas-1 theme-galapago:bg-white theme-dfs:dark:bg-white-a-3 theme-forerunner:dark:bg-black-a-3 theme-galapago:dark:bg-black-a-3 sm:ps-3 sm:text-sm">
<SelectValue className="truncate text-neutral-12 placeholder-shown:text-neutral-11 group-disabled:text-neutral-a-8" />
<span aria-hidden className="text-neutral-11 group-disabled:text-neutral-8">
<CaretSortIcon className="size-5" />
</span>
</Button>
{hasError ? (
// eslint-disable-next-line tailwindcss/no-arbitrary-value
<Form.Message className="mt-3 block text-base/6 text-x-negative-11 group-has-[[data-disabled]]:opacity-50 sm:text-sm/6">
<FieldError className="mt-2 block text-base/6 text-x-negative-11 group-disabled:opacity-50 sm:text-sm/6">
{intl.formatMessage({
defaultMessage: "Sensor is invalid.",
id: "JsiKrm",
})}
</Form.Message>
</FieldError>
) : null}
</Form.Field>
</Form.Root>
<Popover className="isolate min-w-select-trigger-width overflow-auto rounded-xl border-transparent bg-canvas-1 p-1 shadow-lg outline outline-1 outline-offset-0 outline-neutral-a-6 backdrop-blur placement-left:slide-in-from-right-2 placement-right:slide-in-from-left-2 placement-top:slide-in-from-bottom-2 placement-bottom:slide-in-from-top-2 entering:duration-100 entering:animate-in entering:fade-in exiting:duration-75 exiting:animate-out exiting:fade-out exiting:zoom-out-95 theme-forerunner:bg-white-a-3 theme-galapago:bg-white theme-underway:shadow-2xl theme-galapago:dark:bg-black-a-3">
<ListBox className="outline-none">
<ListBoxItem
className="cursor-default select-none rounded-lg py-2.5 pe-5 ps-2 text-base leading-none text-neutral-11 outline-none hover:bg-primary-4 focus:bg-primary-5 focus:outline-none sm:py-1.5 sm:text-sm"
id=""
>
{intl.formatMessage({
defaultMessage: "No sensor",
id: "W2b7y5",
})}
</ListBoxItem>
{sensorList.map((sensor) => (
<ListBoxItem
className="group/item relative cursor-default select-none rounded-lg py-2.5 pe-7 ps-2 text-base leading-none text-neutral-12 outline-none hover:bg-primary-4 focus:bg-primary-5 sm:py-1.5 sm:text-sm rtl:text-right"
id={sensor.id}
key={sensor.id}
textValue={sensor.name}
>
<span>{sensor.name}</span>
<span className="absolute end-1.5 top-2 inline-flex size-4 items-center justify-center opacity-0 group-selected/item:opacity-100">
<CheckIcon className="size-4" />
</span>
</ListBoxItem>
))}
</ListBox>
</Popover>
</Select>
</Form>
</div>
);
};
Expand All @@ -146,10 +147,12 @@ type Story = StoryObj<typeof meta>;

export const Example: Story = {
args: {
hasDescription: true,
hasError: false,
hasLabel: true,
hasLabelDescription: true,
isAlwaysOpen: false,
isDisabled: false,
isOptional: true,
isSquished: false,
},
parameters: {
Expand Down
26 changes: 26 additions & 0 deletions packages/ui/src/components/spinner/spinner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { Meta, StoryObj } from "@storybook/react";

const PreviewSelect = () => (
<svg className="size-5 animate-spin text-neutral-11" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path
className="opacity-75"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
fill="currentColor"
/>
</svg>
);

const meta = {
component: PreviewSelect,
} satisfies Meta<typeof PreviewSelect>;

type Story = StoryObj<typeof meta>;

export const Example: Story = {
parameters: {
layout: "centered",
},
};

export default meta;
Loading

0 comments on commit 869a88e

Please sign in to comment.