diff --git a/.storybook/decorators/withDirection.tsx b/.storybook/decorators/withDirection.tsx new file mode 100644 index 0000000000..a23b3c02ec --- /dev/null +++ b/.storybook/decorators/withDirection.tsx @@ -0,0 +1,16 @@ +import React from 'react'; + +import {DirectionProvider} from '@radix-ui/react-direction'; +import type {Decorator} from '@storybook/react'; + +export const WithDirection: Decorator = (Story, context) => { + const dir = context.globals.direction; + + return ( + +
+ +
+
+ ); +}; diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 03a26e535d..8f2073442b 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -11,6 +11,7 @@ import type {Decorator, Preview} from '@storybook/react'; import {Lang, MobileProvider, ThemeProvider, configure} from '../src'; import {DocsDecorator} from '../src/demo/DocsDecorator/DocsDecorator'; +import {WithDirection} from './decorators/withDirection'; import {WithLang} from './decorators/withLang'; import {WithMobile} from './decorators/withMobile'; import {themes} from './theme'; @@ -32,7 +33,7 @@ const withContextProvider: Decorator = (Story, context) => { }; const preview: Preview = { - decorators: [WithMobile, WithLang, withContextProvider], + decorators: [WithMobile, WithLang, WithDirection, withContextProvider], parameters: { docs: { theme: themes.light, @@ -78,6 +79,17 @@ const preview: Preview = { ], }, }, + direction: { + defaultValue: 'rtl', // TODO: change to ltr before merge + toolbar: { + title: 'Direction', + icon: 'transfer', + items: [ + {value: 'ltr', right: '->', title: 'left to right'}, + {value: 'rtl', right: '<-', title: 'right to left'}, + ], + }, + }, platform: { defaultValue: 'desktop', toolbar: { diff --git a/gulpfile.js b/gulpfile.js index dd7caec5db..ce82ca12fd 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -3,8 +3,10 @@ const path = require('path'); const {task, src, dest, series, parallel} = require('gulp'); const sass = require('gulp-dart-sass'); +const postcss = require('gulp-postcss'); const replace = require('gulp-replace'); const ts = require('gulp-typescript'); +const rtl = require('postcss-rtl'); const rimraf = require('rimraf'); const BUILD_DIR = path.resolve('build'); @@ -58,12 +60,14 @@ task('copy-i18n', () => { task('styles-global', () => { return src(['styles/styles.scss', 'styles/fonts.scss']) .pipe(sass().on('error', sass.logError)) + .pipe(postcss([rtl()])) .pipe(dest('styles')); }); task('styles-components', () => { return src(['src/components/**/*.scss', '!src/components/**/__stories__/**/*']) .pipe(sass().on('error', sass.logError)) + .pipe(postcss([rtl()])) .pipe(dest(path.resolve(BUILD_DIR, 'esm', 'components'))) .pipe(dest(path.resolve(BUILD_DIR, 'cjs', 'components'))); }); diff --git a/package-lock.json b/package-lock.json index e32961b007..a7d61c41b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@gravity-ui/i18n": "^1.1.0", "@gravity-ui/icons": "^2.5.0", "@popperjs/core": "^2.11.8", + "@radix-ui/react-direction": "^1.0.1", "blueimp-md5": "^2.19.0", "focus-trap": "^7.5.2", "lodash": "^4.17.21", @@ -33,6 +34,7 @@ "@commitlint/cli": "^17.7.1", "@commitlint/config-conventional": "^17.7.0", "@faker-js/faker": "^8.0.2", + "@gravity-ui/browserslist-config": "^4.1.0", "@gravity-ui/eslint-config": "^2.2.0", "@gravity-ui/prettier-config": "^1.0.1", "@gravity-ui/stylelint-config": "^2.0.0", @@ -61,6 +63,7 @@ "gulp": "^4.0.2", "gulp-cli": "^2.3.0", "gulp-dart-sass": "^1.1.0", + "gulp-postcss": "^9.0.1", "gulp-replace": "^1.1.4", "gulp-typescript": "^5.0.1", "husky": "^8.0.3", @@ -70,6 +73,7 @@ "nano-staged": "^0.8.0", "npm-run-all": "^4.1.5", "postcss": "^8.4.28", + "postcss-rtl": "^2.0.0", "prettier": "^2.8.8", "react": "^18.2.0", "react-docgen-typescript": "^2.2.2", @@ -3299,6 +3303,12 @@ "integrity": "sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw==", "dev": true }, + "node_modules/@gravity-ui/browserslist-config": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/browserslist-config/-/browserslist-config-4.1.0.tgz", + "integrity": "sha512-W5xmaxctgYYY70KYtvFZjA2BnXK3K3j4xZvFvaSUT3HpcvH/LKM/qzrSNpQtU70koNSFc00DW/bzrwc0G2np3Q==", + "dev": true + }, "node_modules/@gravity-ui/eslint-config": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@gravity-ui/eslint-config/-/eslint-config-2.2.0.tgz", @@ -4549,7 +4559,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", "integrity": "sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==", - "dev": true, "dependencies": { "@babel/runtime": "^7.13.10" }, @@ -15029,6 +15038,62 @@ "xtend": "~4.0.1" } }, + "node_modules/gulp-postcss": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-9.0.1.tgz", + "integrity": "sha512-9QUHam5JyXwGUxaaMvoFQVT44tohpEFpM8xBdPfdwTYGM0AItS1iTQz0MpsF8Jroh7GF5Jt2GVPaYgvy8qD2Fw==", + "dev": true, + "dependencies": { + "fancy-log": "^1.3.3", + "plugin-error": "^1.0.1", + "postcss-load-config": "^3.0.0", + "vinyl-sourcemaps-apply": "^0.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/gulp-postcss/node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/gulp-postcss/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/gulp-replace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.1.4.tgz", @@ -21342,6 +21407,21 @@ "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", "dev": true }, + "node_modules/postcss-rtl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-rtl/-/postcss-rtl-2.0.0.tgz", + "integrity": "sha512-vFu78CvaGY9BafWRHNgDm6OjUxzRCWWCrp+KtnyXdgwibLwb/j5ls8Z/ubvOsk9B/Q2NLwSPrXRARKMaa9RBmA==", + "dev": true, + "dependencies": { + "rtlcss": "4.0.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, "node_modules/postcss-safe-parser": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", @@ -22791,6 +22871,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rtlcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.0.0.tgz", + "integrity": "sha512-j6oypPP+mgFwDXL1JkLCtm6U/DQntMUqlv5SOhpgHhdIE+PmBcjrtAHIpXfbIup47kD5Sgja9JDsDF1NNOsBwQ==", + "dev": true, + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0", + "postcss": "^8.4.6", + "strip-json-comments": "^3.1.1" + }, + "bin": { + "rtlcss": "bin/rtlcss.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", diff --git a/package.json b/package.json index 9355378e98..acfdaeb4c5 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@gravity-ui/i18n": "^1.1.0", "@gravity-ui/icons": "^2.5.0", "@popperjs/core": "^2.11.8", + "@radix-ui/react-direction": "^1.0.1", "blueimp-md5": "^2.19.0", "focus-trap": "^7.5.2", "lodash": "^4.17.21", @@ -98,6 +99,7 @@ "@commitlint/cli": "^17.7.1", "@commitlint/config-conventional": "^17.7.0", "@faker-js/faker": "^8.0.2", + "@gravity-ui/browserslist-config": "^4.1.0", "@gravity-ui/eslint-config": "^2.2.0", "@gravity-ui/prettier-config": "^1.0.1", "@gravity-ui/stylelint-config": "^2.0.0", @@ -126,6 +128,7 @@ "gulp": "^4.0.2", "gulp-cli": "^2.3.0", "gulp-dart-sass": "^1.1.0", + "gulp-postcss": "^9.0.1", "gulp-replace": "^1.1.4", "gulp-typescript": "^5.0.1", "husky": "^8.0.3", @@ -135,6 +138,7 @@ "nano-staged": "^0.8.0", "npm-run-all": "^4.1.5", "postcss": "^8.4.28", + "postcss-rtl": "^2.0.0", "prettier": "^2.8.8", "react": "^18.2.0", "react-docgen-typescript": "^2.2.2", @@ -160,5 +164,10 @@ "*.md": [ "prettier --write" ] - } + }, + "browserslist": [ + "extends @gravity-ui/browserslist-config", + "Chrome >= 100", + "Firefox >= 100" + ] }