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

chore: migrate vui-source changes to v1.1.0 #170

Closed
wants to merge 1 commit into from
Closed
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vectara/vectara-ui",
"version": "1.0.1",
"version": "1.1.1",
"homepage": "https://vectara.github.io/vectara-ui/",
"description": "Vectara's design system, codified as a React and Sass component library",
"author": "Vectara",
Expand Down
3 changes: 2 additions & 1 deletion src/docs/pages/modal/PrimaryModal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from "react";
import { VuiButtonPrimary, VuiButtonSecondary, VuiModal, VuiSearchSelect, VuiSpacer, VuiText } from "../../../lib";
import { BiInfoCircle } from "react-icons/bi";

const options = [
{ value: "a", label: "Caffeine-free" },
Expand Down Expand Up @@ -27,7 +28,7 @@ export const PrimaryModal = () => {
Open primary modal
</VuiButtonPrimary>

<VuiModal color="primary" isOpen={isOpen} onClose={() => setIsOpen(false)} title="FYI">
<VuiModal color="primary" isOpen={isOpen} onClose={() => setIsOpen(false)} icon={<BiInfoCircle />} title="FYI">
<VuiText>
<p>I just thought you should know that your modal is showing.</p>
</VuiText>
Expand Down
87 changes: 57 additions & 30 deletions src/docs/pages/popover/Popover.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
import { useState } from "react";
import { VuiButtonSecondary, VuiIcon, VuiOptionsList, VuiPopover } from "../../../lib";
import {
AnchorSide,
VuiButtonSecondary,
VuiFormGroup,
VuiIcon,
VuiOptionsList,
VuiPopover,
VuiSelect,
VuiSpacer
} from "../../../lib";
import { BiCaretDown } from "react-icons/bi";

const options = [
Expand All @@ -11,36 +20,54 @@ const options = [
export const Popover = () => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState("apples");
const [anchorSide, setAnchorSide] = useState<AnchorSide>("right");

return (
<VuiPopover
isOpen={isOpen}
setIsOpen={() => setIsOpen(!isOpen)}
header="Tribes"
button={
<VuiButtonSecondary
color="neutral"
size="s"
icon={
<VuiIcon size="m">
<BiCaretDown />
</VuiIcon>
}
>
Tribe: {selectedOption}
</VuiButtonSecondary>
}
>
<VuiOptionsList
isSelectable
isScrollable
onSelectOption={(value: string) => {
setIsOpen(false);
setSelectedOption(value);
}}
selected={selectedOption}
options={options}
/>
</VuiPopover>
<>
<VuiFormGroup labelFor="anchorSideSelect" label="Anchor side">
<VuiSelect
id="anchorSideSelect"
options={[
{ text: "Left", value: "left" },
{ text: "Right", value: "right" }
]}
value={anchorSide}
onChange={(event) => setAnchorSide(event.target.value as AnchorSide)}
/>
</VuiFormGroup>

<VuiSpacer size="m" />

<VuiPopover
anchorSide={anchorSide}
isOpen={isOpen}
setIsOpen={() => setIsOpen(!isOpen)}
header="Tribes"
button={
<VuiButtonSecondary
color="neutral"
size="s"
icon={
<VuiIcon size="m">
<BiCaretDown />
</VuiIcon>
}
>
Tribe: {selectedOption}
</VuiButtonSecondary>
}
>
<VuiOptionsList
isSelectable
isScrollable
onSelectOption={(value: string) => {
setIsOpen(false);
setSelectedOption(value);
}}
selected={selectedOption}
options={options}
/>
</VuiPopover>
</>
);
};
43 changes: 43 additions & 0 deletions src/docs/pages/searchSelect/SingleSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useState } from "react";
import { VuiButtonSecondary, VuiSearchSelect } from "../../../lib";

const options = [
{ value: "a", label: "Caffeine-free" },
{ value: "b", label: "Freeze dried" },
{ value: "c", label: "Gluten-free" },
{ value: "d", label: "Halal" },
{ value: "e", label: "High fiber" },
{ value: "f", label: "Kosher" },
{ value: "g", label: "Lactose-free" },
{ value: "h", label: "Low-carb" },
{ value: "i", label: "No nuts" },
{ value: "j", label: "Non-GMO" },
{ value: "k", label: "Sugar-free" },
{ value: "l", label: "Vegan" }
];

export const SingleSelect = () => {
const [isOpen, setIsOpen] = useState(false);
const [searchValue, setSearchValue] = useState<string>("");
const [selectedOptions, setSelectedOptions] = useState(["a"]);

return (
<VuiSearchSelect
title="Choose one or none"
isOpen={isOpen}
setIsOpen={setIsOpen}
searchValue={searchValue}
setSearchValue={setSearchValue}
onSelect={(value: string[]) => {
setSelectedOptions(value);
}}
selectedOptions={selectedOptions}
options={options}
isMultiSelect={false}
>
<VuiButtonSecondary color="neutral" size="s">
Meal preference
</VuiButtonSecondary>
</VuiSearchSelect>
);
};
9 changes: 9 additions & 0 deletions src/docs/pages/searchSelect/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
import { SearchSelect } from "./SearchSelect";
import { Async } from "./Async";
import { SingleSelect } from "./SingleSelect";

const SearchSelectSource = require("!!raw-loader!./SearchSelect");
const AsyncSource = require("!!raw-loader!./Async");
const SingleSelectSource = require("!!raw-loader!./SingleSelect");

export const searchSelect = {
name: "Search Select",
path: "/searchSelect",
examples: [
{
name: "Synchronous search",
component: <SearchSelect />,
source: SearchSelectSource.default.toString()
},
{
name: "Asynchronous search",
component: <Async />,
source: AsyncSource.default.toString()
},
{
name: "Single selection",
component: <SingleSelect />,
source: SingleSelectSource.default.toString()
}
]
};
84 changes: 73 additions & 11 deletions src/lib/components/code/Code.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from "react";
import { useEffect, useState } from "react";
import Prism from "prismjs";
import "prismjs/themes/prism.css";
import "prismjs/components/prism-json";
Expand All @@ -8,24 +8,36 @@ import "prismjs/components/prism-bash";
import "prismjs/components/prism-jsx";
import "prismjs/components/prism-tsx";
import classNames from "classnames";
import { BiClipboard } from "react-icons/bi";
import { BiClipboard, BiFullscreen, BiX } from "react-icons/bi";
import { VuiIconButton } from "../button/IconButton";
import { VuiIcon } from "../icon/Icon";
import { CodeLanguage } from "./types";
import { VuiFlexContainer } from "../flex/FlexContainer";
import { FocusOn } from "react-focus-on";

type Props = {
language?: CodeLanguage;
onCopy?: () => void;
isFullscreenEnabled?: boolean;
children?: string;
fullHeight?: boolean;
"data-testid"?: string;
};

// PrismJS clears highlighting when language-none is set.
export const VuiCode = ({ onCopy, language = "none", fullHeight, children = "", ...rest }: Props) => {
export const VuiCode = ({
onCopy,
isFullscreenEnabled = true,
language = "none",
fullHeight,
children = "",
...rest
}: Props) => {
const [isFullscreen, setIsFullscreen] = useState(false);

useEffect(() => {
Prism.highlightAll();
}, [children, language]);
}, [children, language, isFullscreen]);

const containerClasses = classNames("vuiCodeContainer", {
"vuiCodeContainer--fullHeight": fullHeight
Expand All @@ -37,33 +49,83 @@ export const VuiCode = ({ onCopy, language = "none", fullHeight, children = "",

const testId = rest["data-testid"];

return (
<div className={containerClasses} {...rest}>
<pre className="vuiCodePre">
<code className={classes}>{children}</code>
</pre>
const actions = (
<VuiFlexContainer className="vuiCodeActions" spacing="xxs">
{isFullscreenEnabled && (
<VuiIconButton
color="neutral"
size="xs"
icon={
<VuiIcon>
<BiFullscreen />
</VuiIcon>
}
aria-label="Full screen"
onClick={() => {
setIsFullscreen(!isFullscreen);
}}
/>
)}

<VuiIconButton
color="neutral"
size="xs"
icon={
<VuiIcon>
<BiClipboard size={20} />
<BiClipboard />
</VuiIcon>
}
aria-label="Copy to clipboard"
className="vuiCodeCopyButton"
onClick={() => {
navigator.clipboard.writeText(children);
if (onCopy) onCopy();
}}
/>
</VuiFlexContainer>
);

const code = (
<pre className="vuiCodePre">
<code className={classes}>{children}</code>
</pre>
);

return (
<div className={containerClasses} {...rest}>
{code}

{actions}

{/* Expose this for tests to assert against. */}
{testId && (
<div data-testid={`${testId}-hidden`} hidden>
{children}
</div>
)}

{isFullscreen && (
<FocusOn
onEscapeKey={() => {
setIsFullscreen(false);
}}
>
<div className="vuiCodeFullscreen">
<VuiIconButton
className="vuiCodeFullscreen__closeButton"
color="neutral"
size="m"
icon={
<VuiIcon>
<BiX />
</VuiIcon>
}
aria-label="Exit fullscreen code"
onClick={() => setIsFullscreen(false)}
/>
{code}
</div>
</FocusOn>
)}
</div>
);
};
22 changes: 20 additions & 2 deletions src/lib/components/code/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
max-height: 100%;
}

.vuiCodeCopyButton {
.vuiCodeActions {
position: absolute;
right: $sizeXxs;
right: $sizeS;
top: $sizeXxs;
}

Expand All @@ -31,3 +31,21 @@
white-space: pre-wrap;
font-size: $fontSizeSmall !important;
}

.vuiCodeFullscreen {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: $fullscreenZIndex;
// PrismJS theme color.
background-color: #f5f2f0;
overflow: auto;
}

.vuiCodeFullscreen__closeButton {
position: absolute;
right: $sizeS;
top: $sizeXxs;
}
Loading
Loading