Migrate landing page to app dir (#1587)

* app dir yay

* better docs route

* fix icon sizing

* mobile sidebars

* detect webgl in useEffect

* separate zxcvbn
This commit is contained in:
Brendan Allan
2023-10-16 12:28:16 +08:00
committed by GitHub
parent 4b37d71efe
commit 151c26dfd3
29 changed files with 100 additions and 24 deletions

View File

@@ -20,7 +20,7 @@ import {
} from '@sd/interface';
import { getSpacedropState } from '@sd/interface/hooks/useSpacedropState';
import '@sd/ui/style';
import '@sd/ui/style/style.scss';
import * as commands from './commands';
import { createUpdater } from './updater';

View File

@@ -1,6 +1,6 @@
import type { Preview } from '@storybook/react';
import '@sd/ui/style';
import '@sd/ui/style.scss';
const preview: Preview = {
parameters: {

View File

@@ -2,7 +2,7 @@
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import '@sd/ui/style';
import '@sd/ui/style/style.scss';
import '~/patches';
import App from './App';

View File

@@ -1,12 +1,29 @@
import clsx from 'clsx';
import { getPasswordStrength } from '@sd/client';
import { useEffect, useState } from 'react';
import { type getPasswordStrength } from '@sd/client';
export interface PasswordMeterProps {
password: string;
}
export const PasswordMeter = (props: PasswordMeterProps) => {
const { score, scoreText } = getPasswordStrength(props.password);
const [getStrength, setGetStrength] = useState<typeof getPasswordStrength | undefined>();
const { score, scoreText } = getStrength
? getStrength(props.password)
: { score: 0, scoreText: 'Loading...' };
useEffect(() => {
let cancelled = false;
import('@sd/client').then(({ getPasswordStrength }) => {
if (cancelled) return;
setGetStrength(() => getPasswordStrength);
});
return () => {
cancelled = true;
};
}, []);
return (
<div className="relative">

View File

@@ -3,6 +3,7 @@
"private": true,
"main": "index.tsx",
"types": "index.tsx",
"sideEffects": false,
"scripts": {
"lint": "eslint . --cache",
"typecheck": "tsc -b"
@@ -10,7 +11,7 @@
"dependencies": {
"@fontsource/inter": "^4.5.13",
"@headlessui/react": "^1.7.3",
"@icons-pack/react-simple-icons": "^7.2.0",
"@icons-pack/react-simple-icons": "^9.1.0",
"@phosphor-icons/react": "^2.0.10",
"@radix-ui/react-progress": "^1.0.1",
"@radix-ui/react-slider": "^1.1.0",

View File

@@ -3,6 +3,7 @@
"version": "1.0.0",
"license": "GPL-3.0-only",
"private": true,
"sideEffects": false,
"scripts": {
"gen": "node ./scripts/generate.mjs"
}

View File

@@ -3,6 +3,8 @@
* To regenerate this file, run: pnpm assets gen
*/
'use client';
import { ReactComponent as Academia } from './Academia.svg';
import { ReactComponent as Apple } from './apple.svg';
import { ReactComponent as Discord } from './Discord.svg';

View File

@@ -1,6 +1,7 @@
{
"name": "@sd/client",
"private": true,
"sideEffects": false,
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {

View File

@@ -4,6 +4,7 @@
"license": "GPL-3.0-only",
"main": "src/index.ts",
"types": "src/index.ts",
"sideEffects": false,
"exports": {
".": "./src/index.ts",
"./src/forms": "./src/forms/index.ts",

View File

@@ -1,9 +1,11 @@
'use client';
import { cva, cx, VariantProps } from 'class-variance-authority';
import clsx from 'clsx';
import { ComponentProps, forwardRef } from 'react';
import { Link } from 'react-router-dom';
export interface ButtonBaseProps extends VariantProps<typeof styles> {}
export interface ButtonBaseProps extends VariantProps<typeof buttonStyles> {}
export type ButtonProps = ButtonBaseProps &
React.ButtonHTMLAttributes<HTMLButtonElement> & {
@@ -22,7 +24,7 @@ type Button = {
const hasHref = (props: ButtonProps | LinkButtonProps): props is LinkButtonProps => 'href' in props;
export const styles = cva(
export const buttonStyles = cva(
[
'cursor-default items-center rounded-md border outline-none transition-colors duration-100',
'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-70',
@@ -73,7 +75,7 @@ export const Button = forwardRef<
HTMLButtonElement | HTMLAnchorElement,
ButtonProps | LinkButtonProps
>(({ className, ...props }, ref) => {
className = cx(styles(props), className);
className = cx(buttonStyles(props), className);
return hasHref(props) ? (
<a {...props} ref={ref as any} className={cx(className, 'inline-block no-underline')} />
) : (
@@ -88,7 +90,7 @@ export const ButtonLink = forwardRef<
return (
<Link
ref={ref}
className={styles({
className={buttonStyles({
size,
variant,
className: clsx(

View File

@@ -1,3 +1,5 @@
'use client';
import { Check } from '@phosphor-icons/react';
import * as Checkbox from '@radix-ui/react-checkbox';
import { cva, VariantProps } from 'class-variance-authority';

View File

@@ -1,3 +1,5 @@
'use client';
import { CaretRight, Check, Icon, IconProps } from '@phosphor-icons/react';
import * as RadixCM from '@radix-ui/react-context-menu';
import { cva, VariantProps } from 'class-variance-authority';

View File

@@ -1,3 +1,5 @@
'use client';
import * as RDialog from '@radix-ui/react-dialog';
import { animated, useTransition } from '@react-spring/web';
import clsx from 'clsx';

View File

@@ -1,3 +1,5 @@
'use client';
import { Menu, Transition } from '@headlessui/react';
import { ReactComponent as CaretDown } from '@sd/assets/svgs/caret.svg';
import { cva, VariantProps } from 'class-variance-authority';

View File

@@ -1,3 +1,5 @@
'use client';
import * as RadixDM from '@radix-ui/react-dropdown-menu';
import clsx from 'clsx';
import React, {

View File

@@ -1,3 +1,5 @@
'use client';
import { Eye, EyeSlash, Icon, IconProps, MagnifyingGlass } from '@phosphor-icons/react';
import { cva, VariantProps } from 'class-variance-authority';
import clsx from 'clsx';

View File

@@ -1,3 +1,5 @@
'use client';
import * as Radix from '@radix-ui/react-popover';
import clsx from 'clsx';
import React, { useEffect, useRef, useState } from 'react';

View File

@@ -1,3 +1,5 @@
'use client';
import * as ProgressPrimitive from '@radix-ui/react-progress';
import clsx from 'clsx';
import { memo } from 'react';

View File

@@ -1,3 +1,5 @@
'use client';
/* eslint-disable tailwindcss/migration-from-tailwind-2 */
import * as RadioGroup from '@radix-ui/react-radio-group';
import clsx from 'clsx';

View File

@@ -1,3 +1,5 @@
'use client';
import { Check } from '@phosphor-icons/react';
import * as RS from '@radix-ui/react-select';
import { ReactComponent as ChevronDouble } from '@sd/assets/svgs/chevron-double.svg';

View File

@@ -1,3 +1,5 @@
'use client';
import * as SliderPrimitive from '@radix-ui/react-slider';
import clsx from 'clsx';

View File

@@ -1,3 +1,5 @@
'use client';
import * as SwitchPrimitive from '@radix-ui/react-switch';
import { cva, VariantProps } from 'class-variance-authority';
import { forwardRef } from 'react';

View File

@@ -1,3 +1,5 @@
'use client';
import * as TabsPrimitive from '@radix-ui/react-tabs';
import { tw } from './utils';

View File

@@ -1,3 +1,5 @@
'use client';
import { CheckCircle, Icon, Info, Warning, WarningCircle, X } from '@phosphor-icons/react';
import clsx from 'clsx';
import { CSSProperties, ForwardedRef, forwardRef, ReactNode, useEffect, useState } from 'react';

View File

@@ -1,3 +1,5 @@
'use client';
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
import clsx from 'clsx';
import { PropsWithChildren, ReactNode } from 'react';

View File

@@ -1,6 +1,3 @@
import { zxcvbn, zxcvbnOptions } from '@zxcvbn-ts/core';
import zxcvbnCommonPackage from '@zxcvbn-ts/language-common';
import zxcvbnEnPackage from '@zxcvbn-ts/language-en';
import clsx from 'clsx';
import { forwardRef, useEffect, useState } from 'react';
import { useFormContext } from 'react-hook-form';
@@ -29,29 +26,48 @@ export interface PasswordInputProps extends UseFormFieldProps, Root.InputProps {
}
const PasswordStrengthMeter = (props: { password: string }) => {
const [zxcvbn, setZxcvbn] = useState<typeof import('./zxcvbn') | undefined>();
const [strength, setStrength] = useState<{ label: string; score: number }>();
const updateStrength = useDebouncedCallback(
() => setStrength(props.password ? getPasswordStrength(props.password) : undefined),
100
);
const updateStrength = useDebouncedCallback(() => {
if (!zxcvbn) return;
setStrength(props.password ? getPasswordStrength(props.password, zxcvbn) : undefined);
}, 100);
// TODO: Remove duplicate in @sd/client
function getPasswordStrength(password: string): { label: string; score: number } {
function getPasswordStrength(
password: string,
zxcvbn: typeof import('./zxcvbn')
): { label: string; score: number } {
const ratings = ['Poor', 'Weak', 'Good', 'Strong', 'Perfect'];
zxcvbnOptions.setOptions({
zxcvbn.zxcvbnOptions.setOptions({
dictionary: {
...zxcvbnCommonPackage.dictionary,
...zxcvbnEnPackage.dictionary
...zxcvbn.languageCommon.dictionary,
...zxcvbn.languageEn.dictionary
},
graphs: zxcvbnCommonPackage.adjacencyGraphs,
translations: zxcvbnEnPackage.translations
graphs: zxcvbn.languageCommon.adjacencyGraphs,
translations: zxcvbn.languageEn.translations
});
const result = zxcvbn(password);
const result = zxcvbn.zxcvbn(password);
return { label: ratings[result.score]!, score: result.score };
}
useEffect(() => {
let cancelled = false;
import('./zxcvbn').then((zxcvbn) => {
if (cancelled) return;
setZxcvbn(zxcvbn);
});
return () => {
cancelled = true;
};
}, []);
useEffect(() => updateStrength(), [props.password, updateStrength]);
return (

View File

@@ -1,3 +1,5 @@
'use client';
export * from './Form';
export * from './FormField';
export * from './CheckBoxField';

View File

@@ -0,0 +1,3 @@
export { zxcvbn, zxcvbnOptions } from '@zxcvbn-ts/core';
export { default as languageCommon } from '@zxcvbn-ts/language-common';
export { default as languageEn } from '@zxcvbn-ts/language-en';

BIN
pnpm-lock.yaml generated
View File

Binary file not shown.