From 98b1cad3ad91e875cf8ee08c5fc28b5d7fe767c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Wed, 21 Aug 2024 11:08:12 +0300 Subject: [PATCH 1/3] feat!: simplify UnoCSS integration BREAKING CHANGES: - `@tutorialkit/astro` package no longer exports `unoCSSConfig`. Use `defineConfig` from `@tutorialkit/theme` instead. - `@tutorialkit/theme` package no longer exports `rules`, `shortcuts` and `theme`. - `@tutorialkit/theme` package exports `transitionTheme` from new entrypoint: `@tutorialkit/theme/transition-theme`. --- docs/demo/package.json | 8 +- docs/demo/uno.config.ts | 44 +-- docs/tutorialkit.dev/package.json | 2 - .../docs/reference/react-components.mdx | 25 +- docs/tutorialkit.dev/uno.config.ts | 19 +- packages/astro/package.json | 4 +- packages/astro/src/index.ts | 9 +- packages/astro/src/integrations.ts | 13 +- packages/cli/src/commands/eject/index.ts | 1 + packages/components/react/package.json | 3 +- .../src/core/CodeMirrorEditor/cm-theme.ts | 2 +- packages/template/package.json | 8 +- packages/template/uno.config.ts | 44 +-- packages/theme/package.json | 13 +- packages/theme/src/index.ts | 80 ++++- packages/theme/src/transition-theme.ts | 5 + pnpm-lock.yaml | 283 +++++++++++++----- 17 files changed, 324 insertions(+), 239 deletions(-) create mode 100644 packages/theme/src/transition-theme.ts diff --git a/docs/demo/package.json b/docs/demo/package.json index 24d95208c..41ec04b20 100644 --- a/docs/demo/package.json +++ b/docs/demo/package.json @@ -18,15 +18,11 @@ "devDependencies": { "@astrojs/check": "^0.7.0", "@astrojs/react": "^3.6.0", - "@iconify-json/ph": "^1.1.13", - "@iconify-json/svg-spinners": "^1.1.2", "@tutorialkit/astro": "workspace:*", + "@tutorialkit/theme": "workspace:*", "@tutorialkit/types": "workspace:*", - "@unocss/reset": "^0.59.4", "astro": "^4.12.0", - "fast-glob": "^3.3.2", "prettier-plugin-astro": "^0.14.1", - "typescript": "^5.4.5", - "unocss": "^0.59.4" + "typescript": "^5.4.5" } } diff --git a/docs/demo/uno.config.ts b/docs/demo/uno.config.ts index b42aeaffd..949120d9c 100644 --- a/docs/demo/uno.config.ts +++ b/docs/demo/uno.config.ts @@ -1,45 +1,5 @@ -import { unoCSSConfig } from '@tutorialkit/astro'; -import { globSync, convertPathToPattern } from 'fast-glob'; -import fs from 'node:fs/promises'; -import { basename, dirname, join } from 'node:path'; -import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; - -const iconPaths = globSync('./icons/languages/*.svg'); - -const customIconCollection = iconPaths.reduce( - (acc, iconPath) => { - const collectionName = basename(dirname(iconPath)); - const [iconName] = basename(iconPath).split('.'); - - acc[collectionName] ??= {}; - acc[collectionName][iconName] = async () => fs.readFile(iconPath, 'utf8'); - - return acc; - }, - {} as Record Promise>>, -); +import { defineConfig } from '@tutorialkit/theme'; export default defineConfig({ - ...unoCSSConfig, - content: { - inline: globSync([ - `${convertPathToPattern(join(require.resolve('@tutorialkit/components-react'), '..'))}/**/*.js`, - `${convertPathToPattern(join(require.resolve('@tutorialkit/astro'), '..'))}/default/**/*.astro`, - ]).map((filePath) => { - return () => fs.readFile(filePath, { encoding: 'utf8' }); - }), - }, - transformers: [transformerDirectives()], - presets: [ - presetUno({ - dark: { - dark: '[data-theme="dark"]', - }, - }), - presetIcons({ - collections: { - ...customIconCollection, - }, - }), - ], + // add your UnoCSS config here: https://unocss.dev/guide/config-file }); diff --git a/docs/tutorialkit.dev/package.json b/docs/tutorialkit.dev/package.json index e81fffe98..a4c94b057 100644 --- a/docs/tutorialkit.dev/package.json +++ b/docs/tutorialkit.dev/package.json @@ -21,14 +21,12 @@ "@astrojs/check": "^0.7.0", "@astrojs/react": "^3.6.0", "@astrojs/starlight": "^0.23.4", - "@iconify-json/ph": "^1.1.13", "@tutorialkit/astro": "workspace:*", "@tutorialkit/theme": "workspace:*", "@types/gtag.js": "^0.0.20", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "astro": "^4.12.0", - "fast-glob": "^3.3.2", "sass": "^1.77.6", "sharp": "^0.32.6", "starlight-links-validator": "^0.9.0", diff --git a/docs/tutorialkit.dev/src/content/docs/reference/react-components.mdx b/docs/tutorialkit.dev/src/content/docs/reference/react-components.mdx index 7204f6b70..874d8336e 100644 --- a/docs/tutorialkit.dev/src/content/docs/reference/react-components.mdx +++ b/docs/tutorialkit.dev/src/content/docs/reference/react-components.mdx @@ -32,17 +32,17 @@ These components use TutorialKit's design system which is based on an atomic CSS ```shell - npm install @tutorialkit/components-react @tutorialkit/theme unocss @iconify-json/ph fast-glob + npm install @tutorialkit/components-react @tutorialkit/theme ``` ```shell - pnpm install @tutorialkit/components-react @tutorialkit/theme unocss @iconify-json/ph fast-glob + pnpm install @tutorialkit/components-react @tutorialkit/theme ``` ```shell - yarn add @tutorialkit/components-react @tutorialkit/theme unocss @iconify-json/ph fast-glob + yarn add @tutorialkit/components-react @tutorialkit/theme ``` @@ -50,25 +50,10 @@ These components use TutorialKit's design system which is based on an atomic CSS To setup UnoCSS with TutorialKit's components, you need to create a `uno.config.ts`: ```ts title=uno.config.ts -import { theme, rules, shortcuts } from '@tutorialkit/theme'; -import { convertPathToPattern, globSync } from 'fast-glob'; -import fs from 'node:fs/promises'; -import { join } from 'path'; -import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; +import { defineConfig } from '@tutorialkit/theme'; export default defineConfig({ - theme, - rules, - shortcuts, - content: { - inline: globSync( - `${convertPathToPattern(join(require.resolve('@tutorialkit/components-react'), '..'))}/**/*.js`, - ).map((filePath) => { - return () => fs.readFile(filePath, { encoding: 'utf8' }); - }), - }, - transformers: [transformerDirectives()], - presets: [presetUno(), presetIcons()], + // add your UnoCSS config here: https://unocss.dev/guide/config-file }); ``` diff --git a/docs/tutorialkit.dev/uno.config.ts b/docs/tutorialkit.dev/uno.config.ts index 24f003d03..949120d9c 100644 --- a/docs/tutorialkit.dev/uno.config.ts +++ b/docs/tutorialkit.dev/uno.config.ts @@ -1,20 +1,5 @@ -import { theme, rules, shortcuts } from '@tutorialkit/theme'; -import { convertPathToPattern, globSync } from 'fast-glob'; -import fs from 'node:fs/promises'; -import { join } from 'path'; -import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; +import { defineConfig } from '@tutorialkit/theme'; export default defineConfig({ - theme, - rules, - shortcuts, - content: { - inline: globSync( - `${convertPathToPattern(join(require.resolve('@tutorialkit/components-react'), '..'))}/**/*.js`, - ).map((filePath) => { - return () => fs.readFile(filePath, { encoding: 'utf8' }); - }), - }, - transformers: [transformerDirectives()], - presets: [presetUno(), presetIcons()], + // add your UnoCSS config here: https://unocss.dev/guide/config-file }); diff --git a/packages/astro/package.json b/packages/astro/package.json index 41053beb8..3ffe11d2a 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -19,7 +19,8 @@ "./default-theme.css": "./dist/default/styles/variables.css", "./default/pages/index.astro": "./dist/default/pages/index.astro", "./default/pages/[...slug].astro": "./dist/default/pages/[...slug].astro", - "./default/components/TopBar.astro": "./dist/default/components/TopBar.astro" + "./default/components/TopBar.astro": "./dist/default/components/TopBar.astro", + "./package.json": "./package.json" }, "files": [ "dist" @@ -41,6 +42,7 @@ "@tutorialkit/theme": "workspace:*", "@tutorialkit/types": "workspace:*", "@types/react": "^18.3.3", + "@unocss/reset": "^0.62.2", "@webcontainer/api": "1.2.0", "astro": "^4.12.0", "astro-expressive-code": "^0.35.3", diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index 02bd01f0d..3d1c10f9d 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1,4 +1,3 @@ -import { rules, shortcuts, theme } from '@tutorialkit/theme'; import type { AstroConfig, AstroIntegration } from 'astro'; import { fileURLToPath } from 'node:url'; import { extraIntegrations } from './integrations.js'; @@ -9,12 +8,6 @@ import { tutorialkitStore } from './vite-plugins/store.js'; import { overrideComponents, type OverrideComponentsOptions } from './vite-plugins/override-components.js'; import { WebContainerFiles } from './webcontainer-files/index.js'; -export const unoCSSConfig = { - theme, - rules, - shortcuts, -}; - export interface Options { /** * Whether or not default routes are injected. @@ -133,7 +126,7 @@ export default function createPlugin({ // inject the additional integrations right after ours const selfIndex = config.integrations.findIndex((integration) => integration.name === '@tutorialkit/astro'); - config.integrations.splice(selfIndex + 1, 0, ...extraIntegrations()); + config.integrations.splice(selfIndex + 1, 0, ...extraIntegrations({ root: fileURLToPath(config.root) })); }, 'astro:config:done'({ config }) { _config = config; diff --git a/packages/astro/src/integrations.ts b/packages/astro/src/integrations.ts index 814fbc98f..a0a888fb1 100644 --- a/packages/astro/src/integrations.ts +++ b/packages/astro/src/integrations.ts @@ -1,11 +1,13 @@ +import { createRequire } from 'node:module'; import mdx from '@astrojs/mdx'; import react from '@astrojs/react'; import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections'; import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'; import expressiveCode from 'astro-expressive-code'; import UnoCSS from 'unocss/astro'; +import { getInlineContentForPackage } from '@tutorialkit/theme'; -export function extraIntegrations() { +export function extraIntegrations({ root }: { root: string }) { return [ react(), expressiveCode({ @@ -47,7 +49,14 @@ export function extraIntegrations() { mdx(), UnoCSS({ configDeps: ['./theme.ts'], - injectReset: true, + injectReset: createRequire(root).resolve('@unocss/reset/tailwind.css'), + content: { + inline: getInlineContentForPackage({ + name: '@tutorialkit/astro', + pattern: '/dist/default/**/*.astro', + root, + }), + }, }), ]; } diff --git a/packages/cli/src/commands/eject/index.ts b/packages/cli/src/commands/eject/index.ts index d7070718c..b8d842f34 100644 --- a/packages/cli/src/commands/eject/index.ts +++ b/packages/cli/src/commands/eject/index.ts @@ -25,6 +25,7 @@ const REQUIRED_DEPENDENCIES = [ '@nanostores/react', 'kleur', '@stackblitz/sdk', + 'fast-glob', ]; export function ejectRoutes(flags: Arguments) { diff --git a/packages/components/react/package.json b/packages/components/react/package.json index d5269dbee..c675b7e7d 100644 --- a/packages/components/react/package.json +++ b/packages/components/react/package.json @@ -43,7 +43,8 @@ "types": "./dist/core/Terminal/index.d.ts", "default": "./dist/core/Terminal/index.js" } - } + }, + "./package.json": "./package.json" }, "files": [ "dist" diff --git a/packages/components/react/src/core/CodeMirrorEditor/cm-theme.ts b/packages/components/react/src/core/CodeMirrorEditor/cm-theme.ts index 4387645d8..9c5366b9d 100644 --- a/packages/components/react/src/core/CodeMirrorEditor/cm-theme.ts +++ b/packages/components/react/src/core/CodeMirrorEditor/cm-theme.ts @@ -1,7 +1,7 @@ import { defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language'; import { Compartment, type Extension } from '@codemirror/state'; import { EditorView } from '@codemirror/view'; -import { transitionTheme } from '@tutorialkit/theme'; +import { transitionTheme } from '@tutorialkit/theme/transition-theme'; import '../../styles/cm.css'; import type { Theme } from '../types.js'; import type { EditorSettings } from './index.js'; diff --git a/packages/template/package.json b/packages/template/package.json index 087c7667c..f1f4f592d 100644 --- a/packages/template/package.json +++ b/packages/template/package.json @@ -18,17 +18,13 @@ "devDependencies": { "@astrojs/check": "^0.7.0", "@astrojs/react": "^3.6.0", - "@iconify-json/ph": "^1.1.13", - "@iconify-json/svg-spinners": "^1.1.2", "@tutorialkit/astro": "workspace:*", + "@tutorialkit/theme": "workspace:*", "@tutorialkit/types": "workspace:*", "@types/node": "^20.14.6", "@types/react": "^18.3.3", - "@unocss/reset": "^0.59.4", "astro": "^4.12.0", - "fast-glob": "^3.3.2", "prettier-plugin-astro": "^0.14.1", - "typescript": "^5.4.5", - "unocss": "^0.59.4" + "typescript": "^5.4.5" } } diff --git a/packages/template/uno.config.ts b/packages/template/uno.config.ts index 438b96b92..949120d9c 100644 --- a/packages/template/uno.config.ts +++ b/packages/template/uno.config.ts @@ -1,45 +1,5 @@ -import { unoCSSConfig } from '@tutorialkit/astro'; -import { globSync, convertPathToPattern } from 'fast-glob'; -import fs from 'node:fs/promises'; -import { basename, dirname, join } from 'node:path'; -import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; - -const iconPaths = globSync('./icons/languages/*.svg'); - -const customIconCollection = iconPaths.reduce( - (acc, iconPath) => { - const collectionName = basename(dirname(iconPath)); - const [iconName] = basename(iconPath).split('.'); - - acc[collectionName] ??= {}; - acc[collectionName][iconName] = async () => fs.readFile(iconPath, 'utf8'); - - return acc; - }, - {} as Record Promise>>, -); +import { defineConfig } from '@tutorialkit/theme'; export default defineConfig({ - ...unoCSSConfig, - content: { - inline: globSync([ - `${convertPathToPattern(join(require.resolve('@tutorialkit/components-react'), '..')).replace('\\@', '/@')}/**/*.js`, - `${convertPathToPattern(join(require.resolve('@tutorialkit/astro'), '..')).replace('\\@', '/@')}/default/**/*.astro`, - ]).map((filePath) => { - return () => fs.readFile(filePath, { encoding: 'utf8' }); - }), - }, - transformers: [transformerDirectives()], - presets: [ - presetUno({ - dark: { - dark: '[data-theme="dark"]', - }, - }), - presetIcons({ - collections: { - ...customIconCollection, - }, - }), - ], + // add your UnoCSS config here: https://unocss.dev/guide/config-file }); diff --git a/packages/theme/package.json b/packages/theme/package.json index 908a63187..79c10b741 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -14,7 +14,14 @@ }, "types": "./dist/index.d.ts", "exports": { - ".": "./dist/index.js" + ".": { + "import": "./dist/index.js", + "types": "./dist/index.d.ts" + }, + "./transition-theme": { + "import": "./dist/transition-theme.js", + "types": "./dist/transition-theme.d.ts" + } }, "files": [ "dist" @@ -24,9 +31,13 @@ "dev": "pnpm run build --watch --preserveWatchOutput" }, "dependencies": { + "@iconify-json/ph": "^1.1.13", + "@iconify-json/svg-spinners": "^1.1.2", + "fast-glob": "^3.3.2", "unocss": "^0.59.4" }, "devDependencies": { + "@types/node": "^22.4.1", "typescript": "^5.4.5" } } diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts index c75edcdd4..bc8657fa7 100644 --- a/packages/theme/src/index.ts +++ b/packages/theme/src/index.ts @@ -1,21 +1,83 @@ -import type { ConfigBase } from 'unocss'; +import fs from 'node:fs/promises'; +import { basename, dirname, resolve } from 'node:path'; +import { createRequire } from 'node:module'; +import * as fastGlob from 'fast-glob'; +import { mergeConfigs, presetIcons, presetUno, transformerDirectives, type UserConfig } from 'unocss'; + import { toCSSRules } from './utils.js'; +import { theme } from './theme.js'; +import { transitionTheme } from './transition-theme.js'; -export { theme } from './theme.js'; +const { globSync, convertPathToPattern } = fastGlob.default; +const require = createRequire(import.meta.url); -export const transitionTheme = { - transitionProperty: 'background-color, border-color, box-shadow', - transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', - transitionDuration: '150ms', -}; +export function defineConfig(config: UserConfig) { + return mergeConfigs([ + { + theme, + shortcuts, + rules, + transformers: [transformerDirectives()], + content: { + inline: getInlineContentForPackage({ + name: '@tutorialkit/components-react', + pattern: '/dist/**/*.js', + root: process.cwd(), + }), + }, + presets: [ + presetUno({ + dark: { + dark: '[data-theme="dark"]', + }, + }), + presetIcons({ + collections: { + ...readCustomIcons(), + ph: () => import('@iconify-json/ph').then((i) => i.icons), + 'svg-spinners': () => import('@iconify-json/svg-spinners').then((i) => i.icons), + }, + }), + ], + }, + config, + ]); +} + +export function getInlineContentForPackage({ name, pattern, root }: { name: string; pattern: string; root: string }) { + try { + const packageRoot = resolve(require.resolve(`${name}/package.json`, { paths: [root] }), '..'); + + // work-around for https://github.com/mrmlnc/fast-glob/issues/452 + const packagePattern = convertPathToPattern(packageRoot.replace('\\@', '/@')); + + return globSync(`${packagePattern}${pattern}`).map((filePath) => () => fs.readFile(filePath, { encoding: 'utf8' })); + } catch { + return []; + } +} + +function readCustomIcons() { + const iconPaths = globSync('./icons/languages/*.svg'); + + return iconPaths.reduce Promise>>>((acc, iconPath) => { + const collectionName = basename(dirname(iconPath)); + const [iconName] = basename(iconPath).split('.'); + + acc[collectionName] ??= {}; + acc[collectionName][iconName] = async () => fs.readFile(iconPath, 'utf8'); + + return acc; + }, {}); +} -export const rules: ConfigBase['rules'] = [ +const rules: UserConfig['rules'] = [ ['scrollbar-transparent', { 'scrollbar-color': '#0000004d transparent' }], ['nav-box-shadow', { 'box-shadow': '0 2px 4px -1px rgba(0, 0, 0, 0.1)' }], ['transition-theme', toCSSRules(transitionTheme)], ]; -export const shortcuts: ConfigBase['shortcuts'] = { +const shortcuts: UserConfig['shortcuts'] = { 'panel-container': 'grid grid-rows-[min-content_1fr] h-full', 'panel-header': 'flex items-center px-4 py-2 transition-theme bg-tk-elements-panel-header-backgroundColor min-h-[38px] overflow-x-hidden', diff --git a/packages/theme/src/transition-theme.ts b/packages/theme/src/transition-theme.ts new file mode 100644 index 000000000..c001551bd --- /dev/null +++ b/packages/theme/src/transition-theme.ts @@ -0,0 +1,5 @@ +export const transitionTheme = { + transitionProperty: 'background-color, border-color, box-shadow', + transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)', + transitionDuration: '150ms', +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4911772c4..e1b3cc2fe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,36 +66,24 @@ importers: '@astrojs/react': specifier: ^3.6.0 version: 3.6.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(vite@5.3.4) - '@iconify-json/ph': - specifier: ^1.1.13 - version: 1.1.13 - '@iconify-json/svg-spinners': - specifier: ^1.1.2 - version: 1.1.2 '@tutorialkit/astro': specifier: workspace:* version: link:../../packages/astro + '@tutorialkit/theme': + specifier: workspace:* + version: link:../../packages/theme '@tutorialkit/types': specifier: workspace:* version: link:../../packages/types - '@unocss/reset': - specifier: ^0.59.4 - version: 0.59.4 astro: specifier: ^4.12.0 - version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 + version: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) prettier-plugin-astro: specifier: ^0.14.1 version: 0.14.1 typescript: specifier: ^5.4.5 version: 5.5.3 - unocss: - specifier: ^0.59.4 - version: 0.59.4(postcss@8.4.39)(vite@5.3.4) docs/tutorialkit.dev: dependencies: @@ -124,9 +112,6 @@ importers: '@astrojs/starlight': specifier: ^0.23.4 version: 0.23.4(astro@4.12.2) - '@iconify-json/ph': - specifier: ^1.1.13 - version: 1.1.13 '@tutorialkit/astro': specifier: workspace:* version: link:../../packages/astro @@ -145,9 +130,6 @@ importers: astro: specifier: ^4.12.0 version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 sass: specifier: ^1.77.6 version: 1.77.6 @@ -269,12 +251,15 @@ importers: '@types/react': specifier: ^18.3.3 version: 18.3.3 + '@unocss/reset': + specifier: ^0.62.2 + version: 0.62.2 '@webcontainer/api': specifier: 1.2.0 version: 1.2.0 astro: specifier: ^4.12.0 - version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + version: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) astro-expressive-code: specifier: ^0.35.3 version: 0.35.3(astro@4.12.2) @@ -590,15 +575,12 @@ importers: '@astrojs/react': specifier: ^3.6.0 version: 3.6.0(@types/react-dom@18.3.0)(@types/react@18.3.3)(react-dom@18.3.1)(react@18.3.1)(vite@5.3.4) - '@iconify-json/ph': - specifier: ^1.1.13 - version: 1.1.13 - '@iconify-json/svg-spinners': - specifier: ^1.1.2 - version: 1.1.2 '@tutorialkit/astro': specifier: workspace:* version: link:../astro + '@tutorialkit/theme': + specifier: workspace:* + version: link:../theme '@tutorialkit/types': specifier: workspace:* version: link:../types @@ -608,24 +590,15 @@ importers: '@types/react': specifier: ^18.3.3 version: 18.3.3 - '@unocss/reset': - specifier: ^0.59.4 - version: 0.59.4 astro: specifier: ^4.12.0 - version: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 + version: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) prettier-plugin-astro: specifier: ^0.14.1 version: 0.14.1 typescript: specifier: ^5.4.5 version: 5.5.3 - unocss: - specifier: ^0.59.4 - version: 0.59.4(postcss@8.4.39)(vite@5.3.4) packages/test-utils: devDependencies: @@ -641,10 +614,22 @@ importers: packages/theme: dependencies: + '@iconify-json/ph': + specifier: ^1.1.13 + version: 1.1.13 + '@iconify-json/svg-spinners': + specifier: ^1.1.2 + version: 1.1.2 + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 unocss: specifier: ^0.59.4 version: 0.59.4(postcss@8.4.39)(vite@5.3.4) devDependencies: + '@types/node': + specifier: ^22.4.1 + version: 22.4.1 typescript: specifier: ^5.4.5 version: 5.5.3 @@ -795,7 +780,7 @@ packages: '@astrojs/markdown-remark': 5.1.0 '@mdx-js/mdx': 3.0.1 acorn: 8.12.0 - astro: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + astro: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) es-module-lexer: 1.5.3 estree-util-visit: 2.0.0 github-slugger: 2.0.0 @@ -1001,19 +986,19 @@ packages: lru-cache: 5.1.1 semver: 6.3.1 - /@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7): + /@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.9 '@babel/helper-annotate-as-pure': 7.24.7 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-function-name': 7.24.7 '@babel/helper-member-expression-to-functions': 7.24.7 '@babel/helper-optimise-call-expression': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.9) '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 '@babel/helper-split-export-declaration': 7.24.7 semver: 6.3.1 @@ -1072,6 +1057,21 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.9): + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.9 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color + /@babel/helper-module-transforms@7.24.9(@babel/core@7.24.9): resolution: {integrity: sha512-oYbh+rtFKj/HwBQkFlUzvcybzklmVdVV3UU+mN7n2t/q3yGHbuVdNxyFvSBO1tfvjyArpHNcWMAzsSPdyI46hw==} engines: {node: '>=6.9.0'} @@ -1097,13 +1097,13 @@ packages: resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} engines: {node: '>=6.9.0'} - /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7): + /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.9 '@babel/helper-environment-visitor': 7.24.7 '@babel/helper-member-expression-to-functions': 7.24.7 '@babel/helper-optimise-call-expression': 7.24.7 @@ -1198,15 +1198,6 @@ packages: dependencies: '@babel/types': 7.24.5 - /@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - /@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} engines: {node: '>=6.9.0'} @@ -1216,23 +1207,23 @@ packages: '@babel/core': 7.24.9 '@babel/helper-plugin-utils': 7.24.7 - /@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.7): + /@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.9 '@babel/helper-plugin-utils': 7.24.7 - /@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/core': 7.24.9 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.9) '@babel/helper-plugin-utils': 7.24.7 '@babel/helper-simple-access': 7.24.7 transitivePeerDependencies: @@ -1271,32 +1262,32 @@ packages: transitivePeerDependencies: - supports-color - /@babel/plugin-transform-typescript@7.24.7(@babel/core@7.24.7): + /@babel/plugin-transform-typescript@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.9 '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.9) '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.7) + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.9) transitivePeerDependencies: - supports-color - /@babel/preset-typescript@7.24.7(@babel/core@7.24.7): + /@babel/preset-typescript@7.24.7(@babel/core@7.24.9): resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.7 + '@babel/core': 7.24.9 '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-validator-option': 7.24.7 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.7) + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.9) + '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.9) transitivePeerDependencies: - supports-color @@ -2303,13 +2294,13 @@ packages: resolution: {integrity: sha512-xtM4JJ63HCKj09WRqrBswXiHrpliBlqboWSZH8odcmqYXbvIFceU9/Til4V+MQr6+MoUC+KB72cxhky2+A6r/g==} dependencies: '@iconify/types': 2.0.0 - dev: true + dev: false /@iconify-json/svg-spinners@1.1.2: resolution: {integrity: sha512-Aab6SqkORaTJ1W+ooufn6C8BsBitrn3uk8iRQLPA6pjhyvQAhkKCGMctyXIL5ZjrycnoFVsZ4mx7KnwEMra8qg==} dependencies: '@iconify/types': 2.0.0 - dev: true + dev: false /@iconify/types@2.0.0: resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -3243,6 +3234,12 @@ packages: dependencies: undici-types: 5.26.5 + /@types/node@22.4.1: + resolution: {integrity: sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==} + dependencies: + undici-types: 6.19.8 + dev: true + /@types/normalize-package-data@2.4.4: resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} dev: true @@ -3586,6 +3583,10 @@ packages: /@unocss/reset@0.59.4: resolution: {integrity: sha512-Upy4xzdWl4RChbLAXBq1BoR4WqxXMoIfjvtcwSZcZK2sylXCFAseSWnyzJFdSiXPqNfmMuNgPXgiSxiQB+cmNA==} + /@unocss/reset@0.62.2: + resolution: {integrity: sha512-5hgxcBMMbw5tMSSd4kUX70H0pZK9SwRHtm8Q4VvDV6xOZJa2/fvFR4qyxbuAM9nhOwYUqAAX23lxfmY0bXX73A==} + dev: false + /@unocss/rule-utils@0.59.4: resolution: {integrity: sha512-1qoLJlBWAkS4D4sg73990S1MT7E8E5md/YhopKjTQuEC9SyeVmEg+5pR/Xd8xhPKMqbcuBPl/DS8b6l/GQO56A==} engines: {node: '>=14'} @@ -3599,9 +3600,9 @@ packages: /@unocss/transformer-attributify-jsx-babel@0.59.4: resolution: {integrity: sha512-xtCRSgeTaDBiNJLVX7oOSFe63JiFB5nrdK23PHn3IlZM9O7Bxx4ZxI3MQJtFZFQNE+INFko+DVyY1WiFEm1p/Q==} dependencies: - '@babel/core': 7.24.7 - '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7) - '@babel/preset-typescript': 7.24.7(@babel/core@7.24.7) + '@babel/core': 7.24.9 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/preset-typescript': 7.24.7(@babel/core@7.24.9) '@unocss/core': 0.59.4 transitivePeerDependencies: - supports-color @@ -3658,7 +3659,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.24.7) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - supports-color @@ -4009,7 +4010,7 @@ packages: peerDependencies: astro: ^4.0.0-beta || ^3.3.0 dependencies: - astro: 4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3) + astro: 4.12.2(@types/node@20.14.11)(typescript@5.5.3) rehype-expressive-code: 0.35.3 /astro@4.12.2(@types/node@20.14.11)(sass@1.77.6)(typescript@5.5.3): @@ -4091,6 +4092,87 @@ packages: - supports-color - terser - typescript + dev: true + + /astro@4.12.2(@types/node@20.14.11)(typescript@5.5.3): + resolution: {integrity: sha512-l6OmqlL+FiuSi9x6F+EGZitteOznq1JffOil7st7cdqeMCTEIym4oagI1a6zp6QekliKWEEZWdplGhgh1k1f7Q==} + engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + dependencies: + '@astrojs/compiler': 2.9.1 + '@astrojs/internal-helpers': 0.4.1 + '@astrojs/markdown-remark': 5.2.0 + '@astrojs/telemetry': 3.1.0 + '@babel/core': 7.24.9 + '@babel/generator': 7.24.10 + '@babel/parser': 7.24.8 + '@babel/plugin-transform-react-jsx': 7.24.7(@babel/core@7.24.9) + '@babel/traverse': 7.24.8 + '@babel/types': 7.24.9 + '@types/babel__core': 7.20.5 + '@types/cookie': 0.6.0 + acorn: 8.12.1 + aria-query: 5.3.0 + axobject-query: 4.1.0 + boxen: 7.1.1 + chokidar: 3.6.0 + ci-info: 4.0.0 + clsx: 2.1.1 + common-ancestor-path: 1.0.1 + cookie: 0.6.0 + cssesc: 3.0.0 + debug: 4.3.5 + deterministic-object-hash: 2.0.2 + devalue: 5.0.0 + diff: 5.2.0 + dlv: 1.1.3 + dset: 3.1.3 + es-module-lexer: 1.5.4 + esbuild: 0.21.5 + estree-walker: 3.0.3 + execa: 8.0.1 + fast-glob: 3.3.2 + flattie: 1.1.1 + github-slugger: 2.0.0 + gray-matter: 4.0.3 + html-escaper: 3.0.3 + http-cache-semantics: 4.1.1 + js-yaml: 4.1.0 + kleur: 4.1.5 + magic-string: 0.30.10 + mrmime: 2.0.0 + ora: 8.0.1 + p-limit: 6.1.0 + p-queue: 8.0.1 + path-to-regexp: 6.2.2 + preferred-pm: 4.0.0 + prompts: 2.4.2 + rehype: 13.0.1 + semver: 7.6.2 + shiki: 1.11.0 + string-width: 7.2.0 + strip-ansi: 7.1.0 + tsconfck: 3.1.1(typescript@5.5.3) + unist-util-visit: 5.0.0 + vfile: 6.0.2 + vite: 5.3.4(@types/node@20.14.11) + vitefu: 0.2.5(vite@5.3.4) + which-pm: 3.0.0 + yargs-parser: 21.1.1 + zod: 3.23.8 + zod-to-json-schema: 3.23.1(zod@3.23.8) + optionalDependencies: + sharp: 0.33.4 + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + - typescript /astrojs-compiler-sync@1.0.0(@astrojs/compiler@2.9.1): resolution: {integrity: sha512-IM6FxpMoBxkGGdKppkFHNQIC9Wge7jspG2MIJff8DOhG41USNJLxJfxRm7wnkTKWlYK5Y1YFFNYr2vUUKkI8sw==} @@ -8309,6 +8391,10 @@ packages: /undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + dev: true + /unherit@3.0.1: resolution: {integrity: sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==} @@ -8552,7 +8638,7 @@ packages: debug: 4.3.5 pathe: 1.1.2 picocolors: 1.0.1 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - '@types/node' - less @@ -8582,7 +8668,7 @@ packages: perfect-debounce: 1.0.0 picocolors: 1.0.1 sirv: 2.0.4 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - rollup - supports-color @@ -8599,12 +8685,47 @@ packages: debug: 4.3.5 globrex: 0.1.2 tsconfck: 3.1.0(typescript@5.5.3) - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) transitivePeerDependencies: - supports-color - typescript dev: true + /vite@5.3.4(@types/node@20.14.11): + resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.14.11 + esbuild: 0.21.5 + postcss: 8.4.39 + rollup: 4.18.1 + optionalDependencies: + fsevents: 2.3.3 + /vite@5.3.4(@types/node@20.14.11)(sass@1.77.6): resolution: {integrity: sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -8649,7 +8770,7 @@ packages: vite: optional: true dependencies: - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) /vitest@1.6.0(@types/node@20.14.11): resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} @@ -8694,7 +8815,7 @@ packages: strip-literal: 2.1.0 tinybench: 2.8.0 tinypool: 0.8.4 - vite: 5.3.4(@types/node@20.14.11)(sass@1.77.6) + vite: 5.3.4(@types/node@20.14.11) vite-node: 1.6.0(@types/node@20.14.11) why-is-node-running: 2.2.2 transitivePeerDependencies: From f63f768e1ad5e5c109bdd1af61806735376e55a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Mon, 26 Aug 2024 14:48:54 +0300 Subject: [PATCH 2/3] fix: tests to use new config --- e2e/uno.config.ts | 46 ++-------------------------------------------- 1 file changed, 2 insertions(+), 44 deletions(-) diff --git a/e2e/uno.config.ts b/e2e/uno.config.ts index 7018afe8c..949120d9c 100644 --- a/e2e/uno.config.ts +++ b/e2e/uno.config.ts @@ -1,47 +1,5 @@ -import fs from 'node:fs/promises'; -import { basename, dirname, join } from 'node:path'; -import { globSync, convertPathToPattern } from 'fast-glob'; -import { defineConfig, presetIcons, presetUno, transformerDirectives } from 'unocss'; -import { rules, shortcuts, theme } from '@tutorialkit/theme'; - -const iconPaths = globSync('./icons/languages/*.svg'); - -const customIconCollection = iconPaths.reduce( - (acc, iconPath) => { - const collectionName = basename(dirname(iconPath)); - const [iconName] = basename(iconPath).split('.'); - - acc[collectionName] ??= {}; - acc[collectionName][iconName] = async () => fs.readFile(iconPath, 'utf8'); - - return acc; - }, - {} as Record Promise>>, -); +import { defineConfig } from '@tutorialkit/theme'; export default defineConfig({ - rules, - shortcuts, - theme, - content: { - inline: globSync([ - `${convertPathToPattern(join(require.resolve('@tutorialkit/components-react'), '..')).replace('\\@', '/@')}/**/*.js`, - `${convertPathToPattern(join(require.resolve('@tutorialkit/astro'), '..')).replace('\\@', '/@')}/default/**/*.astro`, - ]).map((filePath) => { - return () => fs.readFile(filePath, { encoding: 'utf8' }); - }), - }, - transformers: [transformerDirectives()], - presets: [ - presetUno({ - dark: { - dark: '[data-theme="dark"]', - }, - }), - presetIcons({ - collections: { - ...customIconCollection, - }, - }), - ], + // add your UnoCSS config here: https://unocss.dev/guide/config-file }); From 6af1bc95fcf101883a9d7a0adbab4403b03cd2ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Mon, 26 Aug 2024 16:34:16 +0300 Subject: [PATCH 3/3] fix: code review --- packages/theme/src/transition-theme.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/theme/src/transition-theme.ts b/packages/theme/src/transition-theme.ts index c001551bd..7ecb41576 100644 --- a/packages/theme/src/transition-theme.ts +++ b/packages/theme/src/transition-theme.ts @@ -1,3 +1,5 @@ +// this is a separate module with its own entrypoint so that it can be used in non-Node environment + export const transitionTheme = { transitionProperty: 'background-color, border-color, box-shadow', transitionTimingFunction: 'cubic-bezier(0.4, 0, 0.2, 1)',