Compare commits

...
12 Commits
Author SHA1 Message Date
Zach Kelling 8234208d93 Remove exports 2024-01-23 15:05:08 +01:00
Zach Kelling b5f072a532 v0.1.27 2024-01-23 15:02:21 +01:00
Zach Kelling 4772c4d946 Update package.json 2024-01-23 15:02:03 +01:00
artemis prime 5a42595a62 esm /cjs error 2024-01-23 00:18:56 -08:00
artemis prime a81a427a7f all but styles and fonts 2024-01-22 19:19:41 -08:00
artemis prime 9b7f4f2b7d previous 2024-01-21 20:37:18 -08:00
artemis prime 8152a17252 previous 2024-01-21 18:20:42 -08:00
artemis prime 6a606a524e creacted clean script for all and clean:all 2024-01-21 18:17:12 -08:00
artemis prime 79e63f8cf3 fixed web build and and tsconfig trees 2024-01-21 11:50:55 -08:00
artemis prime 8d0bfcd32e ui building 2024-01-21 11:31:15 -08:00
artemis prime 4f310fdd1f initial replacement of desired /ui contents 2024-01-21 10:21:58 -08:00
artemis prime 3e9774d75d removed previous /ui 2024-01-21 10:20:22 -08:00
63 changed files with 3313 additions and 3908 deletions
+5 -1
View File
@@ -33,4 +33,8 @@ yarn-error.log*
.turbo
.contentlayer
tsconfig.tsbuildinfo
tsconfig.tsbuildinfo
**/dist
**/.npmrc
-10
View File
@@ -1,10 +0,0 @@
{
"eslint.workingDirectories": [
{ "pattern": "apps/*/" },
{ "pattern": "packages/*/" }
],
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
]
}
+4 -3
View File
@@ -1,5 +1,5 @@
{
"name": "www",
"name": "@luxdefi/ui-demo-www",
"version": "0.0.1",
"private": true,
"scripts": {
@@ -13,7 +13,8 @@
"preview": "next build && next start -p 3001",
"typecheck": "contentlayer build && tsc --noEmit",
"format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache"
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache",
"clean": "rm -rf .next && rm -rf node_modules && rm -rf .contentlayer"
},
"dependencies": {
"@faker-js/faker": "^8.2.0",
@@ -81,7 +82,7 @@
"devDependencies": {
"@types/lodash.template": "^4.5.1",
"@types/node": "^17.0.45",
"@types/react": "^18.2.7",
"@types/react": "^18.2.48",
"@types/react-color": "^3.0.6",
"@types/react-dom": "^18.2.4",
"esbuild": "^0.17.19",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"extends": "../../tsconfig.base.shadcn.json",
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
+33
View File
@@ -0,0 +1,33 @@
"_dependencies": {
"@babel/core": "^7.22.1",
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.1",
"@commitlint/cli": "^17.6.3",
"@commitlint/config-conventional": "^17.6.3",
"@ianvs/prettier-plugin-sort-imports": "^3.7.2",
"@manypkg/cli": "^0.20.0",
"@types/node": "^17.0.45",
"@types/react": "^18.2.7",
"@types/react-dom": "^18.2.4",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "^10.4.14",
"concurrently": "^8.0.1",
"cross-env": "^7.0.3",
"eslint": "^8.41.0",
"eslint-config-next": "13.3.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-turbo": "^1.9.9",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-tailwindcss": "^3.12.0",
"postcss": "^8.4.24",
"prettier": "^2.8.8",
"pretty-quick": "^3.1.3",
"tailwindcss": "^3.4.0",
"tailwindcss-animate": "^1.0.5",
"ts-node": "^10.9.1",
"turbo": "^1.9.9",
"typescript": "^4.9.5",
"vite-tsconfig-paths": "^4.2.0",
"vitest": "^0.31.1"
}
+12 -42
View File
@@ -1,5 +1,5 @@
{
"name": "@luxdefi/ui/cli",
"name": "@luxdefi/ui-mono",
"version": "0.0.1",
"license": "MIT",
"type": "module",
@@ -7,18 +7,13 @@
"name": "@lx/ui",
"url": "https://twitter.com/luxdefi"
},
"workspaces": [
"apps/*",
"packages/*",
"templates/*"
],
"scripts": {
"build": "turbo run build",
"build:cli": "turbo --filter=luxdefi-ui build",
"build:cli": "turbo --filter=@luxdefi/uicli build",
"build:registry": "pnpm --filter=www build:registry",
"dev": "turbo run dev --parallel",
"dev:cli": "turbo --filter=luxdefi-ui dev",
"start:cli": "pnpm --filter=luxdefi-ui start:dev",
"dev:cli": "turbo --filter=@luxdefi/uicli dev",
"start:cli": "pnpm --filter=@luxdefi/uicli start:dev",
"lint": "turbo run lint",
"lint:fix": "turbo run lint:fix",
"preview": "turbo run preview",
@@ -31,40 +26,15 @@
"release": "changeset version",
"pub:beta": "cd packages/cli && pnpm pub:beta",
"pub:release": "cd packages/cli && pnpm pub:release",
"test": "turbo run test --force"
"test": "turbo run test --force",
"clean:all": "rm -rf node_modules && pnpm -r clean"
},
"packageManager": "pnpm@8.5.1",
"packageManager": "pnpm@8.14.1",
"dependencies": {
"@babel/core": "^7.22.1",
"@changesets/changelog-github": "^0.4.8",
"@changesets/cli": "^2.26.1",
"@commitlint/cli": "^17.6.3",
"@commitlint/config-conventional": "^17.6.3",
"@ianvs/prettier-plugin-sort-imports": "^3.7.2",
"@manypkg/cli": "^0.20.0",
"@types/node": "^17.0.45",
"@types/react": "^18.2.7",
"@types/react-dom": "^18.2.4",
"@typescript-eslint/parser": "^5.59.7",
"autoprefixer": "^10.4.14",
"concurrently": "^8.0.1",
"cross-env": "^7.0.3",
"eslint": "^8.41.0",
"eslint-config-next": "13.3.0",
"eslint-config-prettier": "^8.8.0",
"eslint-config-turbo": "^1.9.9",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-tailwindcss": "^3.12.0",
"husky": "^8.0.3",
"postcss": "^8.4.24",
"prettier": "^2.8.8",
"pretty-quick": "^3.1.3",
"tailwindcss": "^3.4.0",
"tailwindcss-animate": "^1.0.5",
"ts-node": "^10.9.1",
"turbo": "^1.9.9",
"typescript": "^4.9.5",
"vite-tsconfig-paths": "^4.2.0",
"vitest": "^0.31.1"
"husky": "^8.0.3"
},
"devDependencies": {
"typescript": "^5.3.3",
"ts-node": "^10.9.1"
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
{
"name": "@luxdefi/ui/cli",
"name": "@luxdefi/uicli",
"version": "0.6.0",
"description": "Add components to your apps.",
"publishConfig": {
@@ -32,7 +32,7 @@
"dev": "tsup --watch",
"build": "tsup",
"typecheck": "tsc --noEmit",
"clean": "rimraf dist && rimraf components",
"clean": "rm -rf dist && rm -rf node_modules",
"start:dev": "cross-env COMPONENTS_REGISTRY_URL=http://localhost:3001 node dist/index.js",
"start": "node dist/index.js",
"format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache",
+1 -1
View File
@@ -19,7 +19,7 @@
"@types/eslint": "^8.37.0",
"@types/node": "^18.16.0",
"@types/prettier": "^2.7.2",
"@types/react": "^18.2.6",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.4",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "../../tsconfig.json",
"extends": "../../tsconfig.base.shadcn.json",
"compilerOptions": {
"isolatedModules": false,
"baseUrl": ".",
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 831 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@@ -0,0 +1,158 @@
/**
*
* Metadata types
*
*/
export interface DeprecatedMetadataFields {
/**
* Deprecated options that have a preferred method
* @deprecated Use appWebApp to configure apple-mobile-web-app-capable which provides
* @see https://www.appsloveworld.com/coding/iphone/11/difference-between-apple-mobile-web-app-capable-and-apple-touch-fullscreen-ipho
*/
'apple-touch-fullscreen'?: never
/**
* Obsolete since iOS 7.
* @see https://web.dev/apple-touch-icon/
* @deprecated use icons.apple or instead
*/
'apple-touch-icon-precomposed'?: never
}
export type TemplateString =
| DefaultTemplateString
| AbsoluteTemplateString
| AbsoluteString
export type DefaultTemplateString = {
default: string
template: string
}
export type AbsoluteTemplateString = {
absolute: string
template: string | null
}
export type AbsoluteString = {
absolute: string
}
export type Author = {
// renders as <link rel="author"...
url?: string | URL
// renders as <meta name="author"...
name?: string
}
// does not include "unsafe-URL". to use this users should
// use '"unsafe-URL" as ReferrerEnum'
export type ReferrerEnum =
| 'no-referrer'
| 'origin'
| 'no-referrer-when-downgrade'
| 'origin-when-cross-origin'
| 'same-origin'
| 'strict-origin'
| 'strict-origin-when-cross-origin'
export type ColorSchemeEnum =
| 'normal'
| 'light'
| 'dark'
| 'light dark'
| 'dark light'
| 'only light'
type RobotsInfo = {
// all and none will be inferred from index/follow boolean options
index?: boolean
follow?: boolean
/** @deprecated set index to false instead */
noindex?: never
/** @deprecated set follow to false instead */
nofollow?: never
noarchive?: boolean
nosnippet?: boolean
noimageindex?: boolean
nocache?: boolean
notranslate?: boolean
indexifembedded?: boolean
nositelinkssearchbox?: boolean
unavailable_after?: string
'max-video-preview'?: number | string
'max-image-preview'?: 'none' | 'standard' | 'large'
'max-snippet'?: number
}
export type Robots = RobotsInfo & {
// if you want to specify an alternate robots just for google
googleBot?: string | RobotsInfo
}
export type ResolvedRobots = {
basic: string | null
googleBot: string | null
}
export type IconURL = string | URL
export type Icon = IconURL | IconDescriptor
export type IconDescriptor = {
url: string | URL
type?: string
sizes?: string
color?: string
/** defaults to rel="icon" unless superseded by Icons map */
rel?: string
media?: string
/**
* @see https://developer.mozilla.org/docs/Web/API/HTMLImageElement/fetchPriority
*/
fetchPriority?: 'high' | 'low' | 'auto'
}
export type Icons = {
/** rel="icon" */
icon?: Icon | Icon[]
/** rel="shortcut icon" */
shortcut?: Icon | Icon[]
/**
* @see https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/ConfiguringWebApplications/ConfiguringWebApplications.html
* rel="apple-touch-icon"
*/
apple?: Icon | Icon[]
/** rel inferred from descriptor, defaults to "icon" */
other?: IconDescriptor | IconDescriptor[]
}
export type Verification = {
google?: null | string | number | (string | number)[]
yahoo?: null | string | number | (string | number)[]
yandex?: null | string | number | (string | number)[]
me?: null | string | number | (string | number)[]
// if you ad-hoc additional verification
other?: {
[name: string]: string | number | (string | number)[]
}
}
export type ResolvedVerification = {
google?: null | (string | number)[]
yahoo?: null | (string | number)[]
yandex?: null | (string | number)[]
me?: null | (string | number)[]
other?: {
[name: string]: (string | number)[]
}
}
export type ResolvedIcons = {
icon: IconDescriptor[]
apple: IconDescriptor[]
shortcut?: IconDescriptor[]
other?: IconDescriptor[]
}
export type ThemeColorDescriptor = {
color: string
media?: string
}
@@ -0,0 +1,267 @@
import type { AbsoluteTemplateString, TemplateString } from './metadata-types'
export type OpenGraphType =
| 'article'
| 'book'
| 'music.song'
| 'music.album'
| 'music.playlist'
| 'music.radio_station'
| 'profile'
| 'website'
| 'video.tv_show'
| 'video.other'
| 'video.movie'
| 'video.episode'
export type OpenGraph =
| OpenGraphWebsite
| OpenGraphArticle
| OpenGraphBook
| OpenGraphProfile
| OpenGraphMusicSong
| OpenGraphMusicAlbum
| OpenGraphMusicPlaylist
| OpenGraphRadioStation
| OpenGraphVideoMovie
| OpenGraphVideoEpisode
| OpenGraphVideoTVShow
| OpenGraphVideoOther
| OpenGraphMetadata
// update this type to reflect actual locales
type Locale = string
type OpenGraphMetadata = {
determiner?: 'a' | 'an' | 'the' | 'auto' | ''
title?: string | TemplateString
description?: string
emails?: string | Array<string>
phoneNumbers?: string | Array<string>
faxNumbers?: string | Array<string>
siteName?: string
locale?: Locale
alternateLocale?: Locale | Array<Locale>
images?: OGImage | Array<OGImage>
audio?: OGAudio | Array<OGAudio>
videos?: OGVideo | Array<OGVideo>
url?: string | URL
countryName?: string
ttl?: number
}
export type OpenGraphWebsite = OpenGraphMetadata & {
type: 'website'
}
type OpenGraphArticle = OpenGraphMetadata & {
type: 'article'
publishedTime?: string // datetime
modifiedTime?: string // datetime
expirationTime?: string // datetime
authors?: null | string | URL | Array<string | URL>
section?: null | string
tags?: null | string | Array<string>
}
type OpenGraphBook = OpenGraphMetadata & {
type: 'book'
isbn?: null | string
releaseDate?: null | string // datetime
authors?: null | string | URL | Array<string | URL>
tags?: null | string | Array<string>
}
type OpenGraphProfile = OpenGraphMetadata & {
type: 'profile'
firstName?: null | string
lastName?: null | string
username?: null | string
gender?: null | string
}
type OpenGraphMusicSong = OpenGraphMetadata & {
type: 'music.song'
duration?: null | number
albums?: null | string | URL | OGAlbum | Array<string | URL | OGAlbum>
musicians?: null | string | URL | Array<string | URL>
}
type OpenGraphMusicAlbum = OpenGraphMetadata & {
type: 'music.album'
songs?: null | string | URL | OGSong | Array<string | URL | OGSong>
musicians?: null | string | URL | Array<string | URL>
releaseDate?: null | string // datetime
}
type OpenGraphMusicPlaylist = OpenGraphMetadata & {
type: 'music.playlist'
songs?: null | string | URL | OGSong | Array<string | URL | OGSong>
creators?: null | string | URL | Array<string | URL>
}
type OpenGraphRadioStation = OpenGraphMetadata & {
type: 'music.radio_station'
creators?: null | string | URL | Array<string | URL>
}
type OpenGraphVideoMovie = OpenGraphMetadata & {
type: 'video.movie'
actors?: null | string | URL | OGActor | Array<string | URL | OGActor>
directors?: null | string | URL | Array<string | URL>
writers?: null | string | URL | Array<string | URL>
duration?: null | number
releaseDate?: null | string // datetime
tags?: null | string | Array<string>
}
type OpenGraphVideoEpisode = OpenGraphMetadata & {
type: 'video.episode'
actors?: null | string | URL | OGActor | Array<string | URL | OGActor>
directors?: null | string | URL | Array<string | URL>
writers?: null | string | URL | Array<string | URL>
duration?: null | number
releaseDate?: null | string // datetime
tags?: null | string | Array<string>
series?: null | string | URL
}
type OpenGraphVideoTVShow = OpenGraphMetadata & {
type: 'video.tv_show'
}
type OpenGraphVideoOther = OpenGraphMetadata & {
type: 'video.other'
}
export type OGImage = string | OGImageDescriptor | URL
type OGImageDescriptor = {
url: string | URL
secureUrl?: string | URL
alt?: string
type?: string
width?: string | number
height?: string | number
}
type OGAudio = string | OGAudioDescriptor | URL
type OGAudioDescriptor = {
url: string | URL
secureUrl?: string | URL
type?: string
}
type OGVideo = string | OGVideoDescriptor | URL
type OGVideoDescriptor = {
url: string | URL
secureUrl?: string | URL
type?: string
width?: string | number
height?: string | number
}
export type ResolvedOpenGraph =
| ResolvedOpenGraphWebsite
| ResolvedOpenGraphArticle
| ResolvedOpenGraphBook
| ResolvedOpenGraphProfile
| ResolvedOpenGraphMusicSong
| ResolvedOpenGraphMusicAlbum
| ResolvedOpenGraphMusicPlaylist
| ResolvedOpenGraphRadioStation
| ResolvedOpenGraphVideoMovie
| ResolvedOpenGraphVideoEpisode
| ResolvedOpenGraphVideoTVShow
| ResolvedOpenGraphVideoOther
| ResolvedOpenGraphMetadata
type ResolvedOpenGraphMetadata = {
determiner?: 'a' | 'an' | 'the' | 'auto' | ''
title: AbsoluteTemplateString
description?: string
emails?: Array<string>
phoneNumbers?: Array<string>
faxNumbers?: Array<string>
siteName?: string
locale?: Locale
alternateLocale?: Array<Locale>
images?: Array<OGImage>
audio?: Array<OGAudio>
videos?: Array<OGVideo>
url: null | URL | string
countryName?: string
ttl?: number
}
type ResolvedOpenGraphWebsite = ResolvedOpenGraphMetadata & {
type: 'website'
}
type ResolvedOpenGraphArticle = ResolvedOpenGraphMetadata & {
type: 'article'
publishedTime?: string // datetime
modifiedTime?: string // datetime
expirationTime?: string // datetime
authors?: Array<string>
section?: string
tags?: Array<string>
}
type ResolvedOpenGraphBook = ResolvedOpenGraphMetadata & {
type: 'book'
isbn?: string
releaseDate?: string // datetime
authors?: Array<string>
tags?: Array<string>
}
type ResolvedOpenGraphProfile = ResolvedOpenGraphMetadata & {
type: 'profile'
firstName?: string
lastName?: string
username?: string
gender?: string
}
type ResolvedOpenGraphMusicSong = ResolvedOpenGraphMetadata & {
type: 'music.song'
duration?: number
albums?: Array<OGAlbum>
musicians?: Array<string | URL>
}
type ResolvedOpenGraphMusicAlbum = ResolvedOpenGraphMetadata & {
type: 'music.album'
songs?: Array<string | URL | OGSong>
musicians?: Array<string | URL>
releaseDate?: string // datetime
}
type ResolvedOpenGraphMusicPlaylist = ResolvedOpenGraphMetadata & {
type: 'music.playlist'
songs?: Array<string | URL | OGSong>
creators?: Array<string | URL>
}
type ResolvedOpenGraphRadioStation = ResolvedOpenGraphMetadata & {
type: 'music.radio_station'
creators?: Array<string | URL>
}
type ResolvedOpenGraphVideoMovie = ResolvedOpenGraphMetadata & {
type: 'video.movie'
actors?: Array<string | URL | OGActor>
directors?: Array<string | URL>
writers?: Array<string | URL>
duration?: number
releaseDate?: string // datetime
tags?: Array<string>
}
type ResolvedOpenGraphVideoEpisode = ResolvedOpenGraphMetadata & {
type: 'video.episode'
actors?: Array<string | URL | OGActor>
directors?: Array<string | URL>
writers?: Array<string | URL>
duration?: number
releaseDate?: string // datetime
tags?: Array<string>
series?: string | URL
}
type ResolvedOpenGraphVideoTVShow = ResolvedOpenGraphMetadata & {
type: 'video.tv_show'
}
type ResolvedOpenGraphVideoOther = ResolvedOpenGraphMetadata & {
type: 'video.other'
}
type OGSong = {
url: string | URL
disc?: number
track?: number
}
type OGAlbum = {
url: string | URL
disc?: number
track?: number
}
type OGActor = {
url: string | URL
role?: string
}
@@ -0,0 +1,92 @@
// Reference: https://developer.twitter.com/en/docs/twitter-for-websites/cards/overview/markup
import type { AbsoluteTemplateString, TemplateString } from './metadata-types'
export type Twitter =
| TwitterSummary
| TwitterSummaryLargeImage
| TwitterPlayer
| TwitterApp
| TwitterMetadata
type TwitterMetadata = {
// defaults to card="summary"
site?: string // username for account associated to the site itself
siteId?: string // id for account associated to the site itself
creator?: string // username for the account associated to the creator of the content on the site
creatorId?: string // id for the account associated to the creator of the content on the site
description?: string
title?: string | TemplateString
images?: TwitterImage | Array<TwitterImage>
}
type TwitterSummary = TwitterMetadata & {
card: 'summary'
}
type TwitterSummaryLargeImage = TwitterMetadata & {
card: 'summary_large_image'
}
type TwitterPlayer = TwitterMetadata & {
card: 'player'
players: TwitterPlayerDescriptor | Array<TwitterPlayerDescriptor>
}
type TwitterApp = TwitterMetadata & {
card: 'app'
app: TwitterAppDescriptor
}
export type TwitterAppDescriptor = {
id: {
iphone?: string | number
ipad?: string | number
googleplay?: string
}
url?: {
iphone?: string | URL
ipad?: string | URL
googleplay?: string | URL
}
name?: string
}
export type TwitterImage = string | TwitterImageDescriptor | URL
type TwitterImageDescriptor = {
url: string | URL
alt?: string
secureUrl?: string | URL
type?: string
width?: string | number
height?: string | number
}
type TwitterPlayerDescriptor = {
playerUrl: string | URL
streamUrl: string | URL
width: number
height: number
}
type ResolvedTwitterImage = {
url: string | URL
alt?: string
secureUrl?: string | URL
type?: string
width?: string | number
height?: string | number
}
type ResolvedTwitterSummary = {
site: string | null
siteId: string | null
creator: string | null
creatorId: string | null
description: string | null
title: AbsoluteTemplateString
images?: Array<ResolvedTwitterImage>
}
type ResolvedTwitterPlayer = ResolvedTwitterSummary & {
players: Array<TwitterPlayerDescriptor>
}
type ResolvedTwitterApp = ResolvedTwitterSummary & { app: TwitterAppDescriptor }
export type ResolvedTwitterMetadata =
| ({ card: 'summary' } & ResolvedTwitterSummary)
| ({ card: 'summary_large_image' } & ResolvedTwitterSummary)
| ({ card: 'player' } & ResolvedTwitterPlayer)
| ({ card: 'app' } & ResolvedTwitterApp)
+207
View File
@@ -0,0 +1,207 @@
import React from 'react'
import type { Metadata } from 'next'
import Head from "next/head"
import type {
IconDescriptor,
TemplateString,
Author,
ThemeColorDescriptor
} from './from-next/metadata-types'
import type { OpenGraph, OGImage } from './from-next/opengraph-types'
import type { Twitter, TwitterImage } from './from-next/twitter-types'
const getURLasString = (url: string | URL) => {
return (
(typeof url === 'string') ? (url as string) : (url.href)
)
}
// https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
const Icons: React.FC<{icons: IconDescriptor[]}> = ({
icons
}) => {
return <Head>
{icons.map(({url, ...rest}: IconDescriptor, index) => (
<link {...rest} href={getURLasString(url)} key={`icons-${index}`}/>
))}
</Head>
}
export const getTitleFromTemplateString = (title: string | TemplateString | null | undefined): string | null => {
if (!title) {
return null
}
if (typeof title === 'object') {
if ('default' in title) {
return title.default
}
else if ('absolute' in title) {
return title.absolute
}
}
return title as string
}
const Authors: React.FC<{
authors: null | undefined | Author | Array<Author>
}> = ({
authors
}) => {
const Author: React.FC<{author: Author}> = ({author}) => (<>
{author.name && <meta name="author" content={author.name} />}
{author.url && <link rel="author" href={getURLasString(author.url)}/>}
</>)
if (!authors) {
return null
}
if (Array.isArray(authors)) {
return (<>
{authors.map((el: Author, index) => (
<Author author={el} key={`authors-${index}`} />
))}
</>)
}
return (<Author author={authors as Author} />)
}
const Keywords: React.FC<{keywords: undefined | null | string | Array<string>}> = ({
keywords
}) => {
if (!keywords) return null
const content = (Array.isArray(keywords) ? keywords.join(', ') : keywords as string)
return (<meta name="keywords" content={content} />)
}
const ThemeColor: React.FC<{
thColors: null | undefined | string | ThemeColorDescriptor | ThemeColorDescriptor[]
}> = ({
thColors
}) => {
const ThColor: React.FC<{thColor: ThemeColorDescriptor}> = ({thColor}) => {
const toSpread: any = {
content: thColor.color
}
if ('media' in thColor) {
toSpread.media = thColor.media
}
return <meta name="theme-color" {...toSpread}/>
}
if (!thColors) {
return null
}
if (Array.isArray(thColors)) {
return (<>
{thColors.map((el: ThemeColorDescriptor, index) => (
<ThColor thColor={el} key={`theme-colors-${index}`} />
))}
</>)
}
else if (typeof thColors === 'string') {
<meta name="theme-color" content={thColors as string}/>
}
return (<ThColor thColor={thColors as ThemeColorDescriptor} />)
}
const Manifest: React.FC<{
manifest: undefined | null | string | URL
}> = ({
manifest
}) => (
manifest && (<link rel="manifest" href={getURLasString(manifest)}/>)
)
const getOGImageURL = (img: OGImage | undefined): string | null => {
if (!img) {
return null
}
if (typeof img === 'object' && 'url' in img) { // this is a OGImageDescriptor
return getURLasString(img.url)
}
return getURLasString(img) // this is a URL or string
}
const getTwitterImageURL = (img: TwitterImage | undefined): string | null => {
if (!img) {
return null
}
if (typeof img === 'object' && 'url' in img) { // this is a TwitterImageDescriptor
return getURLasString(img.url)
}
return getURLasString(img) // this is a URL or string
}
// https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
const OpenGraphComponent: React.FC<{
og: OpenGraph | undefined | null
}> = ({
og
}) => (og && (<Head>
{og.url && (<meta property="og:url" content={(typeof og.url === 'string') ? (og.url as string) : (og.url.href)} />)}
{(og as any).type && (<meta property="og:type" content={(og as any).type} />)}
{og.title && (<meta property="og:title" content={getTitleFromTemplateString(og.title)!} />)}
{og.description && (<meta property="og:description" content={og.description} />)}
{og.images && (<meta property="og:image" content={getOGImageURL(Array.isArray(og.images) ? og.images[0] : og.images)!} />)}
</Head>))
// https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
export const TwitterComponent: React.FC<{
tw: Twitter | undefined | null
}> = ({
tw
}) => (tw && (<Head>
{(tw as any).card && (<meta name="twitter:card" content={(tw as any).card} />)}
{tw.title && (<meta name="twitter:title" content={getTitleFromTemplateString(tw.title)!} />)}
{tw.description && (<meta name="twitter:description" content={tw.description} />)}
{tw.images && (<meta name="twitter:image" content={getTwitterImageURL(Array.isArray(tw.images) ? tw.images[0] : tw.images)!} />)}
{tw.site && (<meta name="twitter:site" content={tw.site} />)}
</Head>))
// For use with pages router only.
// App router does this automatically if you export the metadata object
// https://stackoverflow.com/questions/68746228/next-head-wont-render-meta-tags-inside-of-fragment
const HeadMetadataComponent: React.FC<{
metadata: Metadata
}> = ({
metadata
}) => {
const mainTitle = getTitleFromTemplateString(metadata.title)
return (<>
<Head>
{mainTitle && (<title>{mainTitle}</title>) /* must be here, directly under Head component */}
{metadata.description && (
<meta name="description" content={metadata.description} />
)}
{metadata.applicationName && (
<meta name="application-name" content={metadata.applicationName} />
)}
<Authors authors={metadata.authors} />
<Keywords keywords={metadata.keywords} />
<ThemeColor thColors={metadata.themeColor} />
<Manifest manifest={metadata.manifest} />
</Head>
{/* Icons: We only support this format for now */}
<Icons icons={metadata.icons as IconDescriptor[]} />
<OpenGraphComponent og={metadata.openGraph} />
<TwitterComponent tw={metadata.twitter} />
</>)
}
export default HeadMetadataComponent
+1
View File
@@ -9,6 +9,7 @@ export { default as ActionButton } from './action-button'
export { default as Copyright} from './copyright'
export { default as DrawerMenu} from './drawer-menu'
export { default as LinkElement} from './link-element'
export { default as HeadMetadata, getTitleFromTemplateString, TwitterComponent} from './head-metadata'
export { default as NavItems} from './nav-items'
export { default as YouTubeEmbed} from './youtube-embed'
+4 -3
View File
@@ -15,7 +15,7 @@ const LinkElement: React.FC<{
iconAfter?: boolean
}> = ({
def,
size = 'default',
size, // no default
onClick,
variant,
className = '',
@@ -54,8 +54,9 @@ const LinkElement: React.FC<{
variant: variant ? variant : (defVariant ? defVariant : 'link'),
size: (!defVariant || defVariant.includes('link') || variant?.includes('link')) ? 'link'
: (size ? size : defSize)
}),
(href ? '' : ' pointer-events-none') +
}
),
((href || onClick) ? '' : 'pointer-events-none'),
className
)}
{...toSpread}
+21 -7
View File
@@ -6,13 +6,13 @@ import { cn } from '../util'
import { Icons } from '../common'
const Logo: React.FC<{
size: TShirtSize
size?: TShirtSize
logoOnly?: boolean
href?: string
className?: string
}> = ({
size,
href='/',
href, // no default please
className='',
logoOnly=false
}) => {
@@ -38,14 +38,28 @@ const Logo: React.FC<{
classes.span = 'text-lg' + toAdd.span
}
const spanClasses = 'inline-block font-bold font-heading ' + classes.span
const linkClasses = 'flex items-center text-primary hover:text-primary-hover ' + className
const outerClasses = 'flex items-center ' + className
const spanClasses = 'inline-block font-bold font-heading text-foreground '
+ (href ? 'hover:text-accent ' : 'cursor-default ')
+ classes.span
return (
<Link href={href} className={linkClasses} >
const Inner: React.FC = () => (<>
<Icons.logo className={classes.icon} />
<span className={cn(spanClasses, ' text-inherit')}>LUX</span>
</Link>
</>)
return (
href ? (
<Link href={href} className={outerClasses} >
<Inner />
</Link>
) : (
<span className={outerClasses} >
<Inner />
</span>
)
)
}
+1
View File
@@ -0,0 +1 @@
export { default as ThemeProvider } from './theme-provider'
@@ -5,7 +5,16 @@ import { ThemeProvider as NextThemesProvider } from "next-themes"
import { type ThemeProviderProps } from "next-themes/dist/types"
const ThemeProvider: React.FC<ThemeProviderProps> = ({ children, ...props }) => (
<NextThemesProvider {...props}>{children}</NextThemesProvider>
<NextThemesProvider
attribute="class"
{...props}
value={{
light: 'lux-light-theme',
dark: 'lux-dark-theme'
}}
>
{children}
</NextThemesProvider>
)
export default ThemeProvider
+46
View File
@@ -0,0 +1,46 @@
import esbuild from 'esbuild'
import mdx from '@mdx-js/esbuild'
import { nodeExternalsPlugin } from 'esbuild-node-externals'
import autoprefixer from "autoprefixer"
import tailwindcss from "autoprefixer"
import postCssPlugin from "esbuild-style-plugin"
const css = [
'./style/globals.css',
'./style/lux-tw-base-layer.css',
'./style/social-svg.css',
]
esbuild
.build({
entryPoints: [
{in: './primitives/index', out: 'primitives'},
{in: './util/index', out: 'util'},
{in: './common/index', out: 'common'},
{in: './types/index', out: 'types'},
{in: './next/index', out: 'next'},
{in: './next-fonts/index', out: 'next-fonts'},
{in: './context-providers/index', out: 'context-providers'},
{in: './blocks/index', out: 'blocks'},
{in: './tailwind/index', out: 'tailwind'},
...css
],
outdir: 'dist/esm',
bundle: true,
minify: false,
treeShaking: true,
format: 'esm',
target: ['chrome90', 'firefox74', 'safari14', 'edge90'],
plugins: [
nodeExternalsPlugin(),
mdx(),
postCssPlugin({
plugins: [tailwindcss, autoprefixer],
}),
],
})
.catch((error) => {
console.error(`esbuild build error: ${error}`)
process.exit(1)
})
-21
View File
@@ -1,21 +0,0 @@
export * from './util/index'
export * from './util/specifier'
export * from './common'
export {
type ButtonDef,
type Dimensions,
type SubmitServerAction,
type ButtonModalProps,
type ButtonModalDef,
type LinkDef,
type Icon,
type TShirtSize,
type Breakpoint,
type TShirtDimensions,
Breakpoints
} from './types'
export * from './primitives'
export * from './next'
+1 -1
View File
@@ -1,7 +1,7 @@
import React, { type PropsWithChildren } from 'react'
import { Metadata } from 'next'
import { inter, drukTextWide } from '../style/nextFonts'
import { inter, drukTextWide } from '../next-fonts'
import Header from '../common/header'
import SiteConf from '../types/site-conf'
+57 -12
View File
@@ -1,14 +1,51 @@
{
"name": "@luxdefi/ui",
"version": "0.1.0",
"version": "0.1.27",
"description": "Library that contains shared UI primitives, styles, and core types",
"main": "dist/index.js",
"license": "MIT",
"publishConfig": {
"registry": "https://registry.npmjs.org/",
"access": "public",
"scope": "@luxdefi"
},
"author": "Lux Partners Limited <dev@lux.partners> (https://lux.partners)",
"license": "BSD-3-Clause",
"repository": {
"type": "git",
"url": "git+https://github.com/luxdefi/ui.git",
"directory": "packages/ui"
},
"main": "./dist/index.js",
"module": "./dist/index.js",
"files": [
"assets",
"blocks",
"common",
"conf",
"context-providers",
"dist",
"next",
"next-fonts",
"primitives",
"style",
"tailwind",
"types",
"util"
],
"keywords": [
"components",
"ui",
"radix-ui",
"luxdefi"
],
"scripts": {
"build": "rm -rf dist && tsc",
"tc": "tsc --noEmit"
"build": "rm -rf dist && node ./esbuild.mjs && tsc",
"tc": "tsc --noEmit --emitDeclarationOnly false",
"clean": "rm -rf dist && rm -rf node_modules"
},
"dependencies": {
"@hookform/resolvers": "^3.3.2",
"@next/mdx": "^13.5.6",
"@radix-ui/react-accordion": "^1.1.2",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.0.2",
@@ -17,32 +54,40 @@
"@tailwindcss/container-queries": "^0.1.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"esbuild-style-plugin": "^1.6.3",
"lodash.castarray": "^4.4.0",
"lodash.isplainobject": "^4.0.6",
"lodash.merge": "^4.6.2",
"lucide-react": "^0.307.0",
"markdown-to-jsx": "^7.3.2",
"next": "^14.0.4",
"next-themes": "^0.2.1",
"postcss-selector-parser": "^6.0.13",
"react": "^18.2.0",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
"react-hook-form": "^7.47.0",
"react-social-icons": "^6.4.0",
"validator": "^13.11.0",
"zod": "3.21.4"
},
"peerDependencies": {
"next": "^14.0.4",
"next-themes": "^0.2.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwind-merge": "^2.2.0",
"tailwindcss": "^3.4.1",
"tailwindcss-animate": "^1.0.6",
"tailwindcss-interaction-media": "^0.1.0",
"validator": "^13.11.0",
"zod": "^3.22.4"
"tailwindcss-interaction-media": "^0.1.0"
},
"devDependencies": {
"@mdx-js/esbuild": "^3.0.0",
"@mdx-js/loader": "^2.3.0",
"@mdx-js/react": "^2.3.0",
"@types/mdx": "^2.0.9",
"@types/node": "^20.10.7",
"@types/react": "^18.2.47",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.18",
"autoprefixer": "^10.4.16",
"esbuild": "^0.17.19",
"esbuild-node-externals": "^1.12.0",
"postcss": "^8.4.33",
"postcss-import": "^16.0.0",
"typescript": "^5.3.3"
+5 -4
View File
@@ -5,9 +5,9 @@ import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "../util"
const variant = {
primary: "bg-primary text-primary-fg hover:bg-primary-hover font-heading whitespace-nowrap not-typography",
secondary: "bg-secondary text-secondary-fg hover:bg-secondary/80 font-heading whitespace-nowrap not-typography",
outline: "text-foreground border border-primary hover:bg-level-1 hover:text-accent font-heading whitespace-nowrap not-typography",
primary: "bg-primary-lux text-primary-fg hover:bg-primary-hover font-heading whitespace-nowrap not-typography",
secondary: "bg-secondary-lux text-secondary-fg hover:bg-secondary/80 font-heading whitespace-nowrap not-typography",
outline: "text-foreground border border-muted-4 hover:bg-level-1 hover:text-accent hover:border-accent font-heading whitespace-nowrap not-typography",
destructive: "bg-destructive text-destructive-fg font-sans whitespace-nowrap hover:bg-destructive-hover",
ghost: "text-foreground hover:bg-level-1 hover:text-accent whitespace-nowrap font-sans ",
link: "text-foreground hover:text-muted-1 font-sans ",
@@ -16,7 +16,8 @@ const variant = {
const size = {
link: '',
sm: "h-9 px-3 rounded-md text-xs ",
sm: "h-9 px-3 text-xs ",
square: 'h-10 py-2 px-2 text-sm aspect-square',
default: "h-10 py-2 px-4 text-sm lg:min-w-[220px]",
lg: "h-10 px-8 text-base rounded-lg min-w-[260px] lg:min-w-[300px] lg:h-10 xs:min-w-0 xs:text-sm",
icon: "h-10 w-10",
+53 -47
View File
@@ -1,38 +1,65 @@
import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { X } from "lucide-react"
import { classNames } from "../util/classNames"
import { cn } from "../util"
const Dialog = DialogPrimitive.Root
const DialogTrigger = DialogPrimitive.Trigger
const DialogPortal = ({
children,
...props
}: DialogPrimitive.DialogPortalProps) => (
interface DialogPortalProps extends React.PropsWithChildren<React.ComponentPropsWithoutRef<typeof DialogPrimitive.Portal>> {
className?: string;
}
const DialogPortal = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Portal>,
DialogPortalProps
>(({ className, children, ...props }, ref) => (
<DialogPrimitive.Portal {...props}>
<div className="fixed inset-0 z-50 flex items-end justify-center sm:items-center">
<div className={cn("fixed inset-0 z-50 flex items-end justify-center sm:items-center", className)}>
{children}
</div>
</DialogPrimitive.Portal>
)
DialogPortal.displayName = DialogPrimitive.Portal.displayName
))
DialogPortal.displayName = 'DialogPortal'
interface DialogOverlayProps extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay> {
className?: string;
}
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
DialogOverlayProps
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
<div className={cn("fixed inset-0 z-50 flex items-end justify-center sm:items-center", className)}>
<DialogPrimitive.Overlay ref={ref} {...props} />
</div>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
interface DialogCloseProps extends React.PropsWithChildren<React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>> {
className?: string;
}
const DialogClose = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Close>,
DialogCloseProps
>(({ className, ...props }, ref) => (
<DialogPrimitive.Close
ref={ref}
className={classNames(
"fixed inset-0 z-50 bg-black/50 backdrop-blur-sm transition-all duration-100 data-[state=closed]:animate-out data-[state=closed]:fade-out data-[state=open]:fade-in",
className={cn(
"absolute right-4 top-3 p-1 justify-self-start hover:brightness-105 hover:scale-110 duration-100 ring-1 ring-secondary-400 transition bg-secondary-500 hover:text-primary-text focus:outline-none rounded-full items-center",
className
)}
{...props}
/>
>
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
))
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName
DialogClose.displayName = DialogPrimitive.Close.displayName
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
@@ -42,17 +69,14 @@ const DialogContent = React.forwardRef<
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={classNames(
className={cn(
"fixed z-50 grid w-full gap-4 rounded-t-lg bg-secondary-800 p-4 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-sm sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
className
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute text-secondary-text right-4 top-3 p-1 justify-self-start hover:brightness-105 hover:scale-110 duartion-100 ring-1 ring-secondary-400 transition bg-secondary-500 hover:text-primary-text focus:outline-none rounded-full items-center">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
<DialogClose />
</DialogPrimitive.Content>
</DialogPortal>
))
@@ -63,7 +87,7 @@ const DialogHeader = ({
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={classNames(
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
)}
@@ -77,7 +101,7 @@ const DialogFooter = ({
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={classNames(
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
@@ -86,31 +110,13 @@ const DialogFooter = ({
)
DialogFooter.displayName = "DialogFooter"
const DialogClose = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Close>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Close>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Close
ref={ref}
className={classNames(
"absolute right-4 top-3 p-1 justify-self-start hover:brightness-105 hover:scale-110 duration-100 ring-1 ring-secondary-400 transition bg-secondary-500 hover:text-primary-text focus:outline-none rounded-full items-center",
className
)}
{...props}
>
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
));
DialogClose.displayName = "DialogClose"
const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={classNames(
className={cn(
"text-lg font-semibold leading-none tracking-tight text-primary-text",
className
)}
@@ -125,7 +131,7 @@ const DialogDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={classNames("text-sm text-secondary-text", className)}
className={cn("text-sm text-secondary-text", className)}
{...props}
/>
))
@@ -133,13 +139,13 @@ DialogDescription.displayName = DialogPrimitive.Description.displayName
export {
Dialog,
DialogContent,
DialogClose,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
DialogOverlay,
DialogClose,
DialogPortal,
DialogContent,
DialogHeader,
DialogFooter,
DialogTitle,
DialogDescription,
}
+3 -6
View File
@@ -1,11 +1,11 @@
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } from './accordion'
export { default as ApplyTypography, type TypographySize} from './apply-typography'
export {
default as Button,
export {
default as Button,
type ButtonProps,
type ButtonVariants,
type ButtonSizes,
type ButtonSizes,
buttonVariants,
} from './button'
@@ -71,6 +71,3 @@ export { Toaster } from './toaster'
export { useToast, toast } from './use-toast'
export { default as VideoPlayer } from './video-player'
-46
View File
@@ -1,46 +0,0 @@
module.exports = ({ colors }) => ({
inherit: colors.inherit,
current: colors.current,
transparent: colors.transparent,
input: "var(--input)",
ring: "var(--ring)",
background: 'var(--bg-0)',
// levels forward in z-index (a la Material Design)
level: {
DEFAULT: "var(--bg-0)",
'0': "var(--bg-0)",
'1': "var(--bg-1)",
'2': "var(--bg-2)",
'3': "var(--bg-3)",
},
accent: "var(--fg-0)", // full contrast (darkTheme:white) : heading and links hover
foreground: "var(--fg-body)", // body off-white (bright enough to contrast to bg-level-1)
muted: {
DEFAULT: "var(--fg-2)", // de-emphasized: fine print
'1': "var(--fg-2)", // synonymous ^^^
'2': "var(--fg-3)", // disabled or very de-emphasized
'3': "var(--fg-4)", // very disabled ;)
'4': "var(--fg-5)", // disabled border
},
primary: {
DEFAULT: "var(--primary)",
lux: "var(--primary)",
hover: "var(--primary-hover)",
fg: "var(--primary-fg)",
},
secondary: {
DEFAULT: "var(--secondary)",
lux: "var(--secondary)",
hover: "var(--secondary-hover)",
fg: "var(--secondary-fg)",
},
destructive: {
DEFAULT: "var(--destructive)",
fg: "var(--destructive-fg)",
},
nav: {
DEFAULT: "var(--nav)",
hover: "var(--nav-hover)",
current: "var(--nav-current)",
},
})
+6 -79
View File
@@ -1,87 +1,14 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "tailwindcss/base";
/* see https://stackoverflow.com/questions/69746121/using-nextjs-how-can-you-import-in-css-using-tailwind-css */
@import "lux-tw-base-layer";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
/* Preflight is applied first:
https://unpkg.com/tailwindcss@3.3.5/src/css/preflight.css
*/
@layer base {
:root, .light, .light-theme {
--fg-0: hsl(0 0% 0%);
--fg-body: hsl(0 0% 10%);
--fg-1: hsl(0 0% 20%);
--fg-2: hsl(0 0% 35%);
--fg-3: hsl(0 0% 50%);
--fg-4: hsl(0 0% 70%);
--fg-5: hsl(0 0% 90%);
--bg-0: hsl(0 0% 100%);
--bg-1: hsl(0 0% 90%);
--bg-2: hsl(0 0% 75%);
--bg-3: hsl(0 0% 55%);
--bg-inverted: var(--fg-0);
--bg-inverted-hover: hsla(0, 0%, 0%, 0.85);
--fg-inverted: var(--bg-0);
--secondary-0: hsl(266, 79%, 80%);
--secondary-1: hsl(266, 79%, 70%);
--secondary-2: hsl(266, 79%, 60%);
--secondary-3: hsl(266, 79%, 50%);
--primary: var(--bg-inverted);
--primary-hover: var(--bg-inverted-hover);
--primary-fg: var(--fg-inverted);
--secondary: var(--secondary-0);
--secondary-hover: var(--secondary-2);
--secondary-fg: var(--fg-0);
--nav: var(--fg-4);
--nav-current: var(--fg-0);
--nav-hover: var(--fg-0);
--destructive: hsl(0 62.8% 45%);
--destructive-hover: hsl(0 62.8% 25%);
--destructive-fg: hsl(0 0% 100%);
--input: var(--bg-1);
--ring: var(--fg-1);
--radius: 0.5rem;
}
.dark, .dark-theme {
--fg-0: hsl(0 0% 100%);
--fg-body: hsl(0, 0%, 97%);
--fg-1: hsl(0 0% 85%);
--fg-2: hsl(0 0% 70%);
--fg-3: hsl(0 0% 55%);
--fg-4: hsl(0 0% 40%);
--fg-5: hsl(0 0% 25%);
--bg-inverted: var(--fg-0);
--bg-inverted-hover: hsla(0, 0%, 100%, 0.85);
--bg-3: hsl(0 0% 25%);
--bg-2: hsl(0 0% 18%);
--bg-1: hsl(0 0% 12%);
--bg-0: hsl(0 0% 0%);
--fg-inverted: var(--bg-0);
--secondary-0: hsl(266, 79%, 40%);
--secondary-1: hsl(266, 79%, 50%);
--secondary-2: hsl(266, 79%, 60%);
--secondary-3: hsl(266, 79%, 70%);
}
}
@layer base {
* {
@apply border-muted-3;
+85
View File
@@ -0,0 +1,85 @@
@tailwind base;
/* see https://stackoverflow.com/questions/69746121/using-nextjs-how-can-you-import-in-css-using-tailwind-css */
@layer base {
/* On iOS disabled inputs have default opacitiy */
.ntdi {
opacity: 1;
/* required on iOS */
}
:root, .lux-light-theme {
--lx-fg-0: hsl(0 0% 0%);
--lx-fg-body: hsl(0 0% 10%);
--lx-fg-1: hsl(0 0% 20%);
--lx-fg-2: hsl(0 0% 35%);
--lx-fg-3: hsl(0 0% 50%);
--lx-fg-4: hsl(0 0% 70%);
--lx-fg-5: hsl(0 0% 90%);
--lx-bg-0: hsl(0 0% 100%);
--lx-bg-1: hsl(0 0% 90%);
--lx-bg-2: hsl(0 0% 75%);
--lx-bg-3: hsl(0 0% 55%);
--lx-bg-inverted: var(--lx-fg-0);
--lx-bg-inverted-hover: hsla(0, 0%, 0%, 0.85);
--lx-fg-inverted: var(--lx-bg-0);
--lx-secondary-0: hsl(266, 79%, 80%);
--lx-secondary-1: hsl(266, 79%, 70%);
--lx-secondary-2: hsl(266, 79%, 60%);
--lx-secondary-3: hsl(266, 79%, 50%);
--lx-primary: var(--lx-bg-inverted);
--lx-primary-hover: var(--lx-bg-inverted-hover);
--lx-primary-fg: var(--lx-fg-inverted);
--lx-secondary: var(--lx-secondary-0);
--lx-secondary-hover: var(--lx-secondary-2);
--lx-secondary-fg: var(--lx-fg-0);
--lx-nav: var(--lx-fg-4);
--lx-nav-current: var(--lx-fg-0);
--lx-nav-hover: var(--lx-fg-0);
--lx-destructive: hsl(0 62.8% 45%);
--lx-destructive-hover: hsl(0 62.8% 25%);
--lx-destructive-fg: hsl(0 0% 100%);
--lx-input: var(--lx-bg-1);
--lx-ring: var(--lx-fg-1);
--lx-radius: 0.5rem;
}
.lux-dark-theme {
--lx-fg-0: hsl(0 0% 100%);
--lx-fg-body: hsl(0, 0%, 97%);
--lx-fg-1: hsl(0 0% 85%);
--lx-fg-2: hsl(0 0% 70%);
--lx-fg-3: hsl(0 0% 55%);
--lx-fg-4: hsl(0 0% 40%);
--lx-fg-5: hsl(0 0% 25%);
--lx-bg-inverted: var(--lx-fg-0);
--lx-bg-inverted-hover: hsla(0, 0%, 100%, 0.85);
--lx-bg-3: hsl(0 0% 25%);
--lx-bg-2: hsl(0 0% 18%);
--lx-bg-1: hsl(0 0% 12%);
--lx-bg-0: hsl(0 0% 0%);
--lx-fg-inverted: var(--lx-bg-0);
--lx-secondary-0: hsl(266, 79%, 40%);
--lx-secondary-1: hsl(266, 79%, 50%);
--lx-secondary-2: hsl(266, 79%, 60%);
--lx-secondary-3: hsl(266, 79%, 70%);
}
}
+46
View File
@@ -0,0 +1,46 @@
module.exports = ({ colors }) => ({
inherit: colors.inherit,
current: colors.current,
transparent: colors.transparent,
input: "var(--lx-input)",
ring: "var(--lx-ring)",
background: 'var(--lx-bg-0)',
// levels forward in z-index (a la Material Design)
level: {
DEFAULT: "var(--lx-bg-0)",
'0': "var(--lx-bg-0)",
'1': "var(--lx-bg-1)",
'2': "var(--lx-bg-2)",
'3': "var(--lx-bg-3)",
},
accent: "var(--lx-fg-0)", // full contrast (darkTheme:white) : heading and links hover
foreground: "var(--lx-fg-body)", // body off-white (bright enough to contrast to bg-level-1)
muted: {
DEFAULT: "var(--lx-fg-2)", // de-emphasized: fine print
'1': "var(--lx-fg-2)", // synonymous ^^^
'2': "var(--lx-fg-3)", // disabled or very de-emphasized
'3': "var(--lx-fg-4)", // very disabled ;)
'4': "var(--lx-fg-5)", // disabled border
},
primary: {
DEFAULT: "var(--lx-primary)",
lux: "var(--lx-primary)", // in case there are two configs
hover: "var(--lx-primary-hover)",
fg: "var(--lx-primary-fg)",
},
secondary: {
DEFAULT: "var(--lx-secondary)",
lux: "var(--lx-secondary)", // in case there are two configs
hover: "var(--lx-secondary-hover)",
fg: "var(--lx-secondary-fg)",
},
destructive: {
DEFAULT: "var(--lx-destructive)",
fg: "var(--lx-destructive-fg)",
},
nav: {
DEFAULT: "var(--lx-nav)",
hover: "var(--lx-nav-hover)",
current: "var(--lx-nav-current)",
},
})
+14
View File
@@ -0,0 +1,14 @@
import colors from './colors.tailwind'
import { fontFamily, fontSize } from './fonts.tailwind'
import safelist from './safelist.tailwind'
import screens from './screens.tailwind'
import typographyPlugin from './typo-plugin'
export {
colors,
fontFamily,
fontSize,
safelist,
screens,
typographyPlugin
}
@@ -2,7 +2,7 @@ const {
round,
pxToRem,
pxToEm,
} = require('../util')
} = require('../../util')
const typographyColorTheme = {
// vars are defined in global.css
@@ -80,7 +80,6 @@ const defaultCSS = {
},
'ul > li::before': {
},
hr: {},
hr: {
borderColor: 'var(--tw-prose-hr)',
borderTopWidth: 1,
@@ -1,7 +1,7 @@
const plugin = require('tailwindcss/plugin')
const merge = require('lodash.merge')
const castArray = require('lodash.castarray')
const getStyles = require('../get-plugin-styles')
const getStyles = require('./get-plugin-styles')
const { commonTrailingPseudos } = require('./utils')
let baseFontSize = 16
@@ -1,4 +1,4 @@
{
{ // https://esbuild.github.io/content-types/#tsconfig-json
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
@@ -12,6 +12,6 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
"jsx": "react-jsx",
}
}
+26 -7
View File
@@ -1,13 +1,32 @@
{
"extends": "../../tsconfig.base.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules", "./dist", "**/*.stories.tsx"],
"plugins": [{ "name": "next" }],
"extends": "./tsconfig.base.json",
"include": [
"**/*.ts",
"**/*.tsx",
],
"exclude": [
"node_modules",
"./dist",
],
"plugins": [
{
"name": "next"
}
],
// re emit settings: https://www.simonboisset.com/en/blog/publish-npm-library-with-esbuild
// https://esbuild.github.io/content-types/#tsconfig-json
"compilerOptions": {
"target": "es2020",
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"jsx": "react-jsx",
"lib": ["dom", "es2015"]
"esModuleInterop": true,
"skipLibCheck": true,
"noEmit": false,
"emitDeclarationOnly": true,
"outDir": "./dist/types",
"lib": [
"dom",
"es2015"
]
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
// @ts-nocheck
import bps from '../style/screens.tailwind'
import bps from '../tailwind/screens.tailwind'
type Breakpoint = keyof typeof bps
const Breakpoints = Object.keys(bps)
+1 -1
View File
@@ -1,6 +1,6 @@
interface ContactInfo {
email: string
phone: string
phone?: string
}
type ContactInfoFields = keyof ContactInfo
-3
View File
@@ -1,3 +0,0 @@
export function classNames(...classes: (string | boolean | undefined)[]): string {
return classes.filter(Boolean).join(' ')
}
+2143 -3601
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -29,7 +29,7 @@
"devDependencies": {
"@ianvs/prettier-plugin-sort-imports": "^3.7.2",
"@types/node": "^17.0.45",
"@types/react": "^18.2.14",
"@types/react": "^18.2.48",
"@types/react-dom": "^18.2.6",
"@typescript-eslint/parser": "^5.61.0",
"autoprefixer": "^10.4.14",
+1 -1
View File
@@ -24,4 +24,4 @@
"strict": true
},
"exclude": ["node_modules"]
}
}